2025-07-10 01:18:05 +07:00

112 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"encoding/json"
"github.com/joho/godotenv"
"log/slog"
"os"
"regexp"
"yobble-gateway-go/internal/logger"
"gopkg.in/yaml.v3"
)
// Backend представляет собой отдельный сервер бэкенда.
type Backend struct {
URL string `json:"url"`
Role string `json:"role"`
AllowSelfSigned bool `json:"allow_self_signed"`
}
// Routes сопоставляет строки версий с префиксами маршрутов и бэкендами.
type Routes map[string]map[string][]Backend
// ServerConfig содержит настройки, связанные с сервером.
type ServerConfig struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
}
// GatewayConfig содержит настройки, специфичные для шлюза.
type GatewayConfig struct {
RouteFile string `yaml:"route_file"`
GeoIPDB string `yaml:"geoip_db"`
BlockedCountries []string `yaml:"blocked_countries"`
}
// TLSConfig содержит настройки, связанные с TLS.
type TLSConfig struct {
FullChain string `yaml:"full_chain"`
PrivateKey string `yaml:"private_key"`
}
// LogConfig содержит настройки, связанные с логированием.
type LogConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
}
// Settings содержит всю конфигурацию приложения.
type Settings struct {
Server ServerConfig `yaml:"server"`
Gateway GatewayConfig `yaml:"gateway"`
TLS TLSConfig `yaml:"tls"`
Logging LogConfig `yaml:"logging"`
RouteConfig Routes `yaml:"-"` // Загружается отдельно, не из корня YAML
}
// Load возвращает новый объект конфигурации, считывая YAML-файл.
func Load(configPath string) (*Settings, error) {
op := "config.Load"
log := logger.NewLoggerWithOp(op)
if err := godotenv.Load(); err != nil {
log.Warn("[Attention]: No .env file found or failed to load, using STANDARD settings!")
}
configFile, err := os.ReadFile(configPath)
if err != nil {
log.Error("failed to read config file", slog.String("path", configPath), slog.Any("error", err))
return nil, err
}
processed := replaceEnvVars(string(configFile))
var settings Settings
if err := yaml.Unmarshal([]byte(processed), &settings); err != nil {
log.Error("failed to unmarshal config file", slog.String("path", configPath), slog.Any("error", err))
return nil, err
}
// Загружаем маршруты из JSON-файла
routeFile, err := os.ReadFile(settings.Gateway.RouteFile)
if err != nil {
log.Error("failed to read route file", slog.String("path", settings.Gateway.RouteFile), slog.Any("error", err))
return nil, err
}
var routes Routes
if err := json.Unmarshal(routeFile, &routes); err != nil {
log.Error("failed to unmarshal route file", slog.String("path", settings.Gateway.RouteFile), slog.Any("error", err))
return nil, err
}
settings.RouteConfig = routes
return &settings, nil
}
// replaceEnvVars Поддержка ${ENV_VAR:default} AKA SpringBoot
func replaceEnvVars(input string) string {
re := regexp.MustCompile(`\$\{([^}:\s]+)(?::([^}]*))?\}`)
return re.ReplaceAllStringFunc(input, func(s string) string {
matches := re.FindStringSubmatch(s)
envVar := matches[1]
defVal := matches[2]
val := os.Getenv(envVar)
if val == "" {
val = defVal
}
return val
})
}