Преглед на файлове

Substitute environment variables when loading yaml config to fix #840 (#880)

James Read преди 2 седмици
родител
ревизия
e61c8b036d
променени са 2 файла, в които са добавени 15 реда и са изтрити 27 реда
  1. 9 0
      service/internal/config/config_reloader.go
  2. 6 27
      service/internal/config/config_reloader_test.go

+ 9 - 0
service/internal/config/config_reloader.go

@@ -8,6 +8,7 @@ import (
 	"sort"
 	"strings"
 
+	"github.com/go-viper/mapstructure/v2"
 	"github.com/knadh/koanf/parsers/yaml"
 	"github.com/knadh/koanf/providers/file"
 	"github.com/knadh/koanf/v2"
@@ -51,6 +52,14 @@ func AppendSource(cfg *Config, k *koanf.Koanf, configPath string) {
 func unmarshalRoot(k *koanf.Koanf, cfg *Config) bool {
 	err := k.UnmarshalWithConf("", cfg, koanf.UnmarshalConf{
 		Tag: "koanf",
+		DecoderConfig: &mapstructure.DecoderConfig{
+			DecodeHook: mapstructure.ComposeDecodeHookFunc(
+				envDecodeHookFunc,
+				mapstructure.StringToTimeDurationHookFunc(),
+				mapstructure.TextUnmarshallerHookFunc(),
+			),
+			WeaklyTypedInput: true,
+		},
 	})
 
 	if err != nil {

+ 6 - 27
service/internal/config/config_reloader_test.go

@@ -90,26 +90,22 @@ var envConfigTests = []struct {
 }
 
 func TestEnvInConfig(t *testing.T) {
-	t.Skip("Skipping test in 3k")
-
 	for _, tt := range envConfigTests {
 		cfg := DefaultConfig()
 		setIfNotEmpty("INPUT", tt.input)
-		processed := processYamlWithEnv(tt.yaml)
-		k, err := loadKoanf(processed)
+		k := koanf.New(".")
+		err := k.Load(rawbytes.Provider([]byte(tt.yaml)), yaml.Parser())
 		if err != nil {
 			t.Errorf("Error loading YAML: %v", err)
 			continue
 		}
-
-		if err := k.UnmarshalWithConf("", cfg, koanf.UnmarshalConf{
-			Tag: "koanf",
-		}); err != nil {
-			t.Errorf("Error unmarshalling config: %v", err)
+		if !unmarshalRoot(k, cfg) {
+			t.Errorf("Error unmarshalling config for env=%q", tt.input)
 			continue
 		}
 		field := tt.selector(cfg)
-		assert.Equal(t, tt.output, field, "Unmarshaled config field doesn't match expected value: env=\"%s\"", tt.input)
+		assert.Equal(t, tt.output, field,
+			"Unmarshaled config field doesn't match expected value: env=%q", tt.input)
 		os.Unsetenv("INPUT")
 	}
 }
@@ -119,20 +115,3 @@ func setIfNotEmpty(key, val string) {
 		os.Setenv(key, val)
 	}
 }
-
-func processYamlWithEnv(content string) string {
-	return envRegex.ReplaceAllStringFunc(content, func(match string) string {
-		submatches := envRegex.FindStringSubmatch(match)
-		key := submatches[1]
-		val, _ := os.LookupEnv(key)
-		return val
-	})
-}
-
-func loadKoanf(processed string) (*koanf.Koanf, error) {
-	k := koanf.New(".")
-	if err := k.Load(rawbytes.Provider([]byte(processed)), yaml.Parser()); err != nil {
-		return nil, err
-	}
-	return k, nil
-}