package config import ( "fmt" "os" "strconv" "strings" "time" ) type Config struct { env map[string]string } type ConfigProvider interface { GetString(key string) string GetInt(key string) int GetBool(key string) bool GetDuration(key string) time.Duration GetServerAddress() string GetDatabaseDSN() string GetDatabaseDSNForLogging() string IsProduction() bool Validate() error } func NewConfig() ConfigProvider { env := make(map[string]string) // Load environment variables for _, pair := range os.Environ() { parts := strings.SplitN(pair, "=", 2) if len(parts) == 2 { env[parts[0]] = parts[1] } } // Set defaults setDefault(env, "FAAS_SERVER_HOST", "0.0.0.0") setDefault(env, "FAAS_SERVER_PORT", "8082") setDefault(env, "FAAS_DB_HOST", "localhost") setDefault(env, "FAAS_DB_PORT", "5432") setDefault(env, "FAAS_DB_NAME", "faas") setDefault(env, "FAAS_DB_USER", "postgres") setDefault(env, "FAAS_DB_PASSWORD", "postgres") setDefault(env, "FAAS_DB_SSLMODE", "disable") setDefault(env, "FAAS_APP_ENV", "development") setDefault(env, "FAAS_LOG_LEVEL", "debug") setDefault(env, "FAAS_DEFAULT_RUNTIME", "docker") setDefault(env, "FAAS_FUNCTION_TIMEOUT", "300s") setDefault(env, "FAAS_MAX_MEMORY", "3008") setDefault(env, "FAAS_MAX_CONCURRENT", "100") setDefault(env, "FAAS_SANDBOX_ENABLED", "true") setDefault(env, "FAAS_NETWORK_ISOLATION", "true") setDefault(env, "FAAS_RESOURCE_LIMITS", "true") setDefault(env, "SERVER_READ_TIMEOUT", "30s") setDefault(env, "SERVER_WRITE_TIMEOUT", "30s") setDefault(env, "SERVER_IDLE_TIMEOUT", "120s") setDefault(env, "RATE_LIMIT_ENABLED", "true") setDefault(env, "RATE_LIMIT_RPS", "100") setDefault(env, "RATE_LIMIT_BURST", "200") setDefault(env, "METRICS_ENABLED", "true") setDefault(env, "METRICS_PORT", "9091") setDefault(env, "AUTH_PROVIDER", "header") setDefault(env, "AUTH_HEADER_USER_EMAIL", "X-User-Email") return &Config{env: env} } func setDefault(env map[string]string, key, value string) { if _, exists := env[key]; !exists { env[key] = value } } func (c *Config) GetString(key string) string { return c.env[key] } func (c *Config) GetInt(key string) int { val := c.env[key] if val == "" { return 0 } intVal, err := strconv.Atoi(val) if err != nil { return 0 } return intVal } func (c *Config) GetBool(key string) bool { val := strings.ToLower(c.env[key]) return val == "true" || val == "1" || val == "yes" || val == "on" } func (c *Config) GetDuration(key string) time.Duration { val := c.env[key] if val == "" { return 0 } duration, err := time.ParseDuration(val) if err != nil { return 0 } return duration } func (c *Config) GetServerAddress() string { host := c.GetString("FAAS_SERVER_HOST") port := c.GetString("FAAS_SERVER_PORT") return fmt.Sprintf("%s:%s", host, port) } func (c *Config) GetDatabaseDSN() string { host := c.GetString("FAAS_DB_HOST") port := c.GetString("FAAS_DB_PORT") name := c.GetString("FAAS_DB_NAME") user := c.GetString("FAAS_DB_USER") password := c.GetString("FAAS_DB_PASSWORD") sslmode := c.GetString("FAAS_DB_SSLMODE") return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", host, port, user, password, name, sslmode) } func (c *Config) GetDatabaseDSNForLogging() string { host := c.GetString("FAAS_DB_HOST") port := c.GetString("FAAS_DB_PORT") name := c.GetString("FAAS_DB_NAME") user := c.GetString("FAAS_DB_USER") sslmode := c.GetString("FAAS_DB_SSLMODE") return fmt.Sprintf("host=%s port=%s user=%s password=*** dbname=%s sslmode=%s", host, port, user, name, sslmode) } func (c *Config) IsProduction() bool { env := strings.ToLower(c.GetString("FAAS_APP_ENV")) return env == "production" || env == "prod" } func (c *Config) GetMetricsAddress() string { host := c.GetString("FAAS_SERVER_HOST") port := c.GetString("METRICS_PORT") return fmt.Sprintf("%s:%s", host, port) } func (c *Config) Validate() error { required := []string{ "FAAS_SERVER_HOST", "FAAS_SERVER_PORT", "FAAS_DB_HOST", "FAAS_DB_PORT", "FAAS_DB_NAME", "FAAS_DB_USER", "FAAS_DB_PASSWORD", } for _, key := range required { if c.GetString(key) == "" { return fmt.Errorf("required environment variable %s is not set", key) } } // Validate server port if c.GetInt("FAAS_SERVER_PORT") <= 0 || c.GetInt("FAAS_SERVER_PORT") > 65535 { return fmt.Errorf("invalid server port: %s", c.GetString("FAAS_SERVER_PORT")) } // Validate database port if c.GetInt("FAAS_DB_PORT") <= 0 || c.GetInt("FAAS_DB_PORT") > 65535 { return fmt.Errorf("invalid database port: %s", c.GetString("FAAS_DB_PORT")) } // Validate timeout if c.GetDuration("FAAS_FUNCTION_TIMEOUT") <= 0 { return fmt.Errorf("invalid function timeout: %s", c.GetString("FAAS_FUNCTION_TIMEOUT")) } // Validate memory limit maxMemory := c.GetInt("FAAS_MAX_MEMORY") if maxMemory <= 0 || maxMemory > 10240 { // Max 10GB return fmt.Errorf("invalid max memory: %s", c.GetString("FAAS_MAX_MEMORY")) } return nil }