package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) // SeedConfig represents the top-level YAML seed configuration. After the // hard cutover only global settings + registries are supported; workloads // are created through the API. type SeedConfig struct { Global GlobalConfig `yaml:"global"` Registries map[string]RegistryDef `yaml:"registries"` } // GlobalConfig holds domain-wide settings from the seed file. type GlobalConfig struct { Domain string `yaml:"domain"` ServerIP string `yaml:"server_ip"` Network string `yaml:"network"` SubdomainPattern string `yaml:"subdomain_pattern"` NotificationURL string `yaml:"notification_url"` Npm NpmConfig `yaml:"npm"` } // NpmConfig holds Nginx Proxy Manager connection details. type NpmConfig struct { URL string `yaml:"url"` Email string `yaml:"email"` Password string `yaml:"password"` } // RegistryDef defines a container registry from the seed file. type RegistryDef struct { URL string `yaml:"url"` Type string `yaml:"type"` Token string `yaml:"token"` } // LoadSeedFile reads and parses the YAML seed config from the given path. func LoadSeedFile(path string) (SeedConfig, error) { data, err := os.ReadFile(path) if err != nil { return SeedConfig{}, fmt.Errorf("read seed file: %w", err) } return ParseSeed(data) } // ParseSeed parses raw YAML bytes into a SeedConfig. func ParseSeed(data []byte) (SeedConfig, error) { var cfg SeedConfig if err := yaml.Unmarshal(data, &cfg); err != nil { return SeedConfig{}, fmt.Errorf("parse yaml: %w", err) } if err := validate(cfg); err != nil { return SeedConfig{}, fmt.Errorf("validate seed config: %w", err) } return cfg, nil } // validate checks that required fields are present in the seed config. func validate(cfg SeedConfig) error { if cfg.Global.Domain == "" { return fmt.Errorf("global.domain is required") } return nil }