Skip to content

Commit 69326d1

Browse files
committed
fix: Disable viper auto-env to avoid assigning to parent structs
The viper automatic env mapping and BindEnv were both creating mappings like `vip.BindEnv("telemetry", "CODER_TELEMETRY")` which we don't want since `DeploymentConfig.Telemetry` is a struct housing fields. For some reason, this was causing `DeploymentConfig.Telemetry.URL` to **not** be assigned its default value when `CODER_TELEMETRY=false` was set as an environment variable. Potentially we would want `"telemetry.enable"` to be mapped to `"CODER_TELEMETRY"` for simplicity. But that behavior is not changed by this commit. Arguably, we could remove `vip.SetEnvPrefix` and `vip.SetEnvKeyReplacer` as well since we're manually controlling all environment variable names via `formatEnv`.
1 parent 3f6c448 commit 69326d1

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

cli/deployment/config.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ func Config(flagset *pflag.FlagSet, vip *viper.Viper) (*codersdk.DeploymentConfi
370370
return nil, xerrors.Errorf("get global config from flag: %w", err)
371371
}
372372
vip.SetEnvPrefix("coder")
373-
vip.AutomaticEnv()
374373

375374
if flg != "" {
376375
vip.SetConfigFile(flg + "/server.yaml")
@@ -393,21 +392,26 @@ func setConfig(prefix string, vip *viper.Viper, target interface{}) {
393392
typ = val.Type()
394393
}
395394

396-
// Manually bind to env to support CODER_$INDEX_$FIELD format for structured slices.
397-
_ = vip.BindEnv(prefix, formatEnv(prefix))
398-
395+
// Ensure that we only bind env variables to proper fields,
396+
// otherwise Viper will get confused if the parent struct is
397+
// assigned a value.
399398
if strings.HasPrefix(typ.Name(), "DeploymentConfigField[") {
400399
value := val.FieldByName("Value").Interface()
401400
switch value.(type) {
402401
case string:
402+
vip.MustBindEnv(prefix, formatEnv(prefix))
403403
val.FieldByName("Value").SetString(vip.GetString(prefix))
404404
case bool:
405+
vip.MustBindEnv(prefix, formatEnv(prefix))
405406
val.FieldByName("Value").SetBool(vip.GetBool(prefix))
406407
case int:
408+
vip.MustBindEnv(prefix, formatEnv(prefix))
407409
val.FieldByName("Value").SetInt(int64(vip.GetInt(prefix)))
408410
case time.Duration:
411+
vip.MustBindEnv(prefix, formatEnv(prefix))
409412
val.FieldByName("Value").SetInt(int64(vip.GetDuration(prefix)))
410413
case []string:
414+
vip.MustBindEnv(prefix, formatEnv(prefix))
411415
// As of October 21st, 2022 we supported delimiting a string
412416
// with a comma, but Viper only supports with a space. This
413417
// is a small hack around it!
@@ -422,6 +426,7 @@ func setConfig(prefix string, vip *viper.Viper, target interface{}) {
422426
}
423427
val.FieldByName("Value").Set(reflect.ValueOf(value))
424428
case []codersdk.GitAuthConfig:
429+
// Do not bind to CODER_GITAUTH, instead bind to CODER_GITAUTH_0_*, etc.
425430
values := readSliceFromViper[codersdk.GitAuthConfig](vip, prefix, value)
426431
val.FieldByName("Value").Set(reflect.ValueOf(values))
427432
default:
@@ -471,6 +476,11 @@ func readSliceFromViper[T any](vip *viper.Viper, key string, value any) []T {
471476
prop = fve.Tag.Get("yaml")
472477
}
473478
configKey := fmt.Sprintf("%s.%d.%s", key, entry, prop)
479+
480+
// Ensure the env entry for this key is registered
481+
// before checking value.
482+
vip.MustBindEnv(configKey, formatEnv(configKey))
483+
474484
value := vip.Get(configKey)
475485
if value == nil {
476486
continue
@@ -502,7 +512,6 @@ func NewViper() *viper.Viper {
502512
dc := newConfig()
503513
vip := viper.New()
504514
vip.SetEnvPrefix("coder")
505-
vip.AutomaticEnv()
506515
vip.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
507516

508517
setViperDefaults("", vip, dc)
@@ -566,6 +575,10 @@ func setFlags(prefix string, flagset *pflag.FlagSet, vip *viper.Viper, target in
566575
hidden := val.FieldByName("Hidden").Bool()
567576
value := val.FieldByName("Default").Interface()
568577

578+
// Allow currently set environment variables
579+
// to override default values in help output.
580+
vip.MustBindEnv(prefix, formatEnv(prefix))
581+
569582
switch value.(type) {
570583
case string:
571584
_ = flagset.StringP(flg, shorthand, vip.GetString(prefix), usage)

0 commit comments

Comments
 (0)