fix!(config): read all env variables into config store explicitly
This changes the way environment variables are read into Vikunja's config. With this change, Vikunja loads the config from all env variables into the config store explicitly, after all config files have been processed. The breaking change here is that values from env variables now may override values from a config file when both are specified. This allows specifying openid providers using only environment values. Previously this still required a config file to work, because viper wouldn't know about these values otherwise. Resolves https://community.vikunja.io/t/configure-openid-via-environment/628/16
This commit is contained in:
parent
9aa197b196
commit
5c02527d2d
|
|
@ -29,6 +29,7 @@ import (
|
|||
_ "time/tzdata" // Imports time zone data instead of relying on the os
|
||||
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
|
@ -458,6 +459,40 @@ func readConfigValuesFromFiles() {
|
|||
}
|
||||
}
|
||||
|
||||
func setConfigFromEnv() error {
|
||||
envKeys := os.Environ()
|
||||
configMap := make(map[string]any)
|
||||
for _, envKeyValue := range envKeys {
|
||||
keyValue := strings.SplitN(envKeyValue, "=", 2)
|
||||
if len(keyValue) != 2 {
|
||||
continue
|
||||
}
|
||||
key, value := keyValue[0], keyValue[1]
|
||||
|
||||
if strings.HasPrefix(key, "VIKUNJA_") {
|
||||
formattedKey := strings.ToLower(strings.TrimPrefix(key, "VIKUNJA_"))
|
||||
keys := strings.Split(formattedKey, "_")
|
||||
currentMap := configMap
|
||||
|
||||
for i, part := range keys {
|
||||
if i == len(keys)-1 {
|
||||
// Set the value at the final level
|
||||
currentMap[part] = value
|
||||
} else {
|
||||
// Check if the key exists at the current level, create a new map if not
|
||||
if _, exists := currentMap[part]; !exists {
|
||||
currentMap[part] = make(map[string]any)
|
||||
}
|
||||
|
||||
// Move into the nested map
|
||||
currentMap = currentMap[part].(map[string]any)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return viper.MergeConfigMap(configMap)
|
||||
}
|
||||
|
||||
// InitConfig initializes the config, sets defaults etc.
|
||||
func InitConfig() {
|
||||
|
||||
|
|
@ -469,8 +504,6 @@ func InitConfig() {
|
|||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.AutomaticEnv()
|
||||
|
||||
// Just load environment variables
|
||||
_ = viper.ReadInConfig()
|
||||
log.ConfigureLogger(LogEnabled.GetBool(), LogStandard.GetString(), LogPath.GetString(), LogLevel.GetString())
|
||||
|
||||
// Load the config file
|
||||
|
|
@ -502,6 +535,11 @@ func InitConfig() {
|
|||
log.Info("No config file found, using default or config from environment variables.")
|
||||
}
|
||||
|
||||
err = setConfigFromEnv()
|
||||
if err != nil {
|
||||
log.Warningf("Failed to set config from environment variables: %s", err.Error())
|
||||
}
|
||||
|
||||
readConfigValuesFromFiles()
|
||||
|
||||
if RateLimitStore.GetString() == "keyvalue" {
|
||||
|
|
|
|||
Loading…
Reference in New Issue