Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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.

2 changes: 1 addition & 1 deletion .tekton/console-acm-51-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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
2 changes: 1 addition & 1 deletion .tekton/console-acm-52-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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
2 changes: 1 addition & 1 deletion .tekton/console-mce-mce-51-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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
2 changes: 1 addition & 1 deletion .tekton/console-mce-mce-52-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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