package config import ( "log" "os" "strings" "github.com/joho/godotenv" ) func LoadConfig() *Config { errLoadEnv := godotenv.Load() if errLoadEnv != nil { log.Println("error loading .env") } config := &Config{ Server: ServerConfig{ Port: getEnvAsInt("PORT", 8080), Mode: getEnv("GIN_MODE", "debug"), }, Databases: make(map[string]DatabaseConfig), Security: SecurityConfig{ TrustedOrigins: parseOrigins(getEnv("SECURITY_TRUSTED_ORIGINS", "http://localhost:3000,http://localhost:8080")), }, Keycloak: KeycloakConfig{ BaseUrl: getEnv("KEYCLOAK_BASE_URL", "https://auth.rssa.top"), Realm: getEnv("KEYCLOAK_REALM", "sandbox"), Audience: getEnv("KEYCLOAK_AUDIENCE", "akbar-test"), Issuer: getEnv("KEYCLOAK_ISSUER", "https://auth.rssa.top/realms/sandbox"), SecretKey: getEnv("KEYCLOAK_SECRET_KEY", ""), IsEnabled: getEnvAsBool("KEYCLOAK_IS_ENABLE", false), }, } config.loadCustomDatabaseConfigs() return config } func (c *Config) loadCustomDatabaseConfigs() { envVars := os.Environ() dbConfigs := make(map[string]map[string]string) // Parse database configurations from environment variables for _, envVar := range envVars { parts := strings.SplitN(envVar, "=", 2) if len(parts) != 2 { continue } key := parts[0] value := parts[1] // Parse specific database configurations if strings.HasSuffix(key, "_CONNECTION") || strings.HasSuffix(key, "_HOST") || strings.HasSuffix(key, "_DATABASE") || strings.HasSuffix(key, "_USERNAME") || strings.HasSuffix(key, "_PASSWORD") || strings.HasSuffix(key, "_PORT") || strings.HasSuffix(key, "_NAME") { segments := strings.Split(key, "_") if len(segments) >= 2 { dbName := strings.ToLower(strings.Join(segments[:len(segments)-1], "_")) property := strings.ToLower(segments[len(segments)-1]) if dbConfigs[dbName] == nil { dbConfigs[dbName] = make(map[string]string) } dbConfigs[dbName][property] = value } } } // Create DatabaseConfig from parsed configurations for additional databases for name, config := range dbConfigs { // Skip empty configurations or system configurations if name == "" || strings.Contains(name, "chrome_crashpad_pipe") || name == "primary" { continue } dbType := getEnvFromMap(config, "connection", getEnvFromMap(config, "type", "postgres")) // Skip if username is empty and it's not a system config username := getEnvFromMap(config, "username", "") if username == "" && !strings.HasPrefix(name, "chrome") { continue } dbConfig := DatabaseConfig{ Name: name, Type: dbType, Host: getEnvFromMap(config, "host", "localhost"), Port: getEnvAsIntFromMap(config, "port", getDefaultPort(dbType)), Username: username, Password: getEnvFromMap(config, "password", ""), Database: getEnvFromMap(config, "database", getEnvFromMap(config, "name", name)), Schema: getEnvFromMap(config, "schema", getDefaultSchema(dbType)), SSLMode: getEnvFromMap(config, "sslmode", getDefaultSSLMode(dbType)), Path: getEnvFromMap(config, "path", ""), Options: getEnvFromMap(config, "options", ""), MaxOpenConns: getEnvAsIntFromMap(config, "max_open_conns", getDefaultMaxOpenConns(dbType)), MaxIdleConns: getEnvAsIntFromMap(config, "max_idle_conns", getDefaultMaxIdleConns(dbType)), ConnMaxLifetime: parseDuration(getEnvFromMap(config, "conn_max_lifetime", getDefaultConnMaxLifetime(dbType))), // Security settings RequireSSL: getEnvAsBoolFromMap(config, "require_ssl", false), SSLRootCert: getEnvFromMap(config, "ssl_root_cert", ""), SSLCert: getEnvFromMap(config, "ssl_cert", ""), SSLKey: getEnvFromMap(config, "ssl_key", ""), Timeout: parseDuration(getEnvFromMap(config, "timeout", "30s")), ConnectTimeout: parseDuration(getEnvFromMap(config, "connect_timeout", "10s")), ReadTimeout: parseDuration(getEnvFromMap(config, "read_timeout", "30s")), WriteTimeout: parseDuration(getEnvFromMap(config, "write_timeout", "30s")), StatementTimeout: parseDuration(getEnvFromMap(config, "statement_timeout", "360s")), // Connection pool settings MaxLifetime: parseDuration(getEnvFromMap(config, "max_lifetime", "1h")), MaxIdleTime: parseDuration(getEnvFromMap(config, "max_idle_time", "5m")), HealthCheckPeriod: parseDuration(getEnvFromMap(config, "health_check_period", "1m")), } c.Databases[name] = dbConfig } }