package config import ( "os" "strconv" "strings" ) type Config struct { ServerPort string DatabasePath string TechnitiumURL string TechnitiumUsername string TechnitiumPassword string TechnitiumToken string BaseDomain string SpaceSubdomain string RateLimitPerIP int RateLimitPerToken int TrustedProxies []string } func Load() *Config { cfg := &Config{ ServerPort: getEnv("SERVER_PORT", "8080"), DatabasePath: getEnv("DATABASE_PATH", "./dyn.db"), TechnitiumURL: getEnv("TECHNITIUM_URL", ""), TechnitiumUsername: getEnv("TECHNITIUM_USERNAME", ""), TechnitiumPassword: getEnv("TECHNITIUM_PASSWORD", ""), TechnitiumToken: getEnv("TECHNITIUM_TOKEN", ""), BaseDomain: getEnv("BASE_DOMAIN", "dws.rip"), SpaceSubdomain: getEnv("SPACE_SUBDOMAIN", "space"), RateLimitPerIP: getEnvAsInt("RATE_LIMIT_PER_IP", 10), RateLimitPerToken: getEnvAsInt("RATE_LIMIT_PER_TOKEN", 1), TrustedProxies: getEnvAsSlice("TRUSTED_PROXIES", []string{}), } return cfg } func (c *Config) Validate() []string { var errors []string if c.TechnitiumURL == "" { errors = append(errors, "TECHNITIUM_URL is required") } if c.TechnitiumToken == "" && (c.TechnitiumUsername == "" || c.TechnitiumPassword == "") { errors = append(errors, "Either TECHNITIUM_TOKEN or TECHNITIUM_USERNAME/PASSWORD must be provided") } return errors } func (c *Config) GetZone() string { if c.SpaceSubdomain == "" { return c.BaseDomain } return c.SpaceSubdomain + "." + c.BaseDomain } func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } func getEnvAsInt(key string, defaultValue int) int { if value := os.Getenv(key); value != "" { if intVal, err := strconv.Atoi(value); err == nil { return intVal } } return defaultValue } func getEnvAsSlice(key string, defaultValue []string) []string { if value := os.Getenv(key); value != "" { return strings.Split(value, ",") } return defaultValue }