Files
felhom.eu/hub/internal/api/r1150_events_test.go
T
admin 5121536f10 hub v0.159.0: a refused whole-guest backup has its own alarm (R-1150); a reinstall re-issues the claim code and the off-site login when the old host is stale or off (R-1154)
R-1150: the agent's localapi:backup-cadence-cap is a separate per-host state in
HostCapabilityChecker: alone it raises whole_guest_backup_refused (warning, plain text,
agent reason in details) and whole_guest_backup_refusal_cleared (info); other critical
caps keep agent_capability_degraded/_recovered unchanged. New types operator-only and
hub-origin only (not in allowedEventTypes: the suspected controller must not post them).
agent_capability_degraded/_recovered join operatorOnlyEvents (the checker's "never the
customer" claim was configuration only).

R-1154: handleHostEnroll's reuse path re-issues (claim code + off-site login) when no
controller wait is open and either deliberate_off_at is held or both the host report and
the controller report are older than alerting.stale_threshold (wired from main); once per
silence (host_reenroll_reissued record, also written at mint); a live box gets nothing
re-issued and the skip is recorded (host_reenroll_not_reissued). 05 section 8 [DESIGN].

Tests red-proved; go build/vet/test green.
2026-10-19 03:18:34 +02:00

24 lines
962 B
Go

package api
import (
"testing"
"gitea.dooplex.hu/admin/felhom-hub/internal/monitor"
"gitea.dooplex.hu/admin/felhom-hub/internal/notify"
)
// R-1150 (v0.159.0): the refused whole-guest backup pair is operator-only AND hub-origin only — not in
// allowedEventTypes, so no box can POST one to /api/v1/event. The alarm says the guest's controller may be
// compromised; that controller holds the /event credential, and a type it could post it could fake, or post
// first to spend the operator cooldown and drown the real one (the R-895 reasoning). Both registers in one test.
func TestR1150_RefusedBackupEventsAreOperatorOnlyAndHubOrigin(t *testing.T) {
for _, et := range []string{monitor.EventWholeGuestBackupRefused, monitor.EventWholeGuestBackupRefusalCleared} {
if !notify.IsOperatorOnly(et) {
t.Errorf("%s is not operator-only", et)
}
if allowedEventTypes[et] {
t.Errorf("%s is in allowedEventTypes — a box could POST it", et)
}
}
}