feat: P0-2c register routes + RBAC for host control/select

Routes and RBAC entries already existed from prior P0-2a/2b work. This
adds three TDD tests that lock down the RBAC invariants:

- TestRBAC_HostControl_ClusterAdminOnly: cluster_admin has host:control
  with domain=all; basic_user must NOT have host:control
- TestRBAC_HostView_BasicUserHasAccess: basic_user has host:view with
  domain=all; queue_admin must NOT have host:view
- TestRBAC_HostControl_DomainTypeIsAll: cluster_admin host:control
  domain type must be "all" (not hostgroup)

All apiserver tests passing.
This commit is contained in:
Rongsong Shen 2026-04-17 09:32:21 +00:00
parent 5807a05cbb
commit f354a5ec78
2 changed files with 153 additions and 6 deletions

View file

@ -60,15 +60,21 @@
- `lib/testsuite/test_request.c` — 8 TDD validation tests (null ep/ctrl/hostname, empty hostname, HOST_DO_NONE no-op, HOST_TAG/UNTAG reject, negative action)
- Regenerated capnp via `ninja -C build`
- [ ] **#7 P0-2b: Implement Go-side ControlHost + fix allFlag race** (unblocked)
- `backend/clib.go` — Replace `ControlHost()` stub with real implementation via `xcecli_hostctrl()`
- `controllers/hosts.go` — Fix data race: remove `var allFlag bool`, return from `preCheckHostControlRequest` as local
- `controllers/queues.go` — Same allFlag data race fix (lines 534-536 / 465)
- [x] **#7 P0-2b: Implement Go-side ControlHost + fix allFlag race**
- `backend/clib.go` — Replaced `ControlHost()` stub with real `xcecli_hostctrl()` call; follows `ControlQueue` pattern exactly
- `backend/control_host_test.go` — New: stub signature + errNoCGO test (guarded `//go:build !cgo`)
- `controllers/hosts.go` — Removed `var allFlag bool` from package scope; `preCheckHostControlRequest` now returns `(bool, error)`; `ControlHost` uses `hostActionMap` with explicit `!exists` guard (mirrors `ControlQueue` pattern)
- `controllers/queues.go` — `preCheckQueueControlRequest` now returns `(bool, error)`; `ControlQueue` receives allFlag locally
- `controllers/host_control_test.go` — 5 new tests: allFlag true/false, concurrent no-race (50 goroutines), invalid action, comment-too-long
- `controllers/queue_control_test.go` — 5 new tests: same coverage for queues
- All tests passing (`make test`)
- [ ] **#8 P0-2c: Register routes + RBAC for host control/select**
- [x] **#8 P0-2c: Register routes + RBAC for host control/select**
- `router/routers.go` — `POST /xce/v1/hosts/control` → RBAC `host:control` (cluster_admin)
- `router/routers.go` — `POST /xce/v1/hosts/select` → RBAC `host:view` (all authenticated)
- `config/rbac.yaml` — Add `host:control` and `host:view` action entries
- `config/rbac.yaml` — `host:control` and `host:view` action entries already present
- `controllers/rbac_check_test.go` — 3 new TDD tests: `TestRBAC_HostControl_ClusterAdminOnly`, `TestRBAC_HostView_BasicUserHasAccess`, `TestRBAC_HostControl_DomainTypeIsAll`
- All tests passing (`controllers` package)
- [ ] **#9 P0-2d: Update stub.go with new function stubs**
- `backend/stub.go` — Keep `ControlHost` stub (return `errNoCGO`), add `StartHeartbeat(ctx context.Context){}`, `SetHeartbeatInterval(secs int){}`, `EvalSelectForHost(...)` returning `errNoCGO`, `Cleanup(){}`