diff --git a/Dockerfile b/Dockerfile index 8639ca0..4d3bc6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:latest +FROM alpine:3.22 RUN apk --no-cache add ca-certificates ARG IMAGE_TAG diff --git a/go.mod b/go.mod index d2af6d4..4352619 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,9 @@ module github.com/codeshelldev/secured-signal-api go 1.25.4 -require github.com/codeshelldev/gotl v0.0.2 +require github.com/codeshelldev/gotl v0.0.4-29 -require go.uber.org/zap v1.27.0 // indirect +require go.uber.org/zap v1.27.1 // indirect require ( github.com/fsnotify/fsnotify v1.9.0 // indirect diff --git a/go.sum b/go.sum index a51f9a7..3df5b8d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,27 @@ -github.com/codeshelldev/gotl v0.0.2 h1:PQbipYHut3DNvwcrdkQmIGo2p6X6a889Glmba/KIeFQ= -github.com/codeshelldev/gotl v0.0.2/go.mod h1:OzawxKcFw9QEgbeR5H2UXryhYeeLo8xSLme1r8viE+U= +github.com/codeshelldev/gotl v0.0.4-18 h1:Uv7803qOcaVI7zVyBmadX2SCObHvbO9LBcBUNWa0Ejg= +github.com/codeshelldev/gotl v0.0.4-18/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-19 h1:dshnBkR7F8BvzVD2aakk8yFKWB7aZZbAA4TjOLrzyaA= +github.com/codeshelldev/gotl v0.0.4-19/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-20 h1:B7tTiiDiCpr/WnkK8O6jj2Q+GIzykNgX4qsvTLWyRzQ= +github.com/codeshelldev/gotl v0.0.4-20/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-21 h1:umeAIi56fmAyWw5fz5eXnrje6pAS1nqlDlKrXGhdp9k= +github.com/codeshelldev/gotl v0.0.4-21/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-22 h1:wfPxZa5B2HX5rhZlbz3Yl2uukNUGko3ayFVPDcA3rmA= +github.com/codeshelldev/gotl v0.0.4-22/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-23 h1:A83kFtHLO8ryPxTsH0bXGsx+upzpDOooPLygCePeD6Y= +github.com/codeshelldev/gotl v0.0.4-23/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-24 h1:XwOlOA1OKjpCuBG4jWe51aVYYghtgPCBPy03F/UYFcc= +github.com/codeshelldev/gotl v0.0.4-24/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-25 h1:79FIwopXMuKPqYAE/G1dlso5v5LYnREgAmQCfURjYxM= +github.com/codeshelldev/gotl v0.0.4-25/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-26 h1:qT+ybh/bauRLE4irt45oAV14mCrkmXBG/zeZqryj3Mo= +github.com/codeshelldev/gotl v0.0.4-26/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-27 h1:SV8Oad50uYpwMSdLpS6uOkJlSHrvSKi0KBe0Sf+0TQU= +github.com/codeshelldev/gotl v0.0.4-27/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-28 h1:Q1lWa0hcvRp1jVJmWicGNsQyupBy/s7N8gi++Jgvf4E= +github.com/codeshelldev/gotl v0.0.4-28/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= +github.com/codeshelldev/gotl v0.0.4-29 h1:c1fRnCQsP7DgqyRgYE2+9jg7FlgGsVAdFbeHX1gxe5A= +github.com/codeshelldev/gotl v0.0.4-29/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= @@ -34,8 +56,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= diff --git a/internals/config/loader.go b/internals/config/loader.go index f51fa8f..3088914 100644 --- a/internals/config/loader.go +++ b/internals/config/loader.go @@ -15,18 +15,20 @@ import ( ) var ENV *structure.ENV = &structure.ENV{ - CONFIG_PATH: os.Getenv("CONFIG_PATH"), - DEFAULTS_PATH: os.Getenv("DEFAULTS_PATH"), - TOKENS_DIR: os.Getenv("TOKENS_DIR"), - FAVICON_PATH: os.Getenv("FAVICON_PATH"), - CONFIGS: map[string]*structure.CONFIG{}, - INSECURE: false, + CONFIG_PATH: os.Getenv("CONFIG_PATH"), + DEFAULTS_PATH: os.Getenv("DEFAULTS_PATH"), + TOKENS_DIR: os.Getenv("TOKENS_DIR"), + FAVICON_PATH: os.Getenv("FAVICON_PATH"), + INSECURE: false, + + CONFIGS: map[string]*structure.CONFIG{}, } var DEFAULT *structure.CONFIG var defaultsConf *configutils.Config var userConf *configutils.Config +var envConf *configutils.Config var tokenConf *configutils.Config var mainConf *configutils.Config @@ -42,32 +44,39 @@ func Load() { LoadTokens() - userConf.LoadEnv(normalizeEnv) + NormalizeConfig("", defaultsConf) + NormalizeConfig("config", userConf) - NormalizeConfig(defaultsConf) - NormalizeConfig(userConf) - - NormalizeTokens() + envConf.LoadEnv(normalizeEnv) + NormalizeConfig("env", envConf) + + userConf.MergeLayers(envConf.Layer) + mainConf.MergeLayers(defaultsConf.Layer, userConf.Layer) mainConf.TemplateConfig() - InitTokens() + NormalizeTokens() + + InitConfig() - InitEnv() + InitTokens() log.Info("Finished Loading Configuration") } func Log() { - log.Dev("Loaded Config:", mainConf.Layer.All()) - log.Dev("Loaded Token Configs:", tokenConf.Layer.All()) + // TODO: Change back to `log.Dev()` as soon as config parsing is working again. + log.Info("Loaded Config:", mainConf.Layer.Get("")) + log.Info("Loaded Token Configs:", tokenConf.Layer.Get("")) + log.Info("Parsed Configs: ", ENV) } func Clear() { defaultsConf = configutils.New() userConf = configutils.New() + envConf = configutils.New() tokenConf = configutils.New() mainConf = configutils.New() } @@ -85,11 +94,11 @@ func LowercaseKeys(config *configutils.Config) { config.Load(data, "") } -func NormalizeConfig(config *configutils.Config) { - Normalize(config, "", &structure.CONFIG{}) +func NormalizeConfig(id string, config *configutils.Config) { + Normalize(id, config, "", &structure.CONFIG{}) } -func Normalize(config *configutils.Config, path string, structure any) { +func Normalize(id string, config *configutils.Config, path string, structure any) { data := config.Layer.Get(path) old, ok := data.(map[string]any) @@ -103,7 +112,7 @@ func Normalize(config *configutils.Config, path string, structure any) { tmpConf.Load(old, "") // Apply transforms to the new config - tmpConf.ApplyTransformFuncs(structure, "", transformFuncs) + tmpConf.ApplyTransformFuncs(id, structure, "", transformFuncs) // Lowercase actual config LowercaseKeys(config) @@ -126,7 +135,7 @@ func InitReload() { tokenConf.OnReload(reload) } -func InitEnv() { +func InitConfig() { var config structure.CONFIG mainConf.Layer.Unmarshal("", &config) @@ -161,3 +170,11 @@ func LoadConfig() { log.Error("Could not Load Config ", ENV.CONFIG_PATH, ": ", err.Error()) } } + +func normalizeEnv(key string, value string) (string, any) { + key = strings.ToLower(key) + key = strings.ReplaceAll(key, "__", ".") + key = strings.ReplaceAll(key, "_", "") + + return key, stringutils.ToType(value) +} diff --git a/internals/config/structure/structure.go b/internals/config/structure/structure.go index 38fce9c..148dfcb 100644 --- a/internals/config/structure/structure.go +++ b/internals/config/structure/structure.go @@ -13,17 +13,17 @@ type ENV struct { type CONFIG struct { SERVICE SERVICE `koanf:"service"` API API `koanf:"api"` - SETTINGS SETTINGS `koanf:"settings" aliases:"overrides"` + SETTINGS SETTINGS `koanf:"settings" token>aliases:"overrides"` } type SERVICE struct { - PORT string `koanf:"port"` - LOG_LEVEL string `koanf:"loglevel"` + PORT string `koanf:"port" env>aliases:".port"` + LOG_LEVEL string `koanf:"loglevel" env>aliases:".loglevel"` } type API struct { - URL string `koanf:"url"` - TOKENS []string `koanf:"tokens" aliases:"token"` + URL string `koanf:"url" env>aliases:".apiurl"` + TOKENS []string `koanf:"tokens" env>aliases:".apitokens,.apitoken" aliases:"token"` } type SETTINGS struct { diff --git a/internals/config/tokens.go b/internals/config/tokens.go index ac00219..716b977 100644 --- a/internals/config/tokens.go +++ b/internals/config/tokens.go @@ -28,7 +28,7 @@ func NormalizeTokens() { tmpConf := configutils.New() tmpConf.Load(config.Raw(), "") - Normalize(tmpConf, "overrides", &structure.SETTINGS{}) + Normalize("token", tmpConf, "", &structure.SETTINGS{}) data = append(data, tmpConf.Layer.Raw()) } @@ -38,7 +38,7 @@ func NormalizeTokens() { } func InitTokens() { - apiTokens := mainConf.Layer.Strings("api.tokens") + apiTokens := DEFAULT.API.TOKENS var tokenConfigs []structure.CONFIG @@ -61,7 +61,7 @@ func InitTokens() { // Set Blocked Endpoints on Config to User Layer Value // => effectively ignoring Default Layer - mainConf.Layer.Set("settings.access.endpoints", userConf.Layer.Strings("settings.access.endpoints")) + DEFAULT.SETTINGS.ACCESS.ENDPOINTS = userConf.Layer.Strings("settings.access.endpoints") } if len(apiTokens) > 0 {