The repair action no longer creates a Kubernetes Job and polls it. Ariadne
patches the fixture ConfigMap directly through its own k8s client, which
removes roughly 40 seconds of pod scheduling from the loop, drops the two
failure modes that Job introduced (volume attach and node selection), and
turns an opaque pod log into an Ariadne event.
- execute_repair returns {action, target, succeeded, error} and issues one
merge patch; no Job, no polling, no injectable clock, never raises
- the patch writes the same terminal value every time, so idempotency needs
no duplicate guard; one action per incident is still enforced upstream
- orchestrator records {repair, target}; the state machine, rebuild trigger
and failure path are unchanged
- retires the unused repair-image setting
Ariadne's service account now needs get+patch on that one ConfigMap by name
instead of Job create; the batch/jobs grant and the hermes-demo-repair
service account can be retired.
480 pass in the hermes suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ariadne
Ariadne is the Atlas admin and account automation service.
It sits behind the portal and handles the jobs that are annoying or risky to do by hand: approving access, syncing account state, rotating service passwords, cleaning stale Kubernetes work, checking platform health, and keeping a few service integrations lined up.
How it works
Ariadne is a FastAPI service with a small scheduler. It talks to Keycloak, Vault, Mailu, Nextcloud, Wger, Firefly, Jenkins, Metis, Kubernetes, and a few Atlas-specific services through focused adapters under ariadne/services/.
The API is split between admin routes, account self-service routes, internal event hooks, and Prometheus metrics. Background jobs store run history in the Ariadne database so failures can be inspected later instead of vanishing into logs.
The following are notes for future Brad.
Bring-up dependencies
Ariadne needs:
- Kubernetes API, service DNS, and Ariadne's service account/RBAC
- the Ariadne database, plus the portal database if portal/account sync is enabled
- Vault or the Kubernetes secrets that Vault normally feeds it
- Keycloak/OIDC, because auth and profile sync assume it exists
- ingress/proxy plumbing if humans are going to use it through the portal
- the services for whatever jobs are enabled: Mailu, Nextcloud, Vaultwarden, Wger, Firefly, Jenkins, Metis, OpenSearch, and the comms/game-mode pieces
It can start before every integration is perfect, but the matching scheduled jobs will fail or no-op until their service is actually alive. In a total bring-up, wait for storage, Flux, Postgres, Vault, Keycloak, and ingress first. Afterwards Ariadne becomes useful glue.
Useful routes:
GET /healthGET /metricsGET /api/admin/cluster/statePOST /api/admin/access/requests/{username}/approvePOST /api/account/mailu/rotatePOST /api/account/wger/resetPOST /api/account/firefly/resetPOST /events
Development
python -m pytest
ruff check .
Most runtime behavior is configured through environment variables in ariadne/settings.py. Service-specific logic is in the small adapter modules; ariadne/app.py is focused on request flow and task orchestration.