Add mock OLS server#2182
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR adds a mock OLS server for local testing, updates console startup to resolve cluster endpoint and token details across oc/kubectl with optional token minting, documents the new flows, pins the console image tag, and changes locale file copying to preserve subpaths. ChangesLocal development tooling
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User as Developer
participant StartConsole as start-console.sh
participant CLI as oc/kubectl
participant Cluster as Kubernetes/OpenShift
User->>StartConsole: run start-console or start-console-kind
StartConsole->>CLI: resolve API server endpoint
StartConsole->>CLI: resolve bearer token
CLI->>Cluster: query cluster info or mint token
Cluster-->>CLI: endpoint and token data
CLI-->>StartConsole: resolved values
StartConsole-->>User: start console with bridge config
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Add a minimal mock Lightspeed API for linked-resources development, start-mock-ols npm script, kind/minikube console startup (token mint), CONSOLE_TAG 4.22 default, and ESLint node env for scripts/*.mjs. Co-authored-by: Cursor <cursoragent@cursor.com>
19f044b to
0c9969c
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
.eslintrc.yml (1)
85-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider disabling
no-consoleforscripts/**/*.mjshere instead of per-line disables.
scripts/mock-ols-server.mjshas ~15 individual// eslint-disable-next-line no-consolecomments. Since console output is expected/intended in a CLI script, adding the rule override here would remove that boilerplate.♻️ Proposed addition
overrides: - files: - scripts/**/*.mjs env: node: true + rules: + no-console: 'off'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.eslintrc.yml around lines 85 - 89, Add an ESLint override for scripts/**/*.mjs in the config so console usage is allowed globally for those CLI scripts, rather than requiring repeated per-line disables in scripts/mock-ols-server.mjs. Update the existing overrides block in .eslintrc.yml to include the no-console rule setting for that pattern, using the same scripts/**/*.mjs matcher and keeping the change centralized in the config.scripts/mock-ols-server.mjs (2)
1-1034: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRun
eslint --fix/prettier --writeon this file.Static analysis reports multiple
prettier/prettierformatting errors and acapitalized-commentsviolation (Line 970, comment should start uppercase) across this new file. These are errors, not warnings, so they'll likely fail an enforced lint/CI step.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/mock-ols-server.mjs` around lines 1 - 1034, This file has formatting and comment-style lint failures that need to be cleaned up before CI will pass. Run the formatter on the mock OLS server script and adjust any remaining `prettier/prettier` issues, then fix the lowercase inline comment near the streaming query handler so it satisfies `capitalized-comments`; use the existing `buildStreamBody`, `readBody`, and `/v1/streaming_query` block as the main spot to verify the cleanup.Source: Linters/SAST tools
991-994: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winBind the mock server to loopback only.
server.listen(PORT, ...)with no host binds to all interfaces. Since the mock pulls real cluster resource names (pods/deployments/projects/etc.) viaocwhen available and serves them with zero auth, this can leak real cluster info to anyone on the local network who reaches this port.🔒 Proposed fix
-server.listen(PORT, () => { +server.listen(PORT, '127.0.0.1', () => {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/mock-ols-server.mjs` around lines 991 - 994, The mock OLS server is currently listening on all interfaces, which exposes unauthenticated cluster data to the local network. Update the `server.listen` call in `mock-ols-server.mjs` to bind explicitly to loopback only by passing the localhost host alongside `PORT`, so only the local machine can access it. Keep the change localized to the existing `server.listen(...)` startup block.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@start-console.sh`:
- Around line 54-71: The dev-token flow in start-console.sh creates a permanent
cluster-admin ServiceAccount and ClusterRoleBinding without any warning or
cleanup guidance. Update the dev_token_mint_allowed / kubectl create
serviceaccount / kubectl create clusterrolebinding path to print a loud warning
before granting cluster-admin, and add a clear cleanup command for deleting the
temporary clusterrolebinding and serviceaccount if the user targets the wrong
cluster. Keep the token TTL as-is, but make the privileged resource creation
explicitly visible in this script.
- Around line 75-93: The CLI preflight in start-console.sh is too eager to fail
on oc authentication before allowing the kubectl fallback path used by
resolve_api_server and resolve_bearer_token. Update the PREFERRED_CLI
selection/check logic so that when oc is installed but oc whoami fails, the
script does not exit immediately and instead falls back to kubectl if it is
available; keep the current behavior only when neither CLI is usable or when
kubectl is also unavailable.
- Around line 95-96: The API server lookup in start-console.sh is not guarded
the same way as the bearer token lookup, so a non-zero return from
resolve_api_server can terminate the script before the intended combined error
handling runs. Update the BRIDGE_K8S_MODE_OFF_CLUSTER_ENDPOINT assignment to
follow the same pattern as BRIDGE_K8S_AUTH_BEARER_TOKEN by allowing failure to
pass through, so the script can reach the later “could not read API server or
bearer token” path.
---
Nitpick comments:
In @.eslintrc.yml:
- Around line 85-89: Add an ESLint override for scripts/**/*.mjs in the config
so console usage is allowed globally for those CLI scripts, rather than
requiring repeated per-line disables in scripts/mock-ols-server.mjs. Update the
existing overrides block in .eslintrc.yml to include the no-console rule setting
for that pattern, using the same scripts/**/*.mjs matcher and keeping the change
centralized in the config.
In `@scripts/mock-ols-server.mjs`:
- Around line 1-1034: This file has formatting and comment-style lint failures
that need to be cleaned up before CI will pass. Run the formatter on the mock
OLS server script and adjust any remaining `prettier/prettier` issues, then fix
the lowercase inline comment near the streaming query handler so it satisfies
`capitalized-comments`; use the existing `buildStreamBody`, `readBody`, and
`/v1/streaming_query` block as the main spot to verify the cleanup.
- Around line 991-994: The mock OLS server is currently listening on all
interfaces, which exposes unauthenticated cluster data to the local network.
Update the `server.listen` call in `mock-ols-server.mjs` to bind explicitly to
loopback only by passing the localhost host alongside `PORT`, so only the local
machine can access it. Keep the change localized to the existing
`server.listen(...)` startup block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 96b8938a-641b-4552-8dfd-1ed5786441f6
📒 Files selected for processing (6)
.eslintrc.ymlREADME.mdpackage.jsonscripts/mock-ols-server.mjsstart-console.shwebpack.config.ts
| # Plain Kubernetes clusters (e.g. kind) often use client certs; mint a dev token instead. | ||
| if ! dev_token_mint_allowed; then | ||
| echo "error: no bearer token in kubeconfig (common with kind/minikube client-cert auth)." >&2 | ||
| echo " Run: ALLOW_DEV_TOKEN_MINT=1 npm run start-console" >&2 | ||
| echo " or: npm run start-console-kind" >&2 | ||
| echo " This creates a temporary cluster-admin ServiceAccount (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2 | ||
| return 1 | ||
| fi | ||
| if ! kubectl get serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null 2>&1; then | ||
| kubectl create serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null | ||
| fi | ||
| if ! kubectl get clusterrolebinding "$CONSOLE_DEV_SA_NAME" >/dev/null 2>&1; then | ||
| kubectl create clusterrolebinding "$CONSOLE_DEV_SA_NAME" \ | ||
| --clusterrole=cluster-admin \ | ||
| --serviceaccount="${CONSOLE_DEV_SA_NAMESPACE}:${CONSOLE_DEV_SA_NAME}" >/dev/null | ||
| fi | ||
| kubectl -n "$CONSOLE_DEV_SA_NAMESPACE" create token "$CONSOLE_DEV_SA_NAME" --duration=24h | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Cluster-admin ServiceAccount/ClusterRoleBinding is created but never cleaned up.
When dev token minting is allowed, this creates a ServiceAccount + ClusterRoleBinding granting cluster-admin, with no expiry or teardown beyond the 24h token itself — the SA and binding persist indefinitely on whatever cluster this runs against. There's also no warning printed before granting cluster-admin, and no check that the target looks like a local dev cluster.
Consider at minimum: (1) print a loud warning before creating the binding, and (2) document/offer a cleanup command (kubectl delete clusterrolebinding/serviceaccount ...) for users who point this at the wrong context.
🛡️ Minimal warning addition
if ! dev_token_mint_allowed; then
echo "error: no bearer token in kubeconfig (common with kind/minikube client-cert auth)." >&2
echo " Run: ALLOW_DEV_TOKEN_MINT=1 npm run start-console" >&2
echo " or: npm run start-console-kind" >&2
echo " This creates a temporary cluster-admin ServiceAccount (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2
return 1
fi
+ echo "warning: minting a cluster-admin ServiceAccount token (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2
+ echo " This SA/ClusterRoleBinding is not removed automatically. Use only on local/dev clusters." >&2
if ! kubectl get serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null 2>&1; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Plain Kubernetes clusters (e.g. kind) often use client certs; mint a dev token instead. | |
| if ! dev_token_mint_allowed; then | |
| echo "error: no bearer token in kubeconfig (common with kind/minikube client-cert auth)." >&2 | |
| echo " Run: ALLOW_DEV_TOKEN_MINT=1 npm run start-console" >&2 | |
| echo " or: npm run start-console-kind" >&2 | |
| echo " This creates a temporary cluster-admin ServiceAccount (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2 | |
| return 1 | |
| fi | |
| if ! kubectl get serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null 2>&1; then | |
| kubectl create serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null | |
| fi | |
| if ! kubectl get clusterrolebinding "$CONSOLE_DEV_SA_NAME" >/dev/null 2>&1; then | |
| kubectl create clusterrolebinding "$CONSOLE_DEV_SA_NAME" \ | |
| --clusterrole=cluster-admin \ | |
| --serviceaccount="${CONSOLE_DEV_SA_NAMESPACE}:${CONSOLE_DEV_SA_NAME}" >/dev/null | |
| fi | |
| kubectl -n "$CONSOLE_DEV_SA_NAMESPACE" create token "$CONSOLE_DEV_SA_NAME" --duration=24h | |
| } | |
| # Plain Kubernetes clusters (e.g. kind) often use client certs; mint a dev token instead. | |
| if ! dev_token_mint_allowed; then | |
| echo "error: no bearer token in kubeconfig (common with kind/minikube client-cert auth)." >&2 | |
| echo " Run: ALLOW_DEV_TOKEN_MINT=1 npm run start-console" >&2 | |
| echo " or: npm run start-console-kind" >&2 | |
| echo " This creates a temporary cluster-admin ServiceAccount (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2 | |
| return 1 | |
| fi | |
| echo "warning: minting a cluster-admin ServiceAccount token (${CONSOLE_DEV_SA_NAMESPACE}/${CONSOLE_DEV_SA_NAME})." >&2 | |
| echo " This SA/ClusterRoleBinding is not removed automatically. Use only on local/dev clusters." >&2 | |
| if ! kubectl get serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null 2>&1; then | |
| kubectl create serviceaccount "$CONSOLE_DEV_SA_NAME" -n "$CONSOLE_DEV_SA_NAMESPACE" >/dev/null | |
| fi | |
| if ! kubectl get clusterrolebinding "$CONSOLE_DEV_SA_NAME" >/dev/null 2>&1; then | |
| kubectl create clusterrolebinding "$CONSOLE_DEV_SA_NAME" \ | |
| --clusterrole=cluster-admin \ | |
| --serviceaccount="${CONSOLE_DEV_SA_NAMESPACE}:${CONSOLE_DEV_SA_NAME}" >/dev/null | |
| fi | |
| kubectl -n "$CONSOLE_DEV_SA_NAMESPACE" create token "$CONSOLE_DEV_SA_NAME" --duration=24h | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@start-console.sh` around lines 54 - 71, The dev-token flow in
start-console.sh creates a permanent cluster-admin ServiceAccount and
ClusterRoleBinding without any warning or cleanup guidance. Update the
dev_token_mint_allowed / kubectl create serviceaccount / kubectl create
clusterrolebinding path to print a loud warning before granting cluster-admin,
and add a clear cleanup command for deleting the temporary clusterrolebinding
and serviceaccount if the user targets the wrong cluster. Keep the token TTL
as-is, but make the privileged resource creation explicitly visible in this
script.
| if command -v oc >/dev/null 2>&1; then | ||
| PREFERRED_CLI=oc | ||
| elif command -v kubectl >/dev/null 2>&1; then | ||
| PREFERRED_CLI=kubectl | ||
| else | ||
| echo "error: neither oc nor kubectl found in PATH." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ "$PREFERRED_CLI" = oc ] && ! oc whoami >/dev/null 2>&1; then | ||
| echo "error: not logged in to a cluster. Run 'oc login' (or point KUBECONFIG at a running cluster) and retry." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ "$PREFERRED_CLI" = kubectl ] && ! kubectl cluster-info >/dev/null 2>&1; then | ||
| echo "error: cannot reach the Kubernetes API. Is your cluster running?" >&2 | ||
| echo " Try: kubectl cluster-info" >&2 | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
grep -n 'PREFERRED_CLI' start-console.sh
sed -n '1,15p' start-console.shRepository: openshift/lightspeed-console
Length of output: 998
🏁 Script executed:
#!/bin/bash
grep -n 'PREFERRED_CLI\|oc whoami\|kubectl cluster-info' start-console.sh
sed -n '70,110p' start-console.shRepository: openshift/lightspeed-console
Length of output: 2123
🏁 Script executed:
#!/bin/bash
sed -n '1,70p' start-console.shRepository: openshift/lightspeed-console
Length of output: 2745
Preflight should fall back to kubectl when oc is present but unauthenticated. PREFERRED_CLI is selected by binary presence, so a machine with oc installed but not logged in exits before the kubectl-based fallback in resolve_api_server/resolve_bearer_token can run. That blocks the kind/minikube path on mixed-tool dev setups.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@start-console.sh` around lines 75 - 93, The CLI preflight in start-console.sh
is too eager to fail on oc authentication before allowing the kubectl fallback
path used by resolve_api_server and resolve_bearer_token. Update the
PREFERRED_CLI selection/check logic so that when oc is installed but oc whoami
fails, the script does not exit immediately and instead falls back to kubectl if
it is available; keep the current behavior only when neither CLI is usable or
when kubectl is also unavailable.
| BRIDGE_K8S_MODE_OFF_CLUSTER_ENDPOINT=$(resolve_api_server) | ||
| BRIDGE_K8S_AUTH_BEARER_TOKEN=$(resolve_bearer_token || true) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
sed -n '1,6p' start-console.shRepository: openshift/lightspeed-console
Length of output: 371
🏁 Script executed:
#!/bin/bash
sed -n '85,115p' start-console.sh
rg -n "resolve_api_server|resolve_bearer_token|clearer auth errors|auth" start-console.shRepository: openshift/lightspeed-console
Length of output: 2280
🏁 Script executed:
#!/bin/bash
sed -n '1,80p' start-console.shRepository: openshift/lightspeed-console
Length of output: 2983
🏁 Script executed:
#!/bin/bash
python3 - <<'PY'
import subprocess, textwrap, shlex, os, sys
cases = [
r'''set -e
f(){ return 1; }
echo before
x=$(f)
echo after
''',
r'''set -e
f(){ return 1; }
echo before
x=$(f || true)
echo after
''',
]
for i, script in enumerate(cases, 1):
p = subprocess.run(["bash", "-lc", script], capture_output=True, text=True)
print(f"CASE {i} exit={p.returncode}")
print(p.stdout.strip())
print(p.stderr.strip())
print("---")
PYRepository: openshift/lightspeed-console
Length of output: 420
Guard resolve_api_server like the token lookup.
set -e will make a non-zero return from resolve_api_server exit the script before the later “could not read API server or bearer token” message. Add || true here as well so failures stay on the intended error path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@start-console.sh` around lines 95 - 96, The API server lookup in
start-console.sh is not guarded the same way as the bearer token lookup, so a
non-zero return from resolve_api_server can terminate the script before the
intended combined error handling runs. Update the
BRIDGE_K8S_MODE_OFF_CLUSTER_ENDPOINT assignment to follow the same pattern as
BRIDGE_K8S_AUTH_BEARER_TOKEN by allowing failure to pass through, so the script
can reach the later “could not read API server or bearer token” path.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/mock-ols-server.mjs`:
- Around line 68-70: Run the formatter and lint fixes for
scripts/mock-ols-server.mjs, since Prettier/ESLint violations are present
throughout the file and the capitalized-comments rule is also triggered. Use the
existing symbols in this file as-is, then reformat the affected sections
consistently (including the commented lines around the noted spots) so the file
passes both prettier and eslint without manual style violations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: db7ea1e7-5baf-4f63-b683-6f87b0c3d558
📒 Files selected for processing (6)
.eslintrc.ymlREADME.mdpackage.jsonscripts/mock-ols-server.mjsstart-console.shwebpack.config.ts
✅ Files skipped from review due to trivial changes (3)
- package.json
- .eslintrc.yml
- README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- webpack.config.ts
| const MOCK_DIVERSE_POD_STATUSES = | ||
| process.env.MOCK_DIVERSE_POD_STATUSES === '1' || | ||
| process.env.MOCK_DIVERSE_POD_STATUSES === 'true'; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Run the formatter before merging.
ESLint/Prettier reports errors across this file, plus Line 970 violates capitalized-comments; this will fail lint.
npx prettier --write scripts/mock-ols-server.mjs
npx eslint scripts/mock-ols-server.mjs --fixAlso applies to: 183-185, 190-191, 210-210, 243-248, 367-368, 382-383, 446-448, 482-482, 593-594, 611-612, 668-669, 970-970, 975-975, 999-999, 1002-1002
🧰 Tools
🪛 ESLint
[error] 69-70: Delete ⏎·
(prettier/prettier)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/mock-ols-server.mjs` around lines 68 - 70, Run the formatter and lint
fixes for scripts/mock-ols-server.mjs, since Prettier/ESLint violations are
present throughout the file and the capitalized-comments rule is also triggered.
Use the existing symbols in this file as-is, then reformat the affected sections
consistently (including the commented lines around the noted spots) so the file
passes both prettier and eslint without manual style violations.
Source: Linters/SAST tools
Summary
Dev-only tooling (~1.1k lines, not shipped in the plugin bundle). Split from the linked-resources PR so review stays focused.
scripts/mock-ols-server.mjs— minimal mock Lightspeed API on:8080with SSE streaming and MCP-style tool output (pods, deployments, routes, etc.)npm run start-mock-ols+npm run start-console-kindfor kind/minikube token mintstart-console.sh—CONSOLE_TAG=4.22, kubectl support, clearer auth errorsscripts/*.mjs, webpack locales copyTest plan
Open http://localhost:9000 → Lightspeed → try
show pods,list deployments,list routes.Optional:
MOCK_OLS_SCENARIO=routes npm run start-mock-olsSummary by CodeRabbit
ocandkubectl, with clearer token/auth troubleshooting.