Skip to main content
Once a cluster is running, its detail page (/s/<supervisor>/clusters/<cluster>) is built entirely from read-only calls through the tenant’s own kubeconfig, which Celum already holds on the supervisor. All of these live under /api/clusters/<cluster>/... and take ?supervisor= and ?namespace= query parameters to disambiguate which supervisor hosts the cluster and which namespace its Cluster API objects live in.
<supervisor> and <cluster> are placeholders throughout, and payload excerpts are trimmed — real responses carry more rows and fields.

Nodes and events

GET /api/clusters/<cluster>/nodes lists the cluster’s machines — the Cluster API view of its nodes, with phases and versions. It pairs with the events feed, GET /api/clusters/<cluster>/events, which is the first stop for “why is something failing in this tenant”:
Events carry the tenant’s own reasons and messages verbatim — Celum adds nothing, so what you see is what kubectl get events would show.

Metrics — and the available: false case

GET /api/clusters/<cluster>/metrics aggregates CPU, memory, storage, pod counts, per-node stats, and top namespaces. When the tenant has no metrics source installed (no metrics-server or monitoring agent), the endpoint does not error — it returns this, and it is the expected response, not a failure:
Enable the monitoring addon on the cluster (or install metrics-server in the tenant) and the same endpoint starts returning live numbers with available: true.

Helm releases

Tenants have no Flux — Celum talks Helm directly through the tenant kubeconfig. GET /api/clusters/<cluster>/helm-releases is the app inventory:
The write side mirrors the Helm CLI: Upgrades run asynchronously — the PUT returns a job ID and the status endpoint reports progress until the Helm operation completes. The cluster detail page with its Helm Releases panel expanded — chart, version, status, revision and last update per release

Exposure — LoadBalancers and ingresses

Two endpoints answer “how is this cluster reachable from outside”. GET /api/clusters/<cluster>/lb-services lists its LoadBalancer Services with the external IPs the supervisor’s pools assigned:
GET /api/clusters/<cluster>/ingresses lists the HTTP surface — Ingress objects with hosts and TLS state:
Tenants can also run their own Gateway API stack: /api/clusters/<cluster>/gateway/... installs Envoy Gateway inside the guest and manages its gateways and routes. Publishing through the supervisor’s shared gateway instead is covered in Gateways & routes.

Workloads — namespaces, pods, logs

The workloads drill-down goes namespace → pod list → pod detail, all inside the tenant: The pod list is where trouble shows first — status, readiness, and restart counts per pod:
Log reads accept container and tailLines parameters, defaulting to the first container and the trailing 200 lines.

The kubectl-get escape hatch

When the curated views don’t cover a resource, GET /api/clusters/<cluster>/kubectl-get is a generic, read-only kubectl get against the tenant: any kind — core resources or CRDs — listed or fetched as full YAML with resourceName, scoped with resourceNamespace or allNamespaces=true. It never mutates, and Secret values are redacted. Everything it serves is subject to the same permission (cluster:GetResources) and lands in the audit log like every other call.

Permissions

Celum AI works these same views — get_cluster_events, list_cluster_workload_pods, and get_cluster_pod_logs let it answer “why is this pod crashing?” from the identical data, and get_cluster_exposure covers the LB/ingress side.

Troubleshooting

The triage order that strings these reads together.

Access & credentials

Kubeconfig, talosconfig, and SSH — when you do need direct access.