swarm-controller: OpenAPI spec + gateway swagger UI wiring

Rust half mirrors hive-c0re/src/dashboard/mod.rs's utoipa pattern
exactly: an ApiDoc root, #[utoipa::path(...)] on /health (the one
existing route), and a raw JSON route at /api/openapi.json served
via OpenApiRouter::split_for_parts(). Only annotated routes appear
in the spec.

Gateway wiring extends the swarm-UI vhost (the only vhost swarm-
controller is reachable from) with:
- /api/ — proxied to the controller's unix socket untouched (no URI
  segment after the socket path), so a route swarm-controller
  registers is the path nginx forwards, no prefix-stripping to keep
  in sync by hand.
- /api/docs/ (+ the bare /api/docs redirect) — the same
  swagger-ui-theme dist the per-hive dashboard already serves at its
  own /api/docs/, reused as-is since it's generic.

Both new locations reuse the same auth_request block the vhost's own
'/' already applies, factored into a shared swarmAuthRequest string —
auth_request does not inherit across sibling nginx locations, so
without this the page itself would be gated while its own API and
API docs sat open.

cargo test -p swarm-controller + cargo clippy --all-targets both
clean. Verified the new nginx wiring evaluates correctly with a
throwaway nixosSystem eval (services.hyperhive.swarm.{controller,ui}
enabled): /api/ proxies to the socket, /api/docs redirects, and both
require auth_request the same as the vhost root.

Fixes hyperhive#3212
This commit is contained in:
iris 2026-08-12 21:18:16 +02:00 committed by mara
commit 4828c96957
5 changed files with 94 additions and 9 deletions

2
Cargo.lock generated
View file

@ -4430,6 +4430,8 @@ dependencies = [
"tokio",
"tracing",
"tracing-subscriber",
"utoipa",
"utoipa-axum",
]
[[package]]