mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
feat(config): add network.ipsec_enabled cluster flag (default true)
Add IPSecEnabled to NetworkConfig in both the cluster TOML schema and the formation handshake payload. Default true so AWS-parity intra-AZ encryption is on by default. Operators can flip false in [network] for trusted single-rack lab topologies. Phase 2.5 (bead mulga-siv-125.3.5) consumes the flag from admin init (strongSwan provisioning), formation server (propagates to joiners), and daemon startup (ovs-vsctl ipsec_encapsulation toggle).
This commit is contained in:
@@ -46,6 +46,10 @@ type ExternalPool struct {
|
||||
type NetworkConfig struct {
|
||||
ExternalMode string `mapstructure:"external_mode"` // "pool" or "" (disabled)
|
||||
ExternalPools []ExternalPool `mapstructure:"external_pools"` // One or more IP pools
|
||||
// IPSecEnabled toggles OVN native IPsec on every node for intra-AZ Geneve
|
||||
// (AES-256-GCM via strongSwan). Default true. Operators can flip off for
|
||||
// trusted single-rack lab topologies; production edge stays on.
|
||||
IPSecEnabled bool `mapstructure:"ipsec_enabled"`
|
||||
}
|
||||
|
||||
// BootstrapConfig holds the default VPC infrastructure IDs written by admin init.
|
||||
@@ -205,6 +209,10 @@ func LoadConfig(configPath string) (*ClusterConfig, error) {
|
||||
viper.SetEnvPrefix("SPINIFEX")
|
||||
viper.AutomaticEnv()
|
||||
|
||||
// network.ipsec_enabled defaults to true (intra-AZ Geneve encrypted via OVN
|
||||
// native IPsec). Operators must explicitly set false to disable.
|
||||
viper.SetDefault("network.ipsec_enabled", true)
|
||||
|
||||
// Try to load config file if it exists
|
||||
if configPath != "" {
|
||||
// Check if file exists
|
||||
|
||||
@@ -375,6 +375,48 @@ external_interface = "enp0s3"
|
||||
assert.Equal(t, "enp0s3", n.VPCD.ExternalInterface)
|
||||
}
|
||||
|
||||
func TestLoadConfig_NetworkIPSecEnabledDefaultsTrue(t *testing.T) {
|
||||
resetViper(t)
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "spinifex.toml")
|
||||
|
||||
// No [network] block at all — IPSec must default to true so AWS-parity
|
||||
// edge deployments encrypt intra-AZ Geneve without operator opt-in.
|
||||
toml := `
|
||||
node = "n1"
|
||||
|
||||
[nodes.n1]
|
||||
region = "us-east-1"
|
||||
`
|
||||
require.NoError(t, os.WriteFile(path, []byte(toml), 0600))
|
||||
|
||||
cfg, err := LoadConfig(path)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, cfg.Network.IPSecEnabled, "default")
|
||||
}
|
||||
|
||||
func TestLoadConfig_NetworkIPSecEnabledExplicitFalse(t *testing.T) {
|
||||
resetViper(t)
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "spinifex.toml")
|
||||
|
||||
// Operator escape hatch for trusted single-rack lab deployments.
|
||||
toml := `
|
||||
node = "n1"
|
||||
|
||||
[network]
|
||||
ipsec_enabled = false
|
||||
|
||||
[nodes.n1]
|
||||
region = "us-east-1"
|
||||
`
|
||||
require.NoError(t, os.WriteFile(path, []byte(toml), 0600))
|
||||
|
||||
cfg, err := LoadConfig(path)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, cfg.Network.IPSecEnabled)
|
||||
}
|
||||
|
||||
func TestLoadConfig_NetworkPoolDHCPSourceRejected(t *testing.T) {
|
||||
resetViper(t)
|
||||
dir := t.TempDir()
|
||||
|
||||
@@ -71,6 +71,11 @@ type NetworkConfig struct {
|
||||
PoolPrefixLen int `json:"pool_prefix_len"`
|
||||
PoolDNSServers []string `json:"pool_dns_servers,omitempty"`
|
||||
|
||||
// IPSecEnabled propagates the cluster-wide intra-AZ IPsec toggle so the
|
||||
// joining node provisions strongSwan and flips OVS ipsec_encapsulation to
|
||||
// match the rest of the cluster.
|
||||
IPSecEnabled bool `json:"ipsec_enabled"`
|
||||
|
||||
BootstrapAccountId string `json:"bootstrap_account_id,omitempty"`
|
||||
BootstrapVpcId string `json:"bootstrap_vpc_id,omitempty"`
|
||||
BootstrapSubnetId string `json:"bootstrap_subnet_id,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user