Add NetBox write paths: interface description + IP editing
Stacked on !4 (merged) (feature/web-readonly) — targets that branch until the chain (!1 (merged) -> !2 (merged) -> !3 (merged) -> !4 (merged) -> this) merges in order, then should be retargeted to trunk.
Phase 6 of the build plan, and — per an explicit check-in with the operator — the last phase before pausing ahead of phase 7 (the apply engine that will actually write to Proxmox, the highest-stakes remaining piece).
What's here
The only NetBox writes Rax makes in v1: interface description and IP address editing, both saving immediately (not gated behind Apply, which still doesn't exist). Device-level spec fields stay NetBox-native edits per the already-documented v1 write boundary.
-
internal/netbox:UpdateInterfaceDescription,CreateIPAddress,DeleteIPAddress— all through the write token, with a test that explicitly asserts the Authorization header uses it (not the read-only one). -
internal/web: three new CSRF-protected routes. Empty descriptions are rejected server-side (400) in addition to the form's client-siderequiredattribute. -
device_detail.html: inline description edit + IP list with delete + add-IP form per interface. v1 supports add/remove only, not in-place IP edits (a deliberate scope call — see commit message).
Test plan
-
gofmt -l .clean -
go vet ./...clean -
go build ./...succeeds (binary compiles with new templates embedded) -
go test ./...— 108 tests pass across the module (12 new: 3 netbox write tests, 9 web handler/rendering tests)