package cloudinit import ( "testing" ) func TestParseDHCP(t *testing.T) { yaml := []byte(` hostname: test-node network: mode: dhcp kubesolo: local-storage: true `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.Hostname != "test-node" { t.Errorf("hostname = %q, want %q", cfg.Hostname, "test-node") } if cfg.Network.Mode != "dhcp" { t.Errorf("network.mode = %q, want %q", cfg.Network.Mode, "dhcp") } } func TestParseStatic(t *testing.T) { yaml := []byte(` hostname: edge-01 network: mode: static interface: eth0 address: 192.168.1.100/24 gateway: 192.168.1.1 dns: - 8.8.8.8 - 8.8.4.4 kubesolo: extra-flags: "--disable traefik" local-storage: true apiserver-extra-sans: - edge-01.local `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.Hostname != "edge-01" { t.Errorf("hostname = %q, want %q", cfg.Hostname, "edge-01") } if cfg.Network.Mode != "static" { t.Errorf("network.mode = %q, want %q", cfg.Network.Mode, "static") } if cfg.Network.Address != "192.168.1.100/24" { t.Errorf("network.address = %q, want %q", cfg.Network.Address, "192.168.1.100/24") } if cfg.Network.Gateway != "192.168.1.1" { t.Errorf("network.gateway = %q, want %q", cfg.Network.Gateway, "192.168.1.1") } if len(cfg.Network.DNS) != 2 { t.Fatalf("dns count = %d, want 2", len(cfg.Network.DNS)) } if cfg.Network.DNS[0] != "8.8.8.8" { t.Errorf("dns[0] = %q, want %q", cfg.Network.DNS[0], "8.8.8.8") } if cfg.KubeSolo.ExtraFlags != "--disable traefik" { t.Errorf("extra-flags = %q, want %q", cfg.KubeSolo.ExtraFlags, "--disable traefik") } if len(cfg.KubeSolo.ExtraSANs) != 1 || cfg.KubeSolo.ExtraSANs[0] != "edge-01.local" { t.Errorf("extra-sans = %v, want [edge-01.local]", cfg.KubeSolo.ExtraSANs) } } func TestParseDefaultMode(t *testing.T) { yaml := []byte(` hostname: default-node `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.Network.Mode != "dhcp" { t.Errorf("network.mode = %q, want %q (default)", cfg.Network.Mode, "dhcp") } } func TestParseStaticMissingAddress(t *testing.T) { yaml := []byte(` network: mode: static gateway: 192.168.1.1 `) _, err := ParseBytes(yaml) if err == nil { t.Fatal("expected error for static mode without address") } } func TestParseStaticMissingGateway(t *testing.T) { yaml := []byte(` network: mode: static address: 192.168.1.100/24 `) _, err := ParseBytes(yaml) if err == nil { t.Fatal("expected error for static mode without gateway") } } func TestParseUnknownMode(t *testing.T) { yaml := []byte(` network: mode: ppp `) _, err := ParseBytes(yaml) if err == nil { t.Fatal("expected error for unknown network mode") } } func TestParseAirgap(t *testing.T) { yaml := []byte(` hostname: airgap-node network: mode: static address: 10.0.0.50/24 gateway: 10.0.0.1 airgap: import-images: true images-dir: /mnt/data/images `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if !cfg.Airgap.ImportImages { t.Error("airgap.import-images should be true") } if cfg.Airgap.ImagesDir != "/mnt/data/images" { t.Errorf("airgap.images-dir = %q, want %q", cfg.Airgap.ImagesDir, "/mnt/data/images") } } func TestParsePortainer(t *testing.T) { yaml := []byte(` hostname: edge-node network: mode: dhcp portainer: edge-agent: enabled: true edge-id: test-id edge-key: test-key portainer-url: https://portainer.example.com `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if !cfg.Portainer.EdgeAgent.Enabled { t.Error("portainer.edge-agent.enabled should be true") } if cfg.Portainer.EdgeAgent.EdgeID != "test-id" { t.Errorf("edge-id = %q, want %q", cfg.Portainer.EdgeAgent.EdgeID, "test-id") } if cfg.Portainer.EdgeAgent.PortainerURL != "https://portainer.example.com" { t.Errorf("portainer-url = %q", cfg.Portainer.EdgeAgent.PortainerURL) } } func TestParseNTP(t *testing.T) { yaml := []byte(` hostname: ntp-node ntp: servers: - pool.ntp.org - time.google.com `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(cfg.NTP.Servers) != 2 { t.Fatalf("ntp.servers count = %d, want 2", len(cfg.NTP.Servers)) } if cfg.NTP.Servers[0] != "pool.ntp.org" { t.Errorf("ntp.servers[0] = %q, want %q", cfg.NTP.Servers[0], "pool.ntp.org") } } func TestParseBoolPointer(t *testing.T) { yaml := []byte(` kubesolo: local-storage: false `) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.KubeSolo.LocalStorage == nil { t.Fatal("local-storage should not be nil") } if *cfg.KubeSolo.LocalStorage { t.Error("local-storage should be false") } } func TestParseEmptyConfig(t *testing.T) { yaml := []byte(``) cfg, err := ParseBytes(yaml) if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.Network.Mode != "dhcp" { t.Errorf("empty config should default to dhcp, got %q", cfg.Network.Mode) } } func TestParseExampleFiles(t *testing.T) { examples := []string{ "examples/dhcp.yaml", "examples/static-ip.yaml", "examples/portainer-edge.yaml", "examples/airgapped.yaml", "examples/full-config.yaml", } for _, path := range examples { t.Run(path, func(t *testing.T) { _, err := Parse(path) if err != nil { t.Errorf("failed to parse %s: %v", path, err) } }) } }