package bootstrap import ( "os" "os/exec" "path/filepath" "strings" "testing" "github.com/Pingu-Studio/MaidnCLI/internal/config" ) func TestRenderCiliumConfig(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "values.yaml") if err := os.WriteFile(path, []byte("host: ${CILIUM_K8S_SERVICE_HOST}\ninterface: ${CILIUM_TRAFFIC_INTERFACE}\nstart: ${CILIUM_LB_START}\nend: ${CILIUM_LB_END}\n"), 0644); err != nil { t.Fatal(err) } cfg := config.Config{Talos: config.TalosConfig{KubeconfigEndpoint: "192.168.45.3"}, Cilium: config.CiliumConfig{TrafficInterface: "eth1", LoadBalancerStart: "192.168.45.19", LoadBalancerEnd: "192.168.45.30"}} if err := renderCiliumConfig(dir, cfg); err != nil { t.Fatal(err) } content, err := os.ReadFile(path) if err != nil { t.Fatal(err) } if strings.Contains(string(content), "${") || !strings.Contains(string(content), "192.168.45.30") { t.Fatalf("Cilium configuration was not rendered: %s", content) } } func TestRenderDeliveryConfig(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "webhook.yaml") if err := os.WriteFile(path, []byte("host: ${WEBHOOK_HOSTNAME}\npath: ${WEBHOOK_PATH}\n"), 0644); err != nil { t.Fatal(err) } cfg := config.Config{Delivery: config.DeliveryConfig{WebhookHostname: "tekton.example.test", WebhookPath: "/hooks/forgejo"}} if err := renderDeliveryConfig(dir, cfg); err != nil { t.Fatal(err) } content, err := os.ReadFile(path) if err != nil { t.Fatal(err) } if strings.Contains(string(content), "${") || !strings.Contains(string(content), "/hooks/forgejo") { t.Fatalf("delivery configuration was not rendered: %s", content) } } func TestRenderDemocraticCSISecret(t *testing.T) { secret, err := renderDemocraticCSISecret(config.DemocraticCSIConfig{TrueNASAPIKey: "api-key", TrueNASHost: "truenas.example.test", TargetPortal: "truenas.example.test:3260", ShareHost: "truenas.example.test", DatasetParentNFS: "pool/kubernetes/nfs/v", DatasetSnapshotsNFS: "pool/kubernetes/nfs/s", AllowedNetworks: "192.168.45.0/24", NameSuffix: "-test", PortalGroup: "1", InitiatorGroup: "1"}) if err != nil { t.Fatal(err) } if !strings.Contains(string(secret), "name: democratic-csi-secrets") || !strings.Contains(string(secret), "dataset-parent-nfs: pool/kubernetes/nfs/v") { t.Fatalf("Democratic CSI secret was not rendered: %s", secret) } } func TestWriteDemocraticCSISecretEncryptsValues(t *testing.T) { if _, err := exec.LookPath("age-keygen"); err != nil { t.Skip("age-keygen is required for bootstrap encryption") } if _, err := exec.LookPath("sops"); err != nil { t.Skip("sops is required for bootstrap encryption") } dir := t.TempDir() identity := filepath.Join(dir, "age-key.txt") if err := exec.Command("age-keygen", "-o", identity).Run(); err != nil { t.Fatal(err) } secretPath := filepath.Join(dir, "secret.sops.yaml") csi := config.DemocraticCSIConfig{TrueNASAPIKey: "test-api-key", TrueNASHost: "truenas.example.test", TargetPortal: "truenas.example.test:3260", ShareHost: "truenas.example.test", DatasetParentNFS: "pool/kubernetes/nfs/v", DatasetSnapshotsNFS: "pool/kubernetes/nfs/s", AllowedNetworks: "192.168.45.0/24", NameSuffix: "-test", PortalGroup: "1", InitiatorGroup: "1"} if err := writeDemocraticCSISecret(secretPath, csi, identity); err != nil { t.Fatal(err) } encrypted, err := os.ReadFile(secretPath) if err != nil { t.Fatal(err) } if strings.Contains(string(encrypted), csi.TrueNASAPIKey) || !strings.Contains(string(encrypted), "sops:") { t.Fatal("Democratic CSI secret was not SOPS encrypted") } if err := writeDemocraticCSISecret(secretPath, csi, identity); err != nil { t.Fatal(err) } unchanged, err := os.ReadFile(secretPath) if err != nil { t.Fatal(err) } if string(encrypted) != string(unchanged) { t.Fatal("Democratic CSI secret was re-encrypted without a configuration change") } } func TestNewWebhookAuthorization(t *testing.T) { authorization, err := NewWebhookAuthorization() if err != nil { t.Fatal(err) } if !strings.HasPrefix(authorization, "Bearer ") || len(authorization) <= len("Bearer ") { t.Fatalf("invalid webhook authorization") } } func TestCopyDirSkipsGitDirectory(t *testing.T) { source := t.TempDir() destination := t.TempDir() if err := os.Mkdir(filepath.Join(source, ".git"), 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(source, ".git", "config"), []byte("private"), 0644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(source, "README.md"), []byte("template"), 0644); err != nil { t.Fatal(err) } if err := copyDir(source, destination, false); err != nil { t.Fatal(err) } if _, err := os.Stat(filepath.Join(destination, ".git")); !os.IsNotExist(err) { t.Fatal("copied template must not contain its Git metadata") } content, err := os.ReadFile(filepath.Join(destination, "README.md")) if err != nil || string(content) != "template" { t.Fatalf("template content was not copied: %q, %v", content, err) } } func TestEnsureManifestsKustomizations(t *testing.T) { dir := t.TempDir() for _, environment := range []string{"previews", "staging", "production"} { if err := os.MkdirAll(filepath.Join(dir, "apps", environment), 0755); err != nil { t.Fatal(err) } } if err := ensureManifestsKustomizations(dir); err != nil { t.Fatal(err) } content, err := os.ReadFile(filepath.Join(dir, "apps", "previews", "kustomization.yaml")) if err != nil || !strings.Contains(string(content), "resources:") { t.Fatalf("preview Kustomization was not created: %q, %v", content, err) } } func TestRenderTerraformTFVarsIsStableAndRedactsToken(t *testing.T) { cfg := config.Config{ ClusterID: "test", Talos: config.TalosConfig{ Proxmox: config.TalosProxmoxConfig{APIURL: "https://proxmox.test", APITokenID: "id", APITokenSecret: "secret", NodeInterfaces: map[string]string{"b": "eno2", "a": "eno1"}}, Cluster: config.TalosClusterConfig{Name: "test", Domain: "test", DiskStorage: "local", AdditionalStorage: "local"}, Image: config.TalosImageConfig{TalosVersion: "v1.13.6", KubernetesVersion: "v1.33.4", SchematicID: "abcdefghijkl", Architecture: "amd64"}, }, } first := renderTerraformTFVars(cfg) second := renderTerraformTFVars(cfg) if first != second || strings.Contains(first, "secret") || strings.Index(first, `"a"`) > strings.Index(first, `"b"`) { t.Fatalf("Terraform rendering is not deterministic or redacted: %s", first) } } func TestTerraformPlanPathIsAbsolute(t *testing.T) { path, err := terraformPlanPath(filepath.Join("maidn-workspace", "terraform"), "cluster") if err != nil || !filepath.IsAbs(path) { t.Fatalf("Terraform plan path is not absolute: %q, %v", path, err) } }