package server import ( "bufio" "os" "strings" ) // Config holds application configuration from environment and .env file type Config struct { S3Endpoint string S3AccessKey string S3SecretKey string S3BucketName string S3UseSSL bool S3Enabled bool // Enable/disable S3 backend BaseDataset string ConfigFile string MetadataFile string Port string } // LoadConfig loads configuration from .env file and environment variables func LoadConfig() *Config { // Load .env file if exists loadEnvFile(".env") s3Enabled := getEnv("S3_ENABLED", "true") == "true" s3AccessKey := os.Getenv("S3_ACCESS_KEY") s3SecretKey := os.Getenv("S3_SECRET_KEY") // Disable S3 if credentials are missing if s3AccessKey == "" || s3SecretKey == "" { s3Enabled = false } return &Config{ S3Endpoint: getEnv("S3_ENDPOINT", "s3.amazonaws.com"), S3AccessKey: s3AccessKey, S3SecretKey: s3SecretKey, S3BucketName: getEnv("S3_BUCKET", "zfs-snapshots"), S3UseSSL: getEnv("S3_USE_SSL", "true") != "false", S3Enabled: s3Enabled, BaseDataset: getEnv("ZFS_BASE_DATASET", "backup"), ConfigFile: getEnv("CONFIG_FILE", "clients.json"), MetadataFile: getEnv("METADATA_FILE", "metadata.json"), Port: getEnv("PORT", "8080"), } } // loadEnvFile loads key=value pairs from a .env file func loadEnvFile(filename string) { file, err := os.Open(filename) if err != nil { return // .env file is optional } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) // Skip empty lines and comments if line == "" || strings.HasPrefix(line, "#") { continue } // Parse key=value parts := strings.SplitN(line, "=", 2) if len(parts) != 2 { continue } key := strings.TrimSpace(parts[0]) value := strings.TrimSpace(parts[1]) // Remove quotes if present if len(value) >= 2 && (value[0] == '"' || value[0] == '\'') { value = value[1 : len(value)-1] } // Only set if not already defined in environment if os.Getenv(key) == "" { os.Setenv(key, value) } } } // getEnv gets an environment variable with a default value func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue }