OpenAPI ensure-running readiness gate¶
Motivation¶
The OpenAPI plane (elb-openapi) runs inside the
AKS cluster. When that cluster is stopped, the OpenAPI service is down with it, so
an external caller cannot ask OpenAPI to wake its own host. The always-on dashboard
api sidecar (Container Apps, minReplicas: 1) is the only component that stays up,
so it must be the one to check cluster state and start it.
Callers also need to distinguish "stopped" from "starting" from "warmed and ready to serve" — submitting a BLAST request against a cluster whose node-local DB cache is still cold wastes a run.
User-facing change¶
New endpoint:
Body: resource_group and cluster_name are required; subscription_id defaults to
the AZURE_SUBSCRIPTION_ID env. Optional start=false observes without starting;
optional auto_warmup / auto_openapi mirror POST /api/aks/start and are only used
when a start is actually enqueued.
The response carries a single polled status that transitions across polls:
status |
meaning | Retry-After |
|---|---|---|
not_found |
cluster does not exist in ARM | — |
stopped |
cluster is stopped; a start is enqueued when allowed (start_triggered=true) |
30 s |
starting |
start LRO in progress | 30 s |
warming |
cluster Running but warmup nodes not yet Ready | 15 s |
ready |
Running and (warmup complete, or no warmup configured) — safe to serve | — |
unknown |
ARM unreachable; no start is triggered, retry later | 30 s |
A start is enqueued only for a fully-stopped cluster (never while Stopping/
Starting), so polling the endpoint cannot race an in-flight lifecycle LRO or rack up
cluster-start cost. A cluster whose warmup readiness cannot be confirmed degrades to
warming (never ready). Auto-start can be disabled with ENSURE_RUNNING_AUTO_START=false.
API / IaC diff summary¶
api/services/monitoring/aks.py— newget_aks_cluster_snapshot()(singleManagedClusters.get+ the existing serialiser) re-exported fromapi/services/monitoring/__init__.py.api/services/aks/ensure_running.py— new pure state machineevaluate_ensure_running()(cached ARM health + live warmup readiness gate when Running and warmup is configured). No side effects.api/routes/aks/ensure_running.py— new route underaks_router; enforcesrequire_caller, enqueues the existingstart_akstask on thestopped+ recommended path, setsRetry-After.api/routes/aks/__init__.py— wires + re-exports the new router/handler.- No Bicep / IaC change.
Validation evidence¶
uv run pytest -q api/tests/test_aks_ensure_running.py→ 14 passed (every phase + the route start/no-start/Retry-After/auto-start-disabled contracts).uv run pytest -q api/tests→ 3244 passed, 3 skipped.uv run ruff checkclean on all touched files.