package config import ( "fmt" "os" "time" "gopkg.in/yaml.v3" ) type Config struct { Server ServerConfig `yaml:"server"` Database DatabaseConfig `yaml:"database"` VictoriaLogs VictoriaLogsConfig `yaml:"victorialogs"` VMAlert VMAlertConfig `yaml:"vmalert"` MLService MLServiceConfig `yaml:"ml_service"` Auth AuthConfig `yaml:"auth"` RateLimiting RateLimitingConfig `yaml:"rate_limiting"` } type ServerConfig struct { Port int `yaml:"port"` ReadTimeout time.Duration `yaml:"read_timeout"` WriteTimeout time.Duration `yaml:"write_timeout"` } type DatabaseConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` Name string `yaml:"name"` User string `yaml:"user"` Password string `yaml:"password"` MaxConnections int `yaml:"max_connections"` } type VictoriaLogsConfig struct { URL string `yaml:"url"` Timeout time.Duration `yaml:"timeout"` MaxQuerySize int `yaml:"max_query_size"` } type VMAlertConfig struct { URL string `yaml:"url"` RulesDir string `yaml:"rules_dir"` ReloadEndpoint string `yaml:"reload_endpoint"` } type MLServiceConfig struct { URL string `yaml:"url"` Timeout time.Duration `yaml:"timeout"` } type AuthConfig struct { JWTSecret string `yaml:"jwt_secret"` AccessTokenDuration time.Duration `yaml:"access_token_duration"` RefreshTokenDuration time.Duration `yaml:"refresh_token_duration"` } type RateLimitingConfig struct { Enabled bool `yaml:"enabled"` RequestsPerMinute map[string]int `yaml:"requests_per_minute"` } // Load loads configuration from YAML file and environment variables func Load(configPath string) (*Config, error) { data, err := os.ReadFile(configPath) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } // Expand environment variables in config expandedData := []byte(os.ExpandEnv(string(data))) var cfg Config if err := yaml.Unmarshal(expandedData, &cfg); err != nil { return nil, fmt.Errorf("failed to parse config: %w", err) } // Validate required fields if err := cfg.validate(); err != nil { return nil, fmt.Errorf("config validation failed: %w", err) } return &cfg, nil } func (c *Config) validate() error { if c.Database.Password == "" { return fmt.Errorf("database password is required") } if c.Auth.JWTSecret == "" { return fmt.Errorf("JWT secret is required") } if len(c.Auth.JWTSecret) < 32 { return fmt.Errorf("JWT secret must be at least 32 characters") } return nil } // GetDSN returns the PostgreSQL connection string func (c *DatabaseConfig) GetDSN() string { return fmt.Sprintf( "host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", c.Host, c.Port, c.User, c.Password, c.Name, ) }