Files
OliveTin/service/internal/config/config_reloader.go
James Read fa44e958d8
Some checks failed
Build Snapshot / build-snapshot (push) Has been cancelled
DevSkim / DevSkim (push) Has been cancelled
chore: Big dependency update (#553)
2025-04-06 22:26:51 +00:00

68 lines
1.6 KiB
Go

package config
import (
"os"
"path/filepath"
"reflect"
"regexp"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
var (
metricConfigActionCount = promauto.NewGauge(prometheus.GaugeOpts{
Name: "olivetin_config_action_count",
Help: "The number of actions in the config file",
})
metricConfigReloadedCount = promauto.NewCounter(prometheus.CounterOpts{
Name: "olivetin_config_reloaded_count",
Help: "The number of times the config has been reloaded",
})
listeners []func()
)
func AddListener(l func()) {
listeners = append(listeners, l)
}
func Reload(cfg *Config) {
if err := viper.UnmarshalExact(&cfg, viper.DecodeHook(envDecodeHookFunc)); err != nil {
log.Errorf("Config unmarshal error %+v", err)
os.Exit(1)
}
metricConfigReloadedCount.Inc()
metricConfigActionCount.Set(float64(len(cfg.Actions)))
cfg.SetDir(filepath.Dir(viper.ConfigFileUsed()))
cfg.Sanitize()
for _, l := range listeners {
l()
}
}
var envRegex = regexp.MustCompile(`\${{ *?(\S+) *?}}`)
func envDecodeHookFunc(from reflect.Value, to reflect.Value) (any, error) {
if from.Kind() != reflect.String {
return from.Interface(), nil
}
input := from.Interface().(string)
output := envRegex.ReplaceAllStringFunc(input, func(match string) string {
submatches := envRegex.FindStringSubmatch(match)
key := submatches[1]
val, set := os.LookupEnv(key)
if !set {
log.Warnf("Config file references unset environment variable: \"%s\"", key)
}
return val
})
return output, nil
}