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

Stripping underscores makes viper unable to find env vars #1009

Closed
dionb opened this issue Oct 26, 2020 · 3 comments
Closed

Stripping underscores makes viper unable to find env vars #1009

dionb opened this issue Oct 26, 2020 · 3 comments
Labels
kind/support Support requests for using the project resolution/duplicate This issue or pull request already exists

Comments

@dionb
Copy link

dionb commented Oct 26, 2020

Am I going mad, or is there definitely a problem when stripping the _ from env names? I want to make it so that you can configure my app with either env, config file, or flags. And then use viper.Unmarshal() to write the values into my config object. But stripping the underscores from env keys makes viper miss them completely.
In the following test I would expect to get either ":9090" or ":9091" (which is not important at the moment) but no value is found at all. It would appear that the key replacer is being run before the prefix is being stripped and checked, and so it can no longer be found and the keys are rejected.


func NewViper() *viper.Viper {
	v := viper.New()
	v.AutomaticEnv()
	return v
}

func SetEnv(t *testing.T, key string, value string) {
	err := os.Setenv(key, value)
	require.NoError(t, err)
}

func TestStripUnderscore(t *testing.T) {
	viper := NewViper()
	viper.SetEnvPrefix("rp")
	viper.SetEnvKeyReplacer(strings.NewReplacer("_", ""))
	SetEnv(t, "RP_LISTENSOCKET", ":9090")
	SetEnv(t, "RP_LISTEN_SOCKET", ":9091")
	defer os.Clearenv()
	assert.Equal(t, ":9090", viper.Get("listensocket"))
}

func TestStripUnderscoreWithoutPrefix(t *testing.T) {
	viper := NewViper()
	viper.SetEnvKeyReplacer(strings.NewReplacer("_", ""))
	SetEnv(t, "LISTEN_SOCKET", ":9091")
	defer os.Clearenv()
	assert.Equal(t, ":9091", viper.Get("listensocket"))
}

@github-actions
Copy link

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news,
either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

@dionb
Copy link
Author

dionb commented Oct 26, 2020

Here's the relevant source from my app. It seems to be working perferctly aside from the env variables not being found if the string replacer is present (and I have checked/updated env var names appropriately).


type config struct {
	ValidDomains  []string `mapstructure:"validdomains"`
	ValidRegions  []string `mapstructure:"validregions"`
	DefaultRegion string   `mapstructure:"defaultregion"`
	ListenSocket  string   `mapstructure:"listensocket"`
}

func loadConfig() config {
	viper.AutomaticEnv()
	viper.SetEnvPrefix("rp")
	viper.SetEnvKeyReplacer(strings.NewReplacer("_", ""))

	viper.ReadInConfig()

	pflag.StringSlice("validRegions", nil, "The list of regions that we currently support")
	pflag.String("defaultRegion", "SGP", "The region to use if none is specified in the request")
	pflag.String("listenSocket", ":80", "The socket/interface:port that this proxy should listen on")
	pflag.StringSlice("validDomains", nil, "The set of string that should have the region appended when found in the host in a request")

	pflag.Parse()
	err := viper.BindPFlags(pflag.CommandLine)
	if err != nil {
		log.Fatal(err)
	}

	conf := config{}
	err = viper.Unmarshal(&conf)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("%#v\n", conf)

	return conf
}

@sagikazarmark
Copy link
Collaborator

Automatic env doesn't work with unmarshal on its own. You either have to bind the env var manually, or set a default using SetDefault.

Duplicate of #761

@sagikazarmark sagikazarmark added kind/support Support requests for using the project resolution/duplicate This issue or pull request already exists labels Oct 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/support Support requests for using the project resolution/duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants