102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
|
|
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
|
||
|
|
}
|