You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #119. Split out of #123, which shipped agentlab open <portal|agents> in #136 without the third target it proposed.
Problem
agentlab open opens the portal and the kagent UI. The prometheus target #123 asked for was left out because it cannot work as the lab is routed today: internal/lab/templates/observability-route.yaml.tmpl matches only the /prometheus prefix and rewrites it away (ReplacePrefixMatch: /), so https://observability.<domain>/prometheus reaches Prometheus's root, the returned page asks for /assets/…, and nothing routes that — the browser gets a blank page with 404-ing assets. The template says as much itself: "Only the /prometheus prefix is routed — the Prometheus web UI's absolute asset paths would need / and are not the point."
That endpoint exists for Backstage: gs-backend's MimirService is hardcoded to https://observability.<baseDomain>/prometheus/api/v1/query, which is what puts real numbers on the Deployments and Clusters pages (docs/observability.md). Whatever changes must keep that URL answering.
Proposed solution
Serve Prometheus under the prefix instead of stripping it, so one public path carries both the query API and the UI:
internal/lab/templates/kube-prometheus-stack-values.yaml.tmpl — under kube-prometheus-stack.prometheus.prometheusSpec, next to retention: routePrefix: /prometheus and externalUrl: {{ .ObservabilityBaseURL }} (tmplData embeds *config.Config, so the accessor resolves like {{ .BackstageBaseURL }} does elsewhere).
internal/lab/templates/observability-route.yaml.tmpl — drop the filters: block (the URLRewrite), so /prometheus/... reaches the pod unchanged; rewrite the header comment, which currently explains the opposite.
internal/lab/observability.go — the two note lines that print the in-cluster PromQL endpoint gain the prefix.
internal/lab/open.go — the third row in openTargets: what: "the lab Prometheus", url: (*config.Config).ObservabilityBaseURL, tls: true (it is on the edge, so the trust question applies), gate Platform.Enabled && Platform.Observability with a refusal naming platform.observability, and a hint pointing at agentlab logs prometheus. OpenTargets() feeds cobra's ValidArgs, so completion and the argument-less refusal pick it up on their own.
Each needs a real agentlab up and a platform-test run, not just go test:
Backstage's metrics views. The public path is unchanged (observability.<domain>/prometheus/api/v1/query), so the mimirEnabled: true overlay in backstage-catalog.yaml.tmpl should need no edit — this is the thing to verify first.
agentlab platform-test. Its observability phase queries cfg.ObservabilityBaseURL() (internal/lab/platformtest.go) and is the automated proof that the endpoint survived.
mcp-prometheus has to accept a PROMETHEUS_URL carrying a path prefix; if it joins paths naively, every x_mcp-prometheus_* tool breaks — platform-test's target listing catches it.
Prometheus's own probes and self-scrape are rendered by prometheus-operator from routePrefix; kube-prometheus-stack handles this, but the pinned GS wrapper version is worth re-checking. up's wait on the Prometheus CR (internal/lab/observability.go) is the tripwire.
agentlab render stability — the values file is in the manifests table, so check whether a render test pins its content.
Acceptance criteria
agentlab open prometheus opens the Prometheus web UI through the edge and it renders (graph page, targets page), with the lab-CA trust offer behaving as for the portal; with observability off, a refusal naming platform.observability.
Part of #119. Split out of #123, which shipped
agentlab open <portal|agents>in #136 without the third target it proposed.Problem
agentlab openopens the portal and the kagent UI. Theprometheustarget #123 asked for was left out because it cannot work as the lab is routed today:internal/lab/templates/observability-route.yaml.tmplmatches only the/prometheusprefix and rewrites it away (ReplacePrefixMatch: /), sohttps://observability.<domain>/prometheusreaches Prometheus's root, the returned page asks for/assets/…, and nothing routes that — the browser gets a blank page with 404-ing assets. The template says as much itself: "Only the/prometheusprefix is routed — the Prometheus web UI's absolute asset paths would need/and are not the point."That endpoint exists for Backstage: gs-backend's
MimirServiceis hardcoded tohttps://observability.<baseDomain>/prometheus/api/v1/query, which is what puts real numbers on the Deployments and Clusters pages (docs/observability.md). Whatever changes must keep that URL answering.Proposed solution
Serve Prometheus under the prefix instead of stripping it, so one public path carries both the query API and the UI:
internal/lab/templates/kube-prometheus-stack-values.yaml.tmpl— underkube-prometheus-stack.prometheus.prometheusSpec, next toretention:routePrefix: /prometheusandexternalUrl: {{ .ObservabilityBaseURL }}(tmplDataembeds*config.Config, so the accessor resolves like{{ .BackstageBaseURL }}does elsewhere).internal/lab/templates/observability-route.yaml.tmpl— drop thefilters:block (theURLRewrite), so/prometheus/...reaches the pod unchanged; rewrite the header comment, which currently explains the opposite.internal/lab/templates/mcp-prometheus.yaml.tmpl—PROMETHEUS_URLbecomeshttp://prometheus-operated.monitoring.svc.cluster.local:9090/prometheus.internal/lab/observability.go— the twonotelines that print the in-cluster PromQL endpoint gain the prefix.internal/lab/open.go— the third row inopenTargets:what: "the lab Prometheus",url: (*config.Config).ObservabilityBaseURL,tls: true(it is on the edge, so the trust question applies), gatePlatform.Enabled && Platform.Observabilitywith a refusal namingplatform.observability, and a hint pointing atagentlab logs prometheus.OpenTargets()feeds cobra'sValidArgs, so completion and the argument-less refusal pick it up on their own.prometheustarget; it becomes the description of one), docs/cli.md'sopenrow, and CLAUDE.md's command line.What this puts at risk
Each needs a real
agentlab upand aplatform-testrun, not justgo test:observability.<domain>/prometheus/api/v1/query), so themimirEnabled: trueoverlay in backstage-catalog.yaml.tmpl should need no edit — this is the thing to verify first.agentlab platform-test. Its observability phase queriescfg.ObservabilityBaseURL()(internal/lab/platformtest.go) and is the automated proof that the endpoint survived.PROMETHEUS_URLcarrying a path prefix; if it joins paths naively, everyx_mcp-prometheus_*tool breaks — platform-test's target listing catches it.routePrefix; kube-prometheus-stack handles this, but the pinned GS wrapper version is worth re-checking.up's wait on the Prometheus CR (internal/lab/observability.go) is the tripwire.agentlab renderstability — the values file is in themanifeststable, so check whether a render test pins its content.Acceptance criteria
agentlab open prometheusopens the Prometheus web UI through the edge and it renders (graph page, targets page), with the lab-CA trust offer behaving as for the portal; with observability off, a refusal namingplatform.observability.agentlab platform-testpasses unchanged, observability phase included.agentlab backstage-test, plus one look at the pages).x_mcp-prometheus_execute_querystill answers through muster.