Files
gotail/backend/internal/config/config.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
}