Add read-only web UI: racks, devices, Plan preview
Stacked on !3 (merged) (feature/auth) — targets that branch until the chain (!1 (merged) -> !2 (merged) -> !3 (merged) -> this) merges in order, then should be retargeted to trunk.
Phase 5 of the build plan: the first real HTTP server wiring config/store/netbox/proxmox/diff/auth together, plus rack binding management (moved up from its originally-planned later phase since the rack list needs it to be more than a static display — see the commit message for the reasoning).
What's here
- Rack list: NetBox racks filtered to the configured Rack Role, each row showing bound/unbound status from Rax's own store, with bind/unbind forms (CSRF-protected).
- Rack device list: devices in a rack filtered to a best-guess
managedDeviceRolesset — flagged in code as needing operator confirmation of the exact role list, per the build plan's own open item. - Device detail: declared Spec vs. live Proxmox State vs. the computed Plan (Blockers in red, Warnings in yellow, each Action with a risk badge). Apply button present but disabled — this phase is read-path validation only, matching the plan's phased build order.
- Every handler is tested against fake NetBoxReader/ProxmoxReader/ ProxmoxPool interfaces, no live NetBox/Proxmox needed for the test suite.
-
cmd/rax/main.gois real wiring now, not a healthz-only stub.
Test plan
-
gofmt -l .clean -
go vet ./...clean -
go build ./...succeeds -
go test ./...— 96 tests pass across the module (18 new: 4 store rack-binding tests, 2 netbox listing tests, 12 web handler tests) -
Manual smoke test against the compiled binary: /healthzreturns 200, an unauthenticated/racksrequest redirects to/auth/login?redirect=%2Fracks, and the login page renders.