Cluster modal Workloads card — Pods / Deployments / Jobs tabs¶
Motivation¶
The cluster detail modal's Kubernetes diagnostics only listed Pods. The Azure portal Workloads pane shows Deployments, Jobs and more, and for an ElasticBLAST cluster the Job → Pod relationship is the natural unit of work: operators want to see finished/in-flight Jobs and the supporting Deployments (frontend, CoreDNS, metrics-server) without leaving the dashboard. A flat single list could not carry three resource shapes, so the Pods section was promoted to a tabbed Workloads card.
User-facing change¶
- The cluster modal's "Pods" section is now a collapsible Workloads card with three tabs: Pods | Deployments | Jobs (the subset that matters for ElasticBLAST; the portal's Replica sets / Stateful sets / Daemon sets / Cron jobs were intentionally omitted).
- Node-level diagnostics (Node Resources, Nodes) stay as sibling stacked sections — only the workload views are tabbed.
- Each tab has the same namespace filter and "N shown" indicator. Tab labels show a live item count once loaded.
- Pods — unchanged behaviour (all phases, Node / Pod IP columns, Logs / Describe / Delete actions).
- Deployments — read-only: NS / NAME / READY / UP-TO-DATE / AVAILABLE / AGE. READY turns amber when ready < desired.
- Jobs — read-only: NS / NAME / COMPLETIONS / STATUS / DURATION / AGE. STATUS is colour-coded (Complete / Failed / Running / Pending).
- Tabs fetch lazily — opening the modal no longer fans out three Kubernetes API calls; a tab only loads when the card is expanded and the tab is active. "Refresh All" refetches node data and invalidates the live workload tab.
API / IaC diff summary¶
- New routes (read-only, MSAL-gated, cluster-gated cache +
_gracefuldegrade, same as/aks/pods): GET /api/monitor/aks/deployments→{ "deployments": K8sDeployment[] }GET /api/monitor/aks/jobs→{ "jobs": K8sJob[] }- New service helpers in
api/services/k8s/monitoring.py(re-exported via theapi/services/monitoringfacade): k8s_get_deployments(...)—apps/v1list,ready/up_to_date/availableparsing, optional namespace scoping.k8s_get_jobs(...)—batch/v1list,completionsand derivedstatus(Complete/Failed/Running/Pending),start_time/completion_time.- No IaC change. No new Storage/network surface, no SAS, no shell-out — direct Kubernetes API via the existing kubeconfig token path.
- Frontend: new
K8sDeployment/K8sJobtypes +k8sDeployments/k8sJobstyped clients; newK8sWorkloadsSection(tab container) andK8sDeploymentsPanel/K8sJobsPanel/ refactoredK8sPodsPanel; shareduseNamespaceFilterhook +NamespaceFiltercomponent;formatDurationhelper. OldK8sPodsSectiondeleted.
Validation evidence¶
uv run pytest -q api/tests/test_k8s_get_deployments_jobs.py api/tests/test_k8s_get_pods.py→ 7 passed (new test covers endpoint URLs, namespace scoping, replica parsing, and all four derived Job statuses).uv run pytest -q api/tests -k "aks or monitor or k8s"→ 402 passed (no regression from the facade / route additions).uv run ruff checkon the touched backend files → All checks passed.npx tsc --noEmit→ no errors in any ClusterDiagnostics /monitoring.tsfile (pre-existing unrelatedSequenceDetail.tsxerrors untouched).npx eslint src/components/ClusterDiagnostics src/api/monitoring.ts→ clean.