feat: init commit with main func
This commit is contained in:
112
config.go
Normal file
112
config.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Config holds all runtime configuration loaded from environment variables.
|
||||
type Config struct {
|
||||
TraefikURL string
|
||||
TraefikUsername string
|
||||
TraefikPassword string
|
||||
|
||||
Zones []string
|
||||
PublicIP string
|
||||
PublicIPv6 string // empty = no AAAA records
|
||||
|
||||
RepoPath string
|
||||
RepoBranch string
|
||||
RepoRemote string
|
||||
DynamicDir string
|
||||
AuthorName string
|
||||
AuthorEmail string
|
||||
|
||||
ReconcileInterval time.Duration
|
||||
DebounceDelay time.Duration
|
||||
|
||||
RecordTTL int
|
||||
ExcludeRouters map[string]struct{}
|
||||
}
|
||||
|
||||
// LoadConfig reads configuration from environment variables and validates required fields.
|
||||
func LoadConfig() (*Config, error) {
|
||||
cfg := &Config{}
|
||||
|
||||
cfg.TraefikURL = envOrDefault("TRAEFIK_URL", "http://localhost:8080")
|
||||
cfg.TraefikUsername = os.Getenv("TRAEFIK_USERNAME")
|
||||
cfg.TraefikPassword = os.Getenv("TRAEFIK_PASSWORD")
|
||||
|
||||
zonesStr := os.Getenv("DNS_ZONES")
|
||||
if zonesStr == "" {
|
||||
return nil, fmt.Errorf("DNS_ZONES is required (comma-separated list of zones, e.g. example.com,example.net)")
|
||||
}
|
||||
for _, z := range strings.Split(zonesStr, ",") {
|
||||
if z = strings.TrimSpace(z); z != "" {
|
||||
cfg.Zones = append(cfg.Zones, z)
|
||||
}
|
||||
}
|
||||
|
||||
cfg.PublicIP = os.Getenv("PUBLIC_IP")
|
||||
if cfg.PublicIP == "" {
|
||||
return nil, fmt.Errorf("PUBLIC_IP is required")
|
||||
}
|
||||
cfg.PublicIPv6 = os.Getenv("PUBLIC_IPV6")
|
||||
|
||||
cfg.RepoPath = os.Getenv("DNS_REPO_PATH")
|
||||
if cfg.RepoPath == "" {
|
||||
return nil, fmt.Errorf("DNS_REPO_PATH is required")
|
||||
}
|
||||
|
||||
cfg.RepoBranch = envOrDefault("DNS_REPO_BRANCH", "main")
|
||||
cfg.RepoRemote = envOrDefault("DNS_REPO_REMOTE", "origin")
|
||||
cfg.DynamicDir = envOrDefault("DNS_REPO_DYNAMIC_DIR", "zones-dynamic")
|
||||
cfg.AuthorName = envOrDefault("DNS_REPO_AUTHOR_NAME", "traefik-dns-watcher")
|
||||
cfg.AuthorEmail = envOrDefault("DNS_REPO_AUTHOR_EMAIL", "dns-bot@localhost")
|
||||
|
||||
var err error
|
||||
cfg.ReconcileInterval, err = parseDurationEnv("RECONCILE_INTERVAL", "60s")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.DebounceDelay, err = parseDurationEnv("DEBOUNCE_DELAY", "5s")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ttlStr := envOrDefault("RECORD_TTL", "300")
|
||||
cfg.RecordTTL, err = strconv.Atoi(ttlStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("RECORD_TTL: invalid integer %q: %w", ttlStr, err)
|
||||
}
|
||||
|
||||
cfg.ExcludeRouters = make(map[string]struct{})
|
||||
if v := os.Getenv("EXCLUDE_ROUTERS"); v != "" {
|
||||
for _, r := range strings.Split(v, ",") {
|
||||
if r = strings.TrimSpace(r); r != "" {
|
||||
cfg.ExcludeRouters[r] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func envOrDefault(key, def string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func parseDurationEnv(key, def string) (time.Duration, error) {
|
||||
s := envOrDefault(key, def)
|
||||
d, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%s: invalid duration %q: %w", key, s, err)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
Reference in New Issue
Block a user