首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Go viper .yaml值环境变量重写

Go viper .yaml值环境变量重写
EN

Stack Overflow用户
提问于 2018-10-11 09:20:51
回答 6查看 5.2K关注 0票数 6

我在go应用程序中尝试使用application.yaml文件,该应用程序包含${RMQ_HOST}值,我希望用环境变量覆盖这些值。

application.yaml,我有:

代码语言:javascript
运行
复制
rmq:
  test:
    host: ${RMQ_HOST}
    port: ${RMQ_PORT}

在我的装载机里:

代码语言:javascript
运行
复制
log.Println("Loading config...")
viper.SetConfigName("application")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AutomaticEnv()
err := viper.ReadInConfig()

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

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

而不是

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

EN

回答 6

Stack Overflow用户

发布于 2018-10-12 10:27:47

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

代码语言:javascript
运行
复制
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
}

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

票数 5
EN

Stack Overflow用户

发布于 2019-02-14 11:44:38

更新:

我用这个功能扩展了本机yaml解析器,并在github上发布了它。

使用:

代码语言:javascript
运行
复制
type Config struct {
    Port     string   `yaml:"port"`
    RabbitMQ RabbitMQ `yaml:"rabbitmq"`
}

type RabbitMQ struct {
    Host     string `yaml:"host"`
    Port     string `yaml:"port"`
    Username string `yaml:"username"`
    Password string `yaml:"password"`
    Vhost    string `yaml:"vhost"`
}

func main() {
    var config Config
    file, err := ioutil.ReadFile("application.yaml")
    if err != nil {
        panic(err)
    }
    yaml.Unmarshal(file, &config)
    spew.Dump(config)
}

这就是application.yaml的样子:

代码语言:javascript
运行
复制
port: ${SERVER_PORT}
rabbitmq:
  host: ${RMQ_HOST}
  port: ${RMQ_PORT}
  username: ${RMQ_USERNAME}
  password: ${RMQ_PASSWORD}
  vhost: test

vhost值将像往常一样被解析,而被"${“和"}”包围的所有内容都将被环境变量替换。

票数 3
EN

Stack Overflow用户

发布于 2020-08-23 07:32:17

您可以显式地替换env变量,然后调用“un编排”方法。假设配置存储在"Config“变量中,下面的代码段应该可以工作。

代码语言:javascript
运行
复制
log.Println("Loading config...")
viper.SetConfigName("application")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
    fmt.Fprintf("Error reading config file %s\n", err)
}

for _, k := range viper.AllKeys() {
    v := viper.GetString(k)
    viper.Set(k, os.ExpandEnv(v))
}

if err := viper.Unmarshal(&Config); err != nil {
    fmt.Fprintf("Unable to decode into struct %s\n", err)
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52756532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档