v0.96.0 — R-50 island NIC: provision attaches the guest island net1
- LocalAPIConfig.island_bridge + island_guest_addr (+ IslandEnabled, Validate all-or-nothing + CIDR guard) - buildBringUpConfig attaches static net1 (island) on provision + DR when set; absent otherwise (pre-R-50 byte-for-byte). Plumbed from cfg.LocalAPI at both RunBringUp sites. Endpoint already follows listen_addr (A0: no template change). - healer stays eth0-only (A3 verify-only) — red-proof test locks the scoping - example config + firewall example rewritten for the island; REUSE updated - 3 non-hollow tests; full green. MinAgent unchanged. Coupling: host-install island config requires agent >= 0.96.0 (vouch first).
This commit is contained in:
@@ -171,3 +171,46 @@ func TestDeploymentModeEnvOverlay(t *testing.T) {
|
||||
t.Errorf("env overlay did not set deployment_mode: %q", cfg.DeploymentMode)
|
||||
}
|
||||
}
|
||||
|
||||
// R-50: the island NIC fields are all-or-nothing and the guest addr must be a CIDR. A half-set or
|
||||
// malformed island must fail at config load (a botched install) rather than silently fall back to
|
||||
// LAN-only, which would leave a guest with an island bind and no island NIC — the exact silent break
|
||||
// R-50 exists to kill. Covers LocalAPIConfig.Validate + IslandEnabled.
|
||||
func TestLocalAPIConfig_IslandValidation(t *testing.T) {
|
||||
base := LocalAPIConfig{Enable: true, ListenAddr: "169.254.253.1:8443"}
|
||||
|
||||
// both empty → fine (pre-R-50 default), IslandEnabled false
|
||||
if err := base.Validate(); err != nil {
|
||||
t.Errorf("no island config must validate: %v", err)
|
||||
}
|
||||
if base.IslandEnabled() {
|
||||
t.Errorf("IslandEnabled must be false when unset")
|
||||
}
|
||||
// both set, valid CIDR → fine, IslandEnabled true
|
||||
ok := base
|
||||
ok.IslandBridge, ok.IslandGuestAddr = "vmbr9", "169.254.253.2/30"
|
||||
if err := ok.Validate(); err != nil {
|
||||
t.Errorf("valid island config must validate: %v", err)
|
||||
}
|
||||
if !ok.IslandEnabled() {
|
||||
t.Errorf("IslandEnabled must be true when both set")
|
||||
}
|
||||
// bridge only → rejected (all-or-nothing)
|
||||
half := base
|
||||
half.IslandBridge = "vmbr9"
|
||||
if err := half.Validate(); err == nil {
|
||||
t.Errorf("half-set island (bridge only) must be rejected")
|
||||
}
|
||||
// guest addr only → rejected
|
||||
half2 := base
|
||||
half2.IslandGuestAddr = "169.254.253.2/30"
|
||||
if err := half2.Validate(); err == nil {
|
||||
t.Errorf("half-set island (guest addr only) must be rejected")
|
||||
}
|
||||
// both set but guest addr is not a CIDR → rejected
|
||||
bad := base
|
||||
bad.IslandBridge, bad.IslandGuestAddr = "vmbr9", "169.254.253.2" // missing /30
|
||||
if err := bad.Validate(); err == nil {
|
||||
t.Errorf("island guest addr without a CIDR mask must be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user