102 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-01-31 03:34:34 -03:00
package config
import (
"errors"
"os"
"strconv"
"strings"
)
const (
defaultResticImage = "restic/restic:0.16.4"
defaultJobTTLSeconds = 86400
defaultListenAddr = ":8080"
defaultResticSecret = "soteria-restic"
serviceNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
)
type Config struct {
Namespace string
SecretNamespace string
ResticImage string
ResticRepository string
ResticSecretName string
ResticBackupArgs []string
ResticForgetArgs []string
S3Endpoint string
S3Region string
JobTTLSeconds int32
WorkerServiceAccount string
ListenAddr string
}
func Load() (*Config, error) {
cfg := &Config{}
cfg.Namespace = getenv("SOTERIA_NAMESPACE")
if cfg.Namespace == "" {
ns, _ := os.ReadFile(serviceNamespacePath)
cfg.Namespace = strings.TrimSpace(string(ns))
}
if cfg.Namespace == "" {
cfg.Namespace = "soteria"
}
cfg.SecretNamespace = getenv("SOTERIA_SECRET_NAMESPACE")
if cfg.SecretNamespace == "" {
cfg.SecretNamespace = cfg.Namespace
}
cfg.ResticImage = getenvDefault("SOTERIA_RESTIC_IMAGE", defaultResticImage)
cfg.ResticRepository = getenv("SOTERIA_RESTIC_REPOSITORY")
cfg.ResticSecretName = getenvDefault("SOTERIA_RESTIC_SECRET_NAME", defaultResticSecret)
cfg.ResticBackupArgs = strings.Fields(getenv("SOTERIA_RESTIC_BACKUP_ARGS"))
cfg.ResticForgetArgs = strings.Fields(getenv("SOTERIA_RESTIC_FORGET_ARGS"))
cfg.S3Endpoint = getenv("SOTERIA_S3_ENDPOINT")
cfg.S3Region = getenv("SOTERIA_S3_REGION")
cfg.WorkerServiceAccount = getenv("SOTERIA_JOB_SERVICE_ACCOUNT")
cfg.ListenAddr = getenvDefault("SOTERIA_LISTEN_ADDR", defaultListenAddr)
if ttl, ok := getenvInt("SOTERIA_JOB_TTL_SECONDS"); ok {
cfg.JobTTLSeconds = int32(ttl)
} else {
cfg.JobTTLSeconds = defaultJobTTLSeconds
}
if cfg.ResticRepository == "" {
return nil, errors.New("SOTERIA_RESTIC_REPOSITORY is required")
}
if cfg.ResticSecretName == "" {
return nil, errors.New("SOTERIA_RESTIC_SECRET_NAME is required")
}
if strings.Contains(cfg.ResticRepository, "..") {
return nil, errors.New("SOTERIA_RESTIC_REPOSITORY contains invalid path segments")
}
return cfg, nil
}
func getenv(key string) string {
return strings.TrimSpace(os.Getenv(key))
}
func getenvDefault(key, value string) string {
if v := getenv(key); v != "" {
return v
}
return value
}
func getenvInt(key string) (int, bool) {
val := getenv(key)
if val == "" {
return 0, false
}
parsed, err := strconv.Atoi(val)
if err != nil {
return 0, false
}
return parsed, true
}