package config import ( "fmt" "os" "strings" "time" ) const defaultShutdownTimeout = 10 * time.Second const defaultMigrationLockTimeout = 30 * time.Second type Config struct { Environment string HTTPAddress string DatabaseURL string DatabaseIdentityURL string DatabaseMigrationURL string DatabaseRuntimeRole string DatabaseIdentityRole string MigrationLockTimeout time.Duration IOPEndpoint string ShutdownTimeout time.Duration } func Load() (Config, error) { shutdownTimeout, err := positiveDuration( "ARIADNE_SHUTDOWN_TIMEOUT", defaultShutdownTimeout, ) if err != nil { return Config{}, err } migrationLockTimeout, err := positiveDuration( "ARIADNE_MIGRATION_LOCK_TIMEOUT", defaultMigrationLockTimeout, ) if err != nil { return Config{}, err } config := Config{ Environment: valueOrDefault("ARIADNE_ENVIRONMENT", "development"), HTTPAddress: valueOrDefault("ARIADNE_HTTP_ADDRESS", ":8080"), DatabaseURL: strings.TrimSpace(os.Getenv("ARIADNE_DATABASE_URL")), DatabaseIdentityURL: strings.TrimSpace(os.Getenv("ARIADNE_DATABASE_IDENTITY_URL")), DatabaseMigrationURL: strings.TrimSpace(os.Getenv("ARIADNE_DATABASE_MIGRATION_URL")), DatabaseRuntimeRole: strings.TrimSpace(os.Getenv("ARIADNE_DATABASE_RUNTIME_ROLE")), DatabaseIdentityRole: strings.TrimSpace(os.Getenv("ARIADNE_DATABASE_IDENTITY_ROLE")), MigrationLockTimeout: migrationLockTimeout, IOPEndpoint: strings.TrimSpace(os.Getenv("ARIADNE_IOP_ENDPOINT")), ShutdownTimeout: shutdownTimeout, } return config, nil } func valueOrDefault(name, fallback string) string { if value := strings.TrimSpace(os.Getenv(name)); value != "" { return value } return fallback } func positiveDuration(name string, fallback time.Duration) (time.Duration, error) { value := strings.TrimSpace(os.Getenv(name)) if value == "" { return fallback, nil } parsed, err := time.ParseDuration(value) if err != nil { return 0, fmt.Errorf("parse %s: %w", name, err) } if parsed <= 0 { return 0, fmt.Errorf("%s must be greater than zero", name) } return parsed, nil }