package config import ( "fmt" "os" "github.com/joho/godotenv" ) // Config holds all configuration values type Config struct { // Exoscale ExoscaleAPIKey string ExoscaleAPISecret string // Cloudscale CloudscaleAPIToken string // Hetzner Cloud HetznerAPIKey string // Hetzner Storage Box (for backups) HetznerStorageBoxUser string HetznerStorageBoxHost string // Local backup path LocalBackupPath string } var cfg *Config // Load reads configuration from .env file func Load(envFile string) error { if envFile != "" { if err := godotenv.Load(envFile); err != nil { // Not fatal - env vars might be set directly fmt.Fprintf(os.Stderr, "Warning: could not load %s: %v\n", envFile, err) } } cfg = &Config{ ExoscaleAPIKey: os.Getenv("EXOSCALE_API_KEY"), ExoscaleAPISecret: os.Getenv("EXOSCALE_API_SECRET"), CloudscaleAPIToken: os.Getenv("CLOUDSCALE_API_TOKEN"), HetznerAPIKey: os.Getenv("HETZNER_API_KEY"), HetznerStorageBoxUser: getEnvDefault("HETZNER_STORAGEBOX_USER", "u480813"), HetznerStorageBoxHost: getEnvDefault("HETZNER_STORAGEBOX_HOST", "u480813.your-storagebox.de"), LocalBackupPath: getEnvDefault("LOCAL_BACKUP_PATH", "/srv/backups"), } return nil } // Get returns the current configuration func Get() *Config { if cfg == nil { cfg = &Config{} } return cfg } // Validate checks required credentials for a provider func (c *Config) ValidateProvider(provider string) error { switch provider { case "exoscale": if c.ExoscaleAPIKey == "" || c.ExoscaleAPISecret == "" { return fmt.Errorf("EXOSCALE_API_KEY and EXOSCALE_API_SECRET required") } case "cloudscale": if c.CloudscaleAPIToken == "" { return fmt.Errorf("CLOUDSCALE_API_TOKEN required") } case "hetzner": if c.HetznerAPIKey == "" { return fmt.Errorf("HETZNER_API_KEY required") } default: return fmt.Errorf("unknown provider: %s", provider) } return nil } func getEnvDefault(key, defaultVal string) string { if val := os.Getenv(key); val != "" { return val } return defaultVal }