package config import ( "errors" "fmt" "os" "gopkg.in/yaml.v3" ) type Config struct { Mode string `yaml:"mode"` ExternalIPProvider ExternalIpProviderConfig `yaml:"ip_provider"` DNSProvider DNSProviderConfig `yaml:"dns_provider"` NotificationProvider NotificationProviderConfig `yaml:"notification_provider,omitempty"` Domains []DomainConfig `yaml:"domains"` CheckInterval string `yaml:"check_interval"` } const ( RunOnceMode = "RunOnce" ScheduledMode = "Scheduled" ) type DomainConfig struct { TLD string `yaml:"tld"` Subdomains []string `yaml:"subdomains"` } type ExternalIpProviderConfig struct { Type string `yaml:"type"` ProviderConfig yaml.Node `yaml:"config"` } type DNSProviderConfig struct { Type string `yaml:"type"` ProviderConfig yaml.Node `yaml:"config"` } type NotificationProviderConfig struct { Type string `yaml:"type"` ProviderConfig yaml.Node `yaml:"config"` } func (c *Config) Load(filePath string) error { inputConfig, err := os.ReadFile(filePath) if err != nil { return fmt.Errorf("failed to read config file: %w", err) } if err := yaml.Unmarshal(inputConfig, c); err != nil { return fmt.Errorf("failed to unmarshal config file: %w", err) } if err := c.validate(); err != nil { return fmt.Errorf("failed to validate config: %w", err) } return nil } func (c *Config) validate() error { if c.Mode != RunOnceMode && c.Mode != ScheduledMode { return errors.New("mode must be one of 'RunOnce' or 'Scheduled'") } if c.Mode == ScheduledMode && c.CheckInterval == "" { return errors.New("check interval must be set when mode is 'Scheduled'") } return nil }