Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to rewrite the value in the structure slice from the environment variable /w automatic env? #935

Open
tmarcus87 opened this issue Jul 6, 2020 · 1 comment

Comments

@tmarcus87
Copy link

tmarcus87 commented Jul 6, 2020

Hello everyone.

Currently, I use viper to configure the k8s app, and pass credential information (DB password etc.) from environment variables.
However, when the configuration is a structure slice, I cannot successfully overwrite the value with the environment variable.

Is this something my settings are missing?
Or, in case of structure slice, can't it be overwritten from environment variable?

sample code here

package main

import (
	"encoding/json"
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/spf13/viper"
	"os"
	"strings"
)

var ConfigYaml = `
foo:
  host: host0
  port: 3306
  user: user0
  pass: ""
bar:
  - host: host1
    port: 3306
    user: user1
    pass: ""
  - host: host2
    port: 3306
    user: user2
    pass: ""
`

type Config struct {
	Foo ConfigValue   `yaml:"foo"`
	Bar []ConfigValue `yaml:"bar"`
}

type ConfigValue struct {
	Host string `yaml:"host"`
    Port uint16 `yaml:"port"`
    User string `yaml:"user"`
    Pass string `yaml:"pass"`
}

func main() {
	v := viper.New()

	wd, _ := os.Getwd()
	v.AddConfigPath(wd)
	v.SetConfigType("yaml")
	v.SetConfigName("config")

	v.AutomaticEnv()
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

	if err := v.ReadConfig(strings.NewReader(ConfigYaml)); err != nil {
		panic(err)
	}

	cfg := Config{}
	if err := v.Unmarshal(&cfg, func(cfg *mapstructure.DecoderConfig) { cfg.TagName = "yaml" }); err != nil {
		panic(err)
	}

	bs, _ := json.MarshalIndent(cfg, "", "  ")
	fmt.Println(string(bs))
}

run with environment variable.

mylaptop $ FOO_PASS=pass0  BAR_0_PASS=pass1  BAR_1_PASS=pass2 go run main.go
{
  "Foo": {
    "Host": "host0",
    "Port": 3306,
    "User": "user0",
    "Pass": "pass0"            // <- override OK
  },
  "Bar": [
    {
      "Host": "host1",
      "Port": 3306,
      "User": "user1",
      "Pass": ""               // <- override NG
    },
    {
      "Host": "host2",
      "Port": 3306,
      "User": "user2",
      "Pass": ""
    }
  ]
}
@andig
Copy link
Contributor

andig commented Feb 14, 2023

We would be interested in support for slices from env as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants