Repository navigation
feat(dashboard): cluster overview on the redesign (rebase of #255) - #261
Merged
Merged
Conversation
Extend GET /api/v1/dashboard/summary with three new additive fields
that surface platform-wide telemetry for the operator:
- hosts: node count, ready nodes, allocatable CPU and memory
(millicores / bytes), distinct kubelet versions, OS images
and architectures. Sourced from core/v1/nodes via
KubeVirtDriver.ClusterMetrics.
- hosts.usage: real CPU and memory consumption aggregated from
metrics.k8s.io/v1beta1/nodes (Tier 2 — requires
metrics-server, documented prerequisite in helm-charts).
Served with a 30s in-memory cache, and degrades gracefully
when the API is absent, Forbidden, or transiently
unavailable.
- storage: tenant-scoped PVC capacity and consumption (Bound vs
reserved) plus the count. Sourced from the existing PVC
list path in KubeVirtDriver.
- addons: cluster-wide health of critical dependencies
(KubeVirt, CDI, Multus, metrics-server, networking, and
any chart that follows the Helm label conventions),
discovered dynamically from CustomResourceDefinitions
with the 'app.kubernetes.io/name' label and a small alias
table for the well-known API groups. Each entry reports
'ok' (Established) or 'degraded'.
All four reads are fail-soft: 404, 403, 401, 503, timeouts, and
connection-refused return (nil, nil) so the endpoint never 500s.
Memory mode and nil client leave the fields empty.
docs/rbac-contract.yaml documents the dynamic-client access to
metrics.k8s.io in a new dynamicClient section — rbac_contract_test
keeps passing because the typed client AST scan does not see
Discovery().RESTClient().
PlatformService gains a kv field so the service can read the
hypervisor. CHANGELOG entry under Unreleased. A new
2026-10-08-dashboard-host-metrics.md captures the design and the
locked decisions for this slice.
Surface the new hosts/storage/addons fields from the previous slice
on the existing Dashboard page:
- Rename the section title from 'Cluster nodes' to 'Cluster
overview' to fit the broader scope (nodes + capacity + addons).
- Four cards inside the section: Nodes, Ready nodes, Allocatable
CPU, Allocatable memory. The CPU/memory cards now carry a
usage bar (used / allocatable) and a percent line, with a
colour ramp on 60% / 85% thresholds. A small 'Todos prontos' /
'N degraded' / 'None ready' badge sits next to the Ready
nodes count.
- The four cards share a common baseline via h-full + flex-1 so
the percent and the bars line up at the bottom regardless of
how much content the other cards carry.
- A new 'Storage' card replaces the redundant 'Networks' tile in
the stats row, formatted with auto-scaled units (B / KiB / MiB
/ GiB / TiB) and a percent line.
- A 'Cluster addons' strip below the Kubelet / OS / Arch footer
renders one dot per critical dependency, green and pulsing
when Established, an outlined ring when absent, yellow and
pulsing when unreachable. The list is discovered dynamically
by the backend — only addons actually present on the cluster
are shown.
- The dashboard query polls every 10s when /ws/events is up and
5s when it is down, so the usage bars and the addons strip
stay current without a manual refresh. The existing
realtime-invalidation path still drives VM transitions.
The polling is on a fixed schedule rather than the previous
'health == ok' gate because the underlying data sources
(metrics.k8s.io, the addon probe) have no /ws/events counterpart.
i18n: PT and EN parity for every new key, asserted by i18n.test.ts.
typecheck: tsc --noEmit reports 0 errors new to this commit (the
'isFetching' unused warning is pre-existing).
The dashboard Cluster overview (node counts, capacity, addons) is
platform-wide telemetry, not tenant-scoped. Hide it from any actor
whose role is not 'root'.
Two layers:
1. service.DashboardSummary now takes a role argument. When the
role is anything other than platform.RoleRoot, the service
skips populateHosts, populateStorage and populateAddons; the
JSON response carries no 'hosts', 'storage' or 'addons' field,
so nothing leaks through the Network tab or other consumers.
2. The Dashboard React component gates the entire <SurfaceCard>
with selectIsRoot, so non-root never even renders the card.
Tenant admins and tenant users still see the rest of the dashboard:
volume / VPC / SG / network counts, recent activity, the VM
running% badge, and the health card. Only the platform-wide
telemetry is gone.
The handler passes actor.Role (empty string when unauthenticated,
which is also not root). Two new tests
(TestDashboardSummaryHidesClusterOverviewForNonRoot and
TestDashboardSummaryShowsClusterOverviewForRoot) lock the
behaviour; the existing hosts/storage/addons tests now pass
platform.RoleRoot explicitly so they keep exercising the populated
path.
- populateHosts: cluster usage is optional — an unexpected ClusterUsage error is logged and leaves hosts.usage nil instead of failing the whole dashboard summary (500) for root. - fetchClusterUsage: parse node quantities with resource.ParseQuantity and skip the item on error; resource.MustParse could panic on a malformed metrics.k8s.io payload. - probeAddons: bound the CRD list with a 4s timeout (same bound as the usage call) and request a PartialObjectMetadataList so only names and labels cross the wire, not full OpenAPI schemas. The API group is derived from the CRD object name (<plural>.<group>); Established is not part of ObjectMeta, so a discovered addon is now ok by presence. The apiextensions.k8s.io/customresourcedefinitions get/list grant is listed under dynamicClient in docs/rbac-contract.yaml. - StorageSummary: rename used_bytes to bound_bytes and reword the UI label to "allocated" — the figures are spec.requests sums, i.e. allocated capacity, not real guest consumption. - WithNamespace: build a fresh driver instead of copying the struct — the copy cloned the new cache mutexes (go vet copylocks) while sharing the cache entries. Chart grants land in virtfoundry/helm-charts#141 (rules first).
Render the overview with StatsCard/StatusBadge/SurfaceCard and add demo fixtures for hosts, storage and addons.
Matheus-Thurler
requested review from
RodrigoGoncalves-dev and
wesleip
as code owners
October 16, 2026 13:22
wesleip
approved these changes
Oct 16, 2026
This was referenced Oct 16, 2026
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
maincom o redesign da UI (feat(ui): redesign console with new shell, pages and tokens #259).ClusterOverview.tsxcom os primitivos novos. Só renderiza para root e quando há dados; não repete os blocos de VMs/vCPU/memória do dashboard novo.main. Depende de feat(chart): grant the API read access for the dashboard cluster overview helm-charts#141 (RBAC) e, para uso de CPU/memória dos nós, de helm-charts#140 (metrics-server).Test plan
go build ./... && go test ./...npm run buildenpm test(27 testes)