Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
507f95e
ACM-42589: Migrate console backend to Go with Node sidecar (#46)
Ginxo Aug 31, 2026
a6ddceb
ACM-42592: Migrate hub kube-apiserver proxy routes to Go (#48)
Ginxo Aug 31, 2026
2bfe077
Merge remote-tracking branch 'upstream/main'
Ginxo Sep 1, 2026
f211495
ACM-42594 Serve static plugin and SPA assets from the Go backend (#50)
Ginxo Sep 1, 2026
4bec84a
ACM-42593 Migrate managed cluster, metrics, and VM proxy routes to Go…
Ginxo Sep 1, 2026
6bacb5f
ACM-42595: Migrate OAuth login, logout, and /configure discovery to G…
Ginxo Sep 1, 2026
34b09c9
Merge remote-tracking branch 'upstream/main'
Ginxo Sep 2, 2026
f59dad4
cors fix (#53)
Ginxo Sep 2, 2026
3bdfc73
ACM-42596 Migrate auth check, user, and cluster-info routes to Go (#54)
Ginxo Sep 3, 2026
82826ae
ACM-42597 Implement informer cache with client-go SharedInformerFacto…
Ginxo Sep 3, 2026
da825c6
ACM-42598 Implement SSE hub with per-user RBAC filtering (#57)
Ginxo Sep 3, 2026
1f2fbde
ACM-42600 Migrate aggregation layer to Go (#59)
Ginxo Sep 11, 2026
4862364
ACM-42601 Migrate search proxy and WebSocket relay to Go (#62)
Ginxo Sep 11, 2026
7d793c9
ACM-42602 Migrate long-tail routes to Go (#61)
Ginxo Sep 14, 2026
fe44273
ACM-42603 Decommission Node.js backend (#63)
Ginxo Sep 14, 2026
45fa890
performance improvements (#64)
Ginxo Sep 14, 2026
9ba152a
Fix disable events (#65)
fxiang1 Sep 15, 2026
6d55398
Fix partial discovery failure and stale discover cache (#66)
fxiang1 Sep 15, 2026
4983ce9
Merge remote-tracking branch 'upstream/main' into go/migration
Ginxo Sep 15, 2026
03df0e6
backend check errors fixed
Ginxo Sep 15, 2026
2179921
Backend golangci-lint (Go 1.26 incompatibility)
Ginxo Sep 15, 2026
2cb343c
Merge remote-tracking branch 'upstream/main' into go/migration
Ginxo Sep 15, 2026
a940f62
Remove multi-arch for pull request
fxiang1 Sep 15, 2026
46560e3
Merge remote-tracking branch 'upstream/main' into go/migration
Ginxo Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@
/backend/.vscode/
/backend/certs/
/backend/coverage/
/backend/build/
/backend/node_modules/
/backend/public/
/backend/.dockerignore
/backend/.gitignore
/backend/.Dockerfile
/backend/*.md
/backend/bin/
/backend/.env

/frontend/.vscode/
Expand Down
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright Contributors to the Open Cluster Management project

# https://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.{js,jsx,ts,tsx,mjs,cjs,json,jsonc,yml,yaml,css,scss,graphql}]
indent_style = space
indent_size = 2

[*.go]
indent_style = tab
indent_size = 4

[*.md]
trim_trailing_whitespace = false
29 changes: 0 additions & 29 deletions .github/workflows/backend-upgrade.yml

This file was deleted.

5 changes: 1 addition & 4 deletions .tekton/console-acm-51-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ spec:
- name: build-platforms
value:
- linux/x86_64
- linux/ppc64le
- linux/s390x
- linux/arm64
- name: dockerfile
value: Containerfile.acm
- name: path-context
Expand All @@ -41,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: enable-cache-proxy
value: "true"
pipelineRef:
Expand Down
2 changes: 1 addition & 1 deletion .tekton/console-acm-51-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: send-slack-notification
value: true
- name: konflux-application-name
Expand Down
5 changes: 1 addition & 4 deletions .tekton/console-acm-52-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ spec:
- name: build-platforms
value:
- linux/x86_64
- linux/ppc64le
- linux/s390x
- linux/arm64
- name: dockerfile
value: Containerfile.acm
- name: path-context
Expand All @@ -41,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: enable-cache-proxy
value: "true"
pipelineRef:
Expand Down
2 changes: 1 addition & 1 deletion .tekton/console-acm-52-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: send-slack-notification
value: true
- name: konflux-application-name
Expand Down
5 changes: 1 addition & 4 deletions .tekton/console-mce-mce-51-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ spec:
- name: build-platforms
value:
- linux/x86_64
- linux/ppc64le
- linux/s390x
- linux/arm64
- name: dockerfile
value: Containerfile.mce
- name: path-context
Expand All @@ -41,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: enable-cache-proxy
value: "true"
pipelineRef:
Expand Down
2 changes: 1 addition & 1 deletion .tekton/console-mce-mce-51-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: send-slack-notification
value: true
- name: konflux-application-name
Expand Down
5 changes: 1 addition & 4 deletions .tekton/console-mce-mce-52-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ spec:
- name: build-platforms
value:
- linux/x86_64
- linux/ppc64le
- linux/s390x
- linux/arm64
- name: dockerfile
value: Containerfile.mce
- name: path-context
Expand All @@ -41,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: enable-cache-proxy
value: "true"
pipelineRef:
Expand Down
2 changes: 1 addition & 1 deletion .tekton/console-mce-mce-52-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ spec:
- name: build-source-image
value: "true"
- name: prefetch-input
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"npm"}]'
value: '[{"path":".","type":"npm"},{"path":"./frontend","type":"npm"},{"path":"./backend","type":"gomod"}]'
- name: send-slack-notification
value: true
- name: konflux-application-name
Expand Down
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
golang 1.26.5
nodejs 24.11.0
21 changes: 7 additions & 14 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,15 @@
"program": "${workspaceFolder}/frontend/node_modules/.bin/jest"
},
{
"type": "node",
"name": "vscode-jest-tests.v2.backend",
"name": "Go backend",
"type": "go",
"request": "launch",
"args": [
"--runInBand",
"--watchAll=false",
"--coverage=false",
"--testNamePattern",
"${jest.testNamePattern}",
"--runTestsByPath",
"${jest.testFile}"
],
"mode": "auto",
"program": "${workspaceFolder}/backend/cmd/console",
"cwd": "${workspaceFolder}/backend",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"program": "${workspaceFolder}/backend/node_modules/.bin/jest"
"env": {
"PORT": "4000"
}
}
]
}
29 changes: 21 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ console/
│ ├── react-form-wizard/ # @patternfly-labs/react-form-wizard
│ ├── eslint-config/ # @stolostron/eslint-config
│ └── prettier-config/ # @stolostron/prettier-config
├── backend/ # Node.js ESM proxy server
├── backend/ # Go console backend (public listener)
├── docs/ # Architecture documentation
├── scripts/ # Build and development scripts
└── resources/ # Sample K8s YAML fixtures
Expand All @@ -25,21 +25,30 @@ console/
## Prerequisites

- **Node.js** (version pinned in `.nvmrc` and `.tool-versions`) and **npm**
- **Go** (1.26+) for the console backend
- **OpenShift 4.x cluster** with ACM or MCE installed for full functionality
- **openssl** for certificate generation

## Setup

```bash
npm run setup # Configure cluster connection (creates backend/.env)
npm ci # Install dependencies for frontend and backend
npm ci # installs frontend; go mod download when Go is installed
npm run setup # writes backend/.env and backend/certs/ from the current oc context
```

After wiping local config or `oc login` to a new hub:

```bash
rm -rf backend/.env backend/certs/ && npm run setup && npm run ci:backend
```

(`npm run setup:hub` runs the same steps with the `rm` included.)

## Development Commands

| Command | Purpose |
|---------|---------|
| `npm start` | Start frontend + backend in standalone mode |
| `npm start` | Start frontend + backend in standalone mode (Go live-reloads on `.go` changes) |
| `npm run plugins` | Run as dynamic plugins with local OCP console (**recommended dev mode**) |
| `npm test` | Run all tests (frontend + backend) |
| `npm run check` | Run lint, format, and type checking across the entire project |
Expand All @@ -64,7 +73,7 @@ Ports are customizable via environment variables defined in `port-defaults.sh`:
| Variable | Default | Purpose |
|----------|---------|---------|
| `FRONTEND_PORT` | 3000 | Standalone console |
| `BACKEND_PORT` | 4000 | Backend APIs |
| `BACKEND_PORT` | 4000 | Backend APIs (Go listener) |
| `CONSOLE_PORT` | 9000 | OpenShift console |
| `MCE_PORT` | 3001 | MCE plugin |
| `ACM_PORT` | 3002 | ACM plugin |
Expand All @@ -79,7 +88,8 @@ Use `npm run plugins` for development; it matches the production deployment mode

## Code Quality Standards

- TypeScript strict mode in frontend; backend uses `noImplicitAny` but not full strict mode
- TypeScript strict mode in frontend
- Go backend: `gofmt`, `golangci-lint`, and `go test ./...` (`npm run check:backend`)
- ESLint with `@stolostron/eslint-config` (flat config)
- Prettier with `@stolostron/prettier-config` (120 char width, no semicolons, single quotes)
- Husky `commit-msg` hook enforces a `Signed-off-by` line on every commit
Expand Down Expand Up @@ -131,6 +141,9 @@ Features can be enabled/disabled via the `console-config` ConfigMap in the insta

## Troubleshooting

- **Certificate errors** — Remove `backend/certs/` and run `npm run ci:backend` to regenerate
- **`concurrently: command not found`** — Run `npm ci` at the repo root first
- **Certificate errors** — Remove `backend/certs/` and run `npm run setup && npm run ci:backend` (or `npm run generate-certs` to force regeneration)
- **Module resolution errors** — Verify Node.js and npm versions match `.nvmrc` / `.tool-versions`; version mismatches break ESM resolution
- **Missing `.env`** — Run `npm run setup` to generate `backend/.env` with cluster connection details
- **Missing `.env`** — Run `npm run setup` (or `npm run setup:hub` after `oc login` to a new cluster) to generate `backend/.env`
- **Plugin UI redirects to `/dashboards`** — `oc whoami --show-server` must match `CLUSTER_API_URL` in `backend/.env`. After `oc login` to a new hub, run `npm run setup:hub` and restart `npm run plugins`. `start-ocp-console.sh` runs `scripts/check-hub-alignment.sh` to catch this early.
- **Console `tls: first record does not look like a TLS handshake`** — `backend/certs/` is missing or the backend was started before certs existed. Run `npm run generate-certs` and restart `npm run plugins` (the Go listener reads certs only at startup).
23 changes: 20 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,34 @@ npm test

Make sure your `kubectl` context is set to your target cluster and have Red Hat Advanced Cluster Management installed on the target cluster.

Prerequisites match [README.md](README.md#prerequisites) (Node.js 24, Go 1.26+, openssl, `oc`, and podman/docker for plugin mode).

#### First-time setup

```bash
npm ci
npm run setup
```

`npm ci` runs a `postinstall` that installs `frontend` and (when Go is installed) `go mod download` in `backend/`. `npm run setup` writes `backend/.env` and creates `backend/certs/` when missing; `npm run ci:backend` also ensures certs exist.

After `oc login` to a different hub:

```bash
rm -rf backend/.env backend/certs/ && npm run setup && npm run ci:backend
```

(`npm run setup:hub` runs the same steps with the `rm` included.)

#### Recommended: Run as OpenShift Console plugins

This is the production deployment model. **Always test in this mode before submitting a PR.**

```bash
npm run setup
npm run plugins
```

_WARNING: Running this script will update some parts of the cluster specified in your `KUBECONFIG` context._
_WARNING: `npm run setup` updates some parts of the cluster specified in your `KUBECONFIG` context._

Access the console at **http://localhost:9000**

Expand All @@ -76,7 +94,6 @@ Access the console at **http://localhost:9000**
For rapid iteration on features that don't depend on OpenShift Console integration.

```bash
npm run setup
npm start
```

Expand Down
31 changes: 14 additions & 17 deletions Containerfile.acm
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright Contributors to the Open Cluster Management project
ARG NODE_BASE=registry.redhat.io/ubi9/nodejs-24-minimal:latest
ARG RUNTIME_BASE=registry.redhat.io/ubi9/ubi-minimal:latest
ARG GO_BASE=registry.ci.openshift.org/stolostron/builder:go1.26-linux

FROM registry.redhat.io/ubi9/ubi:latest AS crypto-policy
RUN update-crypto-policies --set DEFAULT:PQ
Expand All @@ -11,33 +13,28 @@ ENV NPM_CONFIG_IGNORE_SCRIPTS=true
FROM build-base as dynamic-plugin
WORKDIR /app/frontend
COPY ./frontend .
# Optimization of copying only package.json and package-lock.json does not work because of workspace packages
# Optimization of copying only package.json and package-lock.json does not work because of workspace packages
RUN npm ci --legacy-peer-deps
RUN npm run build:plugin:acm

FROM build-base as backend
WORKDIR /app/backend
# Copy only package.json and package-lock.json so that the docker layer cache only changes if those change
# This will cause the npm ci to only rerun if the package.json or package-lock.json changes
COPY ./backend/package.json ./backend/package-lock.json ./
RUN npm ci --omit=optional
FROM ${GO_BASE} as go-backend
WORKDIR /src
COPY ./backend/go.mod ./backend/go.sum ./
RUN go mod download
COPY ./backend .
RUN npm run build
RUN CGO_ENABLED=0 GOOS=linux go build -o /console ./cmd/console

FROM build-base as production
WORKDIR /app/backend
COPY ./backend/package-lock.json ./backend/package.json ./
RUN npm ci --omit=optional --only=production

FROM ${NODE_BASE}
FROM ${RUNTIME_BASE}
COPY --from=crypto-policy /etc/crypto-policies /etc/crypto-policies
WORKDIR /app
ENV NODE_ENV production
COPY --from=production /app/backend/node_modules ./node_modules
COPY --from=backend /app/backend/backend.mjs ./
ENV PUBLIC_FOLDER=/app/public
COPY --from=go-backend /console ./console
COPY --from=dynamic-plugin /app/frontend/plugins/acm/dist ./public/plugin
COPY ./scripts/console-entrypoint.sh ./console-entrypoint.sh
RUN chmod 755 /app/console-entrypoint.sh /app/console
USER 1001
CMD ["node", "backend.mjs"]
CMD ["/app/console-entrypoint.sh"]

LABEL com.redhat.component="console-container" \
cpe="cpe:/a:redhat:acm:5.1::el9" \
Expand Down
Loading