101 lines
2.1 KiB
Go
101 lines
2.1 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Config struct {
|
|
ServiceName string
|
|
Environment string
|
|
HTTP HTTPConfig
|
|
Database DatabaseConfig
|
|
Auth AuthConfig
|
|
}
|
|
|
|
type HTTPConfig struct {
|
|
Address string
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
DSN string
|
|
}
|
|
|
|
type AuthConfig struct {
|
|
JWKSURL string
|
|
Audience string
|
|
Issuer string
|
|
FallbackSecret string
|
|
ClockSkew int
|
|
}
|
|
|
|
func Load() (Config, error) {
|
|
cfg := Config{
|
|
ServiceName: getenvDefault("SERVICE_NAME", "platform-projects-core"),
|
|
Environment: getenvDefault("ENVIRONMENT", "development"),
|
|
HTTP: HTTPConfig{
|
|
Address: getenvDefault("HTTP_ADDRESS", ":8080"),
|
|
},
|
|
Database: DatabaseConfig{
|
|
DSN: os.Getenv("DATABASE_DSN"),
|
|
},
|
|
Auth: AuthConfig{
|
|
JWKSURL: os.Getenv("AUTH_JWKS_URL"),
|
|
Audience: os.Getenv("AUTH_AUDIENCE"),
|
|
Issuer: os.Getenv("AUTH_ISSUER"),
|
|
FallbackSecret: os.Getenv("AUTH_FALLBACK_SECRET"),
|
|
ClockSkew: parseIntDefault("AUTH_CLOCK_SKEW_SECONDS", 60),
|
|
},
|
|
}
|
|
|
|
if cfg.Database.DSN == "" {
|
|
return Config{}, errors.New("DATABASE_DSN is required")
|
|
}
|
|
if cfg.Auth.JWKSURL == "" && cfg.Auth.FallbackSecret == "" {
|
|
return Config{}, errors.New("AUTH_JWKS_URL or AUTH_FALLBACK_SECRET must be provided")
|
|
}
|
|
if cfg.Auth.Audience == "" {
|
|
return Config{}, errors.New("AUTH_AUDIENCE is required")
|
|
}
|
|
if cfg.Auth.Issuer == "" {
|
|
return Config{}, errors.New("AUTH_ISSUER is required")
|
|
}
|
|
if err := cfg.Validate(); err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func getenvDefault(key, fallback string) string {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|
|
|
|
func parseIntDefault(key string, fallback int) int {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
parsed, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
func (c Config) Validate() error {
|
|
if c.ServiceName == "" {
|
|
return fmt.Errorf("service name must not be empty")
|
|
}
|
|
if c.HTTP.Address == "" {
|
|
return fmt.Errorf("http address must not be empty")
|
|
}
|
|
return nil
|
|
}
|