113 lines
7 KiB
Go
113 lines
7 KiB
Go
package cmd
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/Pingu-Studio/MaidnCLI/internal/bootstrap"
|
|
"github.com/Pingu-Studio/MaidnCLI/internal/config"
|
|
"github.com/spf13/cobra"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func TestBootstrapInitAppliesFluxDefaultsBeforeFreshValidation(t *testing.T) {
|
|
originalRun := runFreshOrganization
|
|
originalConfigPath, originalOrganization := freshConfigPath, freshOrganization
|
|
originalCreate, originalDelivery, originalMode, originalYes := freshCreateOrganization, freshEnableDelivery, freshMode, freshYes
|
|
t.Cleanup(func() {
|
|
runFreshOrganization = originalRun
|
|
freshConfigPath, freshOrganization = originalConfigPath, originalOrganization
|
|
freshCreateOrganization, freshEnableDelivery, freshMode, freshYes = originalCreate, originalDelivery, originalMode, originalYes
|
|
})
|
|
|
|
workspace := t.TempDir()
|
|
cfg := config.Config{
|
|
ClusterID: "test-cluster",
|
|
WorkspaceDir: workspace,
|
|
Git: config.GitConfig{Provider: "forgejo", BaseURL: "https://git.example.test", Username: "bot", Token: "test-token", Owner: "new-org", CloneParent: filepath.Join(workspace, "checkouts")},
|
|
Flux: config.FluxConfig{RepoName: "cluster", ClusterDomain: "example.test"},
|
|
Talos: config.TalosConfig{
|
|
Proxmox: config.TalosProxmoxConfig{APIURL: "https://proxmox.example.test:8006", APITokenID: "id", APITokenSecret: "test-secret"},
|
|
Cluster: config.TalosClusterConfig{Name: "test-cluster", Domain: "example.test"},
|
|
Image: config.TalosImageConfig{TalosVersion: "v1.13.6", SchematicID: "abcdefghijkl"},
|
|
Nodes: []config.TalosNode{{Name: "cp-01", VMID: 100, Role: "controlplane", Networks: []config.TalosNetwork{{IP: "192.168.45.3", CIDR: "192.168.45.0/28", Gateway: "192.168.45.1", VLANID: 45}, {IP: "192.168.45.18", CIDR: "192.168.45.16/28", VLANID: 451}}}},
|
|
},
|
|
Cilium: config.CiliumConfig{LoadBalancerStart: "192.168.45.19", LoadBalancerEnd: "192.168.45.30"},
|
|
DemocraticCSI: config.DemocraticCSIConfig{TrueNASAPIKey: "test-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"},
|
|
}
|
|
data, err := yaml.Marshal(cfg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(t.TempDir(), "config.yaml")
|
|
if err := os.WriteFile(path, data, 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
runFreshOrganization = func(got config.Config, options bootstrap.FreshOrganizationOptions) (bootstrap.FreshOrganizationPlan, error) {
|
|
if got.Flux.Branch != "main" || got.Flux.ClusterPath != "./clusters/maidn-cd-0" || got.Flux.ManifestsRepo != "cicd-deployment-manifests" || got.Flux.TektonCatalogRepo != "tekton-pipelines" {
|
|
t.Fatalf("fresh init Flux defaults = %#v", got.Flux)
|
|
}
|
|
_, plan, err := bootstrap.PlanFreshOrganization(got, options)
|
|
return plan, err
|
|
}
|
|
freshConfigPath, freshOrganization = path, "new-org"
|
|
freshCreateOrganization, freshEnableDelivery, freshMode, freshYes = true, false, string(bootstrap.Reconcile), false
|
|
command := &cobra.Command{}
|
|
command.SetOut(io.Discard)
|
|
if err := runBootstrapInit(command, nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestAppOnboardValidatesConfigBeforeExternalWork(t *testing.T) {
|
|
originalConfig, originalResolve, originalOnboard := loadAppOnboardConfig, resolveAppOnboarding, onboardApp
|
|
originalConfigPath, originalFrom := onboardConfigPath, onboardFrom
|
|
originalName, originalRepo, originalImage, originalBuildStrategy, originalBuildOutput, originalBuildConfiguration := onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration
|
|
t.Cleanup(func() {
|
|
loadAppOnboardConfig, resolveAppOnboarding, onboardApp = originalConfig, originalResolve, originalOnboard
|
|
onboardConfigPath, onboardFrom = originalConfigPath, originalFrom
|
|
onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration = originalName, originalRepo, originalImage, originalBuildStrategy, originalBuildOutput, originalBuildConfiguration
|
|
})
|
|
loadAppOnboardConfig = func(string) (config.Config, error) { return config.Config{}, nil }
|
|
resolveAppOnboarding = func(config.Config) (config.Config, error) { return config.Config{}, errors.New("incomplete delivery") }
|
|
onboardApp = func(config.Config, string) error {
|
|
t.Fatal("onboarding reached external work before validating config")
|
|
return nil
|
|
}
|
|
onboardConfigPath, onboardFrom = "private.yaml", "app-checkout"
|
|
onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration = "", "", "", "", "", ""
|
|
if err := runAppOnboard(nil, nil); err == nil {
|
|
t.Fatal("onboarding accepted invalid configuration")
|
|
}
|
|
}
|
|
|
|
func TestAppOnboardPassesOnlyValidatedConfigAndCheckout(t *testing.T) {
|
|
originalConfig, originalResolve, originalOnboard := loadAppOnboardConfig, resolveAppOnboarding, onboardApp
|
|
originalConfigPath, originalFrom := onboardConfigPath, onboardFrom
|
|
originalName, originalRepo, originalImage, originalBuildStrategy, originalBuildOutput, originalBuildConfiguration := onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration
|
|
t.Cleanup(func() {
|
|
loadAppOnboardConfig, resolveAppOnboarding, onboardApp = originalConfig, originalResolve, originalOnboard
|
|
onboardConfigPath, onboardFrom = originalConfigPath, originalFrom
|
|
onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration = originalName, originalRepo, originalImage, originalBuildStrategy, originalBuildOutput, originalBuildConfiguration
|
|
})
|
|
cfg := config.Config{Delivery: config.DeliveryConfig{AppRepoURL: "https://git.example.test/new-org/app.git", AppRepoRef: "main"}}
|
|
loadAppOnboardConfig = func(string) (config.Config, error) { return cfg, nil }
|
|
resolveAppOnboarding = func(got config.Config) (config.Config, error) { return got, nil }
|
|
calls := 0
|
|
onboardApp = func(got config.Config, checkout string) error {
|
|
if checkout != "app-checkout" || got.Delivery.AppName != "fixture" || got.Delivery.AppRepoURL != "https://git.example.test/new-org/fixture.git" || got.Delivery.ImageRepository != "registry.example.test/new-org/fixture" || got.Delivery.BuildStrategy != "runtime" || got.Delivery.BuildOutputDirectory != "dist/fixture" || got.Delivery.BuildConfiguration != "ci" {
|
|
t.Fatal("onboarding used the wrong checkout or config")
|
|
}
|
|
calls++
|
|
return nil
|
|
}
|
|
onboardConfigPath, onboardFrom = "private.yaml", "app-checkout"
|
|
onboardAppName, onboardAppRepoURL, onboardImageRepository, onboardBuildStrategy, onboardBuildOutputDirectory, onboardBuildConfiguration = "fixture", "https://git.example.test/new-org/fixture.git", "registry.example.test/new-org/fixture", "runtime", "dist/fixture", "ci"
|
|
if err := runAppOnboard(nil, nil); err != nil || calls != 1 {
|
|
t.Fatalf("runAppOnboard() = %v, calls = %d", err, calls)
|
|
}
|
|
}
|