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

How about adding the ability to use dynamic values in a config file? #112

Open
gocruncher opened this issue Feb 16, 2023 · 1 comment
Open

Comments

@gocruncher
Copy link

gocruncher commented Feb 16, 2023

Example:

psql:
      host: ${DB_HOST}
      port: ${DB_PORT}
      user: ${DB_USER}
      password: ${DB_PASSWORD}
      database: default

where DB_HOST,DB_PORT,... are the environment variables

@tahacodes
Copy link

Hi there

So if i understand this currently, you need to load a config file into your application but some of the variables need to be set by environment variables.

I had a similar experience and this little trick may be helpful:

if errConfig := cleanenv.ReadConfig("config.yaml", configuration); errConfig != nil {
	if errEnv := cleanenv.ReadEnv(configuration); errEnv != nil {
		return nil, multierr.Combine(errConfig, errEnv)
	}
}

Basically you can load your configs from a config.yaml file but you can also load some other variables from env after that and you can use the uber's "multierr" package to combine ReadConfig and ReadEnv errors together. Here's an example of the struct that i used:

type Configuration struct {
	Dialer struct {
		UpstreamTimeout    string `env:"DIALER_UPSTREAM_TIMEOUT" env-default:"2s"`
		KeepAliveDuration  string `env:"DIALER_KEEPALIVE_DURATION" env-default:"5s"`
		InsecureSkipVerify bool   `env:"DIALER_INSECURE_SKIP_VERIFY" env-default:"false"`
	}

	DNS struct {
		Resolver string `env:"DNS_RESOLVER" env-default:"8.8.8.8:53"`
		Protocol string `env:"DNS_PROTOCOL" env-default:"udp"`
		Timeout  string `env:"DNS_TIMEOUT" env-default:"10ms"`
	}

	Log struct {
		LogLevel      string `env:"LOG_LEVEL" env-default:"info"`
		SentryDSN     string `env:"SENTRY_DSN"`
		TimePrecision uint   `env:"LOG_TIMEPRECISION" env-default:"3"`
	}

	Storage struct {
		Endpoints []struct {
			Name         string `yaml:"name"`
			Endpoint     string `yaml:"endpoint"`
		} `yaml:"endpoints"`

		Key struct {
			ServiceAlpha struct {
				Access string `env:"STORAGE_ALPHA_ACCESS"`
				Secret string `env:"STORAGE_ALPHA_SECRET"`
			}
			ServiceBeta struct {
				Access string `env:"STORAGE_BETA_ACCESS"`
				Secret string `env:"STORAGE_BETA_SECRET"`
			}
		}
	} `yaml:"storage"`
}

As you can see i have a combination of yaml configs and env configs.

Here's the config.yaml as well:

storage:
  endpoints:
    - name: Main
      endpoint: https://s3.us-east-2.amazonaws.com
    - name: Fallback
      endpoint: https://s3.us-west-2.amazonaws.com

Hope this helps.

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