Skip to content

Rax foundations: config, domain model, NetBox client, diff engine

Aiho Tehisaru requested to merge feature/foundations into trunk

Phases 1-3 of the Rax build plan (see the plan doc referenced in the session this was built from): repo scaffolding, the pure domain model, a NetBox read client, and the pure diff engine.

What's here

  • Scaffolding: fail-fast env-based config (NetBox tokens, Proxmox environments, OIDC-vs-local-admin auth mode selection), a minimal server exposing /healthz, Dockerfile/Makefile/docker-compose following hop-site's stdlib-first, Docker-multi-stage conventions.
  • Domain model + NetBox client: DeviceSpec/VMState/Plan types (no I/O), and BuildDeviceSpec which resolves a racked dcim.device into a DeviceSpec — rack-role-gated (only vm-rack-role racks are in scope), vid-vs-internal-VLAN-id resolved correctly, MAC read from the primary_mac_address object, routed-prefix detection for the Ansible-static-route reminder.
  • Diff engine: diff.Compute(spec, state, opts) -> Plan, pure and I/O-free so it's reusable from the web UI, a rax debug diff CLI, and apply's own pre-apply re-validation. Disk shrink is always a Blocker, never an Action. A NIC's MAC only diffs when explicitly pinned in NetBox. Every interface needs a description before a Plan is Applyable.

Not yet built

Proxmox client (BuildVMState), auth (OIDC/local-admin), the web UI, internal/apply, and internal/store (rack bindings + audit log) — these are later phases.

Note on branch history

This repo's trunk had no commits when work started, so it began with an empty bootstrap commit (Initialize trunk) purely so a real branch existed to target. The original feature/scaffold branch ended up as GitLab's auto-selected default branch (an artifact of push order before trunk existed) and is now orphaned/protected — safe to delete via the web UI once this MR is in, it holds nothing this branch doesn't also have.

Test plan

  • gofmt -l . clean
  • go vet ./... clean
  • go build ./... succeeds
  • go test ./... — all tests pass (config: 13, netbox: 7, diff: 21)
  • Manual smoke test: binary starts, /healthz returns 200

🤖 Generated with Claude Code

https://claude.ai/code/session_01U9buZPRQy7YXLodkSPFFik

Merge request reports

Loading