Files
api-antrian-operasi/internal/config/config.go
2026-02-19 14:13:25 +07:00

123 lines
4.4 KiB
Go

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
}
}