Repository navigation
feat(dashboard): show metrics at cluster, namespace and shared scope - #744
Open
Hanson-Tsai wants to merge 42 commits into
Open
Hanson-Tsai wants to merge 42 commits into
Hanson-Tsai wants to merge 42 commits into
Conversation
Viewers without cluster metrics access query /prometheus-tenancy for their workspace's namespace, no longer see the cluster and storage dashboards, and the overview drops the Ceph capacity check. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Regular users query the Workspace's namespace through the tenancy proxy. VM metrics are selected on namespace rather than exported_namespace: the kubevirt PodMonitor now keeps the VMI's own namespace label, which is the one namespace scope enforces. The KubeVirt controller and worker tiles are cluster scope and are dropped for viewers without cluster metrics access, so their queries are never sent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Regular users query the Workspace's namespace through the tenancy proxy. GPU memory and XID come from DCGM, which carries gpu-operator's namespace, so viewers without cluster metrics access see neither and send neither query; the vLLM, kube-state-metrics and cAdvisor panels are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GPU allocation dialog and the GPU resources modal read nodes, DCGM and HAMi at cluster scope, where a regular user only gets 403. They now render, and query, only for viewers with cluster metrics access, and the actions menus drop the GPU allocation row with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Against a deployed dashboard: no cluster or storage dashboards, every chart query goes to /prometheus-tenancy for their namespace only, the overview has data, and no infrastructure metric is asked for. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…returns The lab serves Keycloak on the dashboard's origin under /auth/, so an origin check alone resolved while still on the password page and the next navigation could abort the login callback. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sDriver The cluster and storage dashboards and the workspaces viewer still built their PrometheusDriver by hand, against the rule docs/metrics.md states. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A transient hub error silently hid Cluster and Storage from an admin. A non-ok answer now logs its status, a thrown error its cause, with the cluster; both still fail closed. A denial is not logged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The absence checks could pass before the sidebar had rendered at all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It sat inside the private-CA setup steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ible On the overview the Dashboard group is collapsed, so its sub-items are in the DOM but hidden. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… no ResourceQuota Prometheus keeps no metadata for a kube-state-metrics family without series, so the "is the resourcequota collector on" check failed on any cluster without a single ResourceQuota and every workspace showed an error. Decide from kube_namespace_created and kube_resourcequota alone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- ask a failed access check once more before giving up - show a banner on unknown instead of quietly drawing the regular view - redirect only on a denial, so an admin keeps their bookmark
- wait one tick before replaceState on a first page load - keep the toast where it was
- add dashboardBody to pick charts, loading, no-namespace or empty - show a namespace-unknown notice instead of an endless spinner - stop the compute dashboard going blank without a driver
- delete resource-viewer/viewers/workspaces-viewer.svelte (unused) - raise the tenant-metrics describe timeout to 120 s for Keycloak login - give the login waitForURL a 60 s timeout
- namespace="" matched only series without the label - so an admin choosing all namespaces saw nothing
- the server rewrites selectors the way prom-label-proxy does it - docs and the prometheus.ts header no longer say it is forced - metrics.md points optional namespace filters at namespaceSelector
- cluster and storage are hidden from the menu; a bookmark still opens - the retry spec also covers a thrown error followed by an answer
- sends a query name and parameters, never promql - namespace is the workspace's, left out when it has none - returns prometheus-query results, so callers keep their types
- the kubevirt component tiles ask the shared scope for every viewer - so does the overview's storage card for the cluster's capacity
- per-card inventory and vgpu totals come from the shared scope
- the model's nodes come from its namespace, as before - their gpu numbers come from the shared scope, for every viewer - xid shows as unknown, not 0, when it cannot be asked - drop vllmModelHostnamesSelector, which nothing uses any more
- utilization comes from the shared scope for every viewer - members see their own pods and the scheduler's per-card totals - the node view still lists every pod, so it stays with admins
- gpu, kubevirt and ceph components may only use the shared scope - e2e follows every shared call: known name, answered, own namespace - e2e opens the model's analytics, gpu allocation and gpu resources
- fetchModelNodes resolves null when the lookup fails, [] for no nodes - gpu memory shows no data, not no gpu, when a lookup or call fails - xid shows the grey unavailable dash when the node lookup fails - test fetchModelNodes for a failed lookup and duplicate nodes
- metrics.md and the prometheus.ts header still named two scopes
- the row behind the dialog has gpu icons too - the dialog's overlay took the click meant for the row's icon - found when the e2e first ran on the hci lab with E2E_MODEL set
- list node pods only for a cluster admin, who may list every namespace - fetch gpu-allocated totals for everyone else, metrics viewers included - align card-usage and fetch-topology comments with the new check
- render namespace picker when admin and cluster metrics both allowed - keep an admin with unknown access on their own workspace
- size batches so gpu-fb-total stays under the hub's 6144-byte uri cap - count each uuid as the hub escapes and url-encodes it, five matchers - keep the 256-values cap for short uuids - test long, typical and short uuids against a replica of the hub query
- the podmonitor label change ships in kubevirt 1.2.0, not 1.1.2
- scan workspace, model, compute, gpu-allocation, kind-viewer and routes - leave out the cluster and storage dashboards, admins only - forbid new PrometheusDriver and infra helpers from $lib/prometheus - check the listed helpers are still exported, so none goes stale - require actual shared-scope calls instead of the word shared
- add fetchCombinedInstantOrNull, null on failure, with a warning - grey out restart, oom, throttle, shm and preempt when it fails - warn when the gpu memory card fails to load - clear kubevirt cards on a failed reload and show no data - show an error in gpu resources instead of 0 devices - add pod_health_unavailable and gpu_resources_fetch_error messages
- carry the workspace's namespace when there is one, omit it otherwise
- ask cluster scope, another namespace and shared without one directly - expect 403 for each, and 200 for shared as the user's own workspace - wait for the shared answers each step sends, registered before it - poll for chart data instead of a fixed three-second sleep
- the chained replace read as double escaping to code scanning - same byte counts; tests pin backslash, quote and metacharacters
- source-map-js 1.2.2 and postcss-selector-parser 7.1.6 - static-copy watches with chokidar 4, which drops unpatched braces - pnpm audit: no known vulnerabilities
- bring the branch up to date with main; no conflicts
Hanson-Tsai
marked this pull request as ready for review
October 15, 2026 05:53
Hanson-Tsai
requested review from
KUASWoodyLIN,
ZhangEnYao and
iasthc
as code owners
October 15, 2026 05:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Jira: OTTERSCALE-288. Until now every dashboard page asked the hub for cluster-wide PromQL, and the hub answered anyone who was signed in. A Workspace member could read every namespace's metrics. The hub now answers at three scopes (otterscale/otterscale#310), and this PR makes the dashboard ask at the right one.
/prometheus/...otterscale:metrics-cluster-view/prometheus-tenancy/...?namespace=<ns>get podsin that namespace/prometheus-shared/<name>What changes
src/lib/server/metrics-access.ts): the layout asks the hub once whether the user has cluster metrics access, with three results:allowed,denied,unknown. A failure is retried once.unknownrenders as no access, with a banner, and does not redirect.src/lib/prometheus.ts):workspacePrometheusDriverpicks cluster or namespace scope;sharedMetricscalls the named shared queries.sharedMetricsalways sends the current Workspace's namespace when there is one. It doesn't use the namespace picked in the admin's selector.namespace-scope.spec.ts): scans every directory Workspace pages use. It fails on infrastructure PromQL, cluster-scope drivers,new PrometheusDriverand the infrastructure helpers, and requires the shared-scope components to actually call the shared client.docs/metrics.md: the rules for developers.Review fixes in this update
metrics-cluster-view, gets the shared per-card totals, so the cards no longer undercount silently.allowed.console.warn.waitForResponse/expect.pollinstead of fixed timeouts.Screenshots
Taken on a single-node lab cluster against this branch (
4c157c2) and hubb229eb5. Left: a cluster-admin. Right: aviewmember of one Workspace. Under each pair are the metrics requests that step sent. The signed-in user's name in the sidebar footer is covered.Overview
Cluster and Storage: the member lands on the overview
Compute: KubeVirt cards from the shared scope
Model analytics: GPU memory and XID from the shared scope
Model service: GPU Allocation
Model service: GPU Resources in the Update dialog
Node menu: GPU Allocation stays cluster-only
Create VM (control: unchanged for both)
For the member, no step sent a cluster-scope request, every shared request returned 200 with the Workspace's namespace, and no page component sent infrastructure PromQL. The images live on the
pr-assets/otterscale-288branch, which is not meant to be merged.Compatibility
This dashboard needs the hub from otterscale/otterscale#310, and the two must be upgraded together:
Compute charts also need the kubevirt module at chart 1.2.0 (otterscale/helm-charts#67), which keeps a VM metric's
namespaceas the VM's own.Testing
pnpm check: 0 errors, 0 warnings.pnpm lint: clean.pnpm test:unit: 13 files, 90 tests.e2e/tenant-metrics.test.ts: 9/9, run on the lab cluster as a regular user against this branch.Related
🤖 Generated with Claude Code