Public HTTPS pipeline — systempool toleration injection + SPA dict-failure surfacing¶
Motivation¶
On 2026-05-27 the user clicked Settings → Public HTTPS → Enable on
elb-cluster-01. The task ran for 387 s and the SPA showed no error, but the
endpoint was not active. Log Analytics for the worker sidecar showed:
public-https: cert-manager-webhook rollout probe N/5 not ready yet: error: timed out waiting for the condition
RuntimeError: kubectl rollout status cert-manager-webhook failed after 5 probes (360s elapsed)
Task ...setup_openapi_public_https... succeeded in 387.83s:
{'status': 'failed',
'error': 'kubectl rollout status cert-manager-webhook failed after 5 probes (360s elapsed); ...',
'fqdn': 'elb-openapi-a4f11ec1f3.koreacentral.cloudapp.azure.com',
'elapsed_seconds': 387}
Direct kubectl describe on the cluster:
| Node | Taint |
|---|---|
aks-systempool-... |
CriticalAddonsOnly=true:NoSchedule |
aks-blastpool-...-0 |
workload=blast:NoSchedule |
aks-blastpool-...-1 |
workload=blast:NoSchedule |
Both cert-manager.yaml and ingress-nginx's deploy.yaml ship pods with no
tolerations, so every workload Pod they created landed in Pending forever on
this AKS topology. The task happened to swallow the resulting RuntimeError
into a dict result, so Celery reported runtime_status: Completed and the SPA's
poll loop took that to mean "succeeded" → no banner, no toast, no error.
User-facing change¶
- Public HTTPS Enable now succeeds on AKS clusters with tainted node pools.
The setup task injects a
CriticalAddonsOnlytoleration and akubernetes.azure.com/mode=systemnodeSelector into every Deployment / Job from the upstream install manifests before applying, so cert-manager and ingress-nginx land on the systempool only (never on the BLAST workload pool). - The Settings panel now surfaces dict-level pipeline failures. When the
task returns
{status: 'failed', error: '...'}despite Celery reportingCompleted, the SPA flips to the error banner instead of silently switching the status badge to Exposed.
API / IaC diff summary¶
api/services/k8s/ingress.py- New constants
SYSTEM_POOL_TOLERATION,SYSTEM_POOL_NODE_SELECTOR,INGRESS_NGINX_ADMISSION_JOB_SELECTOR. - New
patch_manifest_for_system_pool(raw_manifest) -> str— pure transform that injects the systempool toleration + nodeSelector into everyDeployment | DaemonSet | StatefulSet | Job | ReplicaSetpodTemplate. Preserves existing tolerations / nodeSelector keys, is idempotent, and dropsNoneseparator docs so kubectl does not reject--- null. - New
fetch_install_manifest_for_system_pool(url, *, timeout_seconds=60)— network wrapper around the pure transform. api/tasks/openapi/public_https.py- Step 1 (ingress-nginx install): now streams the patched manifest through
kubectl apply -f -and pre-deletes any pre-existing admission-webhook Jobs (immutable spec from a prior toleration-less install). - Step 4 (cert-manager install): now streams the patched manifest through
kubectl apply -f -(no Job pre-delete needed — cert-manager has no install-time Jobs). web/src/components/SettingsPanel.tsxpollTasknow treatsruntime_status === 'Completed' && output.status === 'failed'as a failure path and surfacesoutput.errorin the existing error banner.
No Bicep / Container App template / sidecar layout changes.
Validation evidence¶
uv run pytest -q api/tests/test_openapi_public_https.py→ 22 passed (4 new unit tests forpatch_manifest_for_system_poolcovering inject, preserve-existing, idempotency, and--- nullseparator regression; full pipeline test updated to assert stdin-streamed apply + admission-Job pre-delete ordering).uv run pytest -q api/tests→ 1530 passed, 1 unrelated flaky (test_terminal_exec.py::test_run_truncates_stdout_above_cap, timing- dependent, passes when isolated).uv run ruff checkon changed files → all checks passed.cd web && npx tsc --noEmit→ no errors.cd web && npm run build→ ok.- Live verification on elb-cluster-01 (manual
kubectl apply -f -of the patched manifests):All add-on pods land on the systempool; nothing leaks onto the blastpool; the ingress-nginx LB keeps its existing EXTERNAL-IPcert-manager-b5474d6b5-8xj4q 1/1 Running aks-systempool-... cert-manager-cainjector-6498996479-qzn2g 1/1 Running aks-systempool-... cert-manager-webhook-7cf4687596-bllbw 1/1 Running aks-systempool-... ingress-nginx-admission-create-h5xff 0/1 Completed aks-systempool-... ingress-nginx-admission-patch-w9jpw 0/1 Completed aks-systempool-... ingress-nginx-controller-549f67b9b5-4grnz 1/1 Running aks-systempool-...20.249.192.56.