161 lines
4.1 KiB
Go
161 lines
4.1 KiB
Go
package config
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Config contém todas as configurações da aplicação
|
|
type Config struct {
|
|
Server ServerConfig
|
|
Auth AuthConfig
|
|
Logging LoggingConfig
|
|
Security SecurityConfig
|
|
}
|
|
|
|
// ServerConfig contém configurações do servidor HTTP
|
|
type ServerConfig struct {
|
|
Port string
|
|
ReadTimeout time.Duration
|
|
WriteTimeout time.Duration
|
|
ShutdownTimeout time.Duration
|
|
TLSEnabled bool
|
|
TLSCertFile string
|
|
TLSKeyFile string
|
|
}
|
|
|
|
// AuthConfig contém configurações de autenticação
|
|
type AuthConfig struct {
|
|
Enabled bool
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
// LoggingConfig contém configurações de logging
|
|
type LoggingConfig struct {
|
|
Level string // debug, info, warn, error
|
|
Format string // json ou console
|
|
}
|
|
|
|
// SecurityConfig contém configurações de segurança
|
|
type SecurityConfig struct {
|
|
RateLimitEnabled bool
|
|
RateLimitRPS int
|
|
CORSOrigins []string
|
|
}
|
|
|
|
// Load carrega a configuração de múltiplas fontes (flags, env vars)
|
|
func Load() (*Config, error) {
|
|
cfg := &Config{}
|
|
|
|
// Definir flags (mantém compatibilidade com versão anterior)
|
|
flag.StringVar(&cfg.Server.Port, "port", getEnv("PORT", ":8080"), "Porta para o servidor web (ex: :8080, 9090)")
|
|
flag.StringVar(&cfg.Auth.Username, "username", getEnv("USERNAME", "admin"), "Nome de usuário para autenticação")
|
|
flag.StringVar(&cfg.Auth.Password, "password", getEnv("PASSWORD", ""), "Senha para autenticação")
|
|
|
|
flag.Parse()
|
|
|
|
// Carregar configurações de variáveis de ambiente
|
|
cfg.Logging.Level = getEnv("LOG_LEVEL", "info")
|
|
cfg.Logging.Format = getEnv("LOG_FORMAT", "console")
|
|
|
|
cfg.Security.RateLimitEnabled = getEnvBool("RATE_LIMIT_ENABLED", true)
|
|
cfg.Security.RateLimitRPS = getEnvInt("RATE_LIMIT_RPS", 100)
|
|
|
|
corsOrigins := getEnv("CORS_ORIGINS", "")
|
|
if corsOrigins != "" {
|
|
cfg.Security.CORSOrigins = strings.Split(corsOrigins, ",")
|
|
} else {
|
|
cfg.Security.CORSOrigins = []string{"*"}
|
|
}
|
|
|
|
cfg.Server.ReadTimeout = getEnvDuration("READ_TIMEOUT", 15*time.Second)
|
|
cfg.Server.WriteTimeout = getEnvDuration("WRITE_TIMEOUT", 15*time.Second)
|
|
cfg.Server.ShutdownTimeout = getEnvDuration("SHUTDOWN_TIMEOUT", 30*time.Second)
|
|
|
|
cfg.Server.TLSEnabled = getEnvBool("TLS_ENABLED", false)
|
|
cfg.Server.TLSCertFile = getEnv("TLS_CERT_FILE", "")
|
|
cfg.Server.TLSKeyFile = getEnv("TLS_KEY_FILE", "")
|
|
|
|
// Autenticação está habilitada se houver senha
|
|
cfg.Auth.Enabled = cfg.Auth.Password != ""
|
|
|
|
// Validar configuração
|
|
if err := cfg.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
// Validate valida a configuração
|
|
func (c *Config) Validate() error {
|
|
// Validar porta
|
|
if c.Server.Port == "" {
|
|
return fmt.Errorf("porta do servidor não pode ser vazia")
|
|
}
|
|
|
|
// Validar TLS
|
|
if c.Server.TLSEnabled {
|
|
if c.Server.TLSCertFile == "" || c.Server.TLSKeyFile == "" {
|
|
return fmt.Errorf("TLS habilitado mas certificado ou chave não especificados")
|
|
}
|
|
}
|
|
|
|
// Validar log level
|
|
validLevels := map[string]bool{"debug": true, "info": true, "warn": true, "error": true}
|
|
if !validLevels[c.Logging.Level] {
|
|
return fmt.Errorf("nível de log inválido: %s (use: debug, info, warn, error)", c.Logging.Level)
|
|
}
|
|
|
|
// Validar log format
|
|
if c.Logging.Format != "json" && c.Logging.Format != "console" {
|
|
return fmt.Errorf("formato de log inválido: %s (use: json, console)", c.Logging.Format)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Funções auxiliares para ler variáveis de ambiente
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getEnvBool(key string, defaultValue bool) bool {
|
|
if value := os.Getenv(key); value != "" {
|
|
b, err := strconv.ParseBool(value)
|
|
if err == nil {
|
|
return b
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getEnvInt(key string, defaultValue int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
i, err := strconv.Atoi(value)
|
|
if err == nil {
|
|
return i
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
|
|
if value := os.Getenv(key); value != "" {
|
|
d, err := time.ParseDuration(value)
|
|
if err == nil {
|
|
return d
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|