Go viper .yaml 值环境变量覆盖

Ajd*_*lac 4 go viper-go

我正在尝试application.yaml在 go 应用程序中有文件,其中包含${RMQ_HOST}我想用环境变量覆盖的值。

application.yaml我有:

rmq:
  test:
    host: ${RMQ_HOST}
    port: ${RMQ_PORT}
Run Code Online (Sandbox Code Playgroud)

在我的装载机中,我有:

log.Println("Loading config...")
viper.SetConfigName("application")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AutomaticEnv()
err := viper.ReadInConfig()
Run Code Online (Sandbox Code Playgroud)

${RMQ_HOST}遇到的问题是不会被我在环境变量中设置的值替换,并尝试使用此字符串连接到 RabbitMQ

amqp://test:test@${RMQ_HOST}:${RMQ_PORT}/test

代替

amqp://test:test@test:test/test

Ajd*_*lac 5

Viper 无法在键/值对中保留值的占位符,所以我设法用这个代码片段解决了我的问题:

log.Println("Loading config...")
viper.SetConfigName("application")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
    panic("Couldn't load configuration, cannot start. Terminating. Error: " + err.Error())
}
log.Println("Config loaded successfully...")
log.Println("Getting environment variables...")
for _, k := range viper.AllKeys() {
    value := viper.GetString(k)
    if strings.HasPrefix(value, "${") && strings.HasSuffix(value, "}") {
        viper.Set(k, getEnvOrPanic(strings.TrimSuffix(strings.TrimPrefix(value,"${"), "}")))
    }
}

func getEnvOrPanic(env string) string {
    res := os.Getenv(env)
    if len(res) == 0 {
        panic("Mandatory env variable not found:" + env)
    }
    return res
}
Run Code Online (Sandbox Code Playgroud)

这将覆盖集合中找到的所有占位符。


krs*_*oni 5

可能不是直接答案,而是您要解决的问题的解决方案。

很可能您不需要更换。如果您将 yml 中的键留空并打开viper.AutomaticEnv(),那么它将从环境变量中选择这些值。您还需要添加一个替换器来将键与环境名称相匹配,例如:

viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.SetConfigFile("config.yml")
config := &Config{}
Run Code Online (Sandbox Code Playgroud)

现在,当您解编配置时,您将从 env 中获取丢失的密钥。

示例:RABBITMQ_PASSWORDenv 变量将用于设置rabbitmq.password您的 yml 是否如下所示:

rabbitmq
  password: ""
Run Code Online (Sandbox Code Playgroud)