如何在 Golang 中将秘密提取为配置文件

How To Pull Secrets as Config File in Golang

所以我是 Go 的新手,我很好奇如何动态导入密码和 URL 而不会在我的脚本中暴露它们。在 python 中,我能够使用 JSON 有效载荷来实现它,并且基本上会导入 JSON,加载有效载荷,并在我需要传递需要保密的规范时指定。

这是我的 Go 脚本:

package main

import (
    "io/ioutil"
    "net/http"
    "fmt"

    "gopkg.in/yaml.v2"
)
// curl -u <username>:<password> <some_url>

func main() {
    type Config struct {
    URL      string `yaml:"url"`
    Username string `yaml:"username"`
    Token    string `yaml:"token"`
    }

    func readConfig() (*Config, error) {
    config := &Config{}
    cfgFile, err := ioutil.ReadFile("config.yaml")
    if err != nil {
        return nil, err
    }
    err = yaml.Unmarshal(cfgFile, config)
    return config, err
    }

    req, err := http.NewRequest("GET", config.URL, nil)
    if err != nil {
        // handle err
    }

    req.SetBasicAuth(config.Username, config.Token)

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        // handle err
    }

    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

正如人们想象的那样,我在加载密码方面运气不佳,当我使用直接令牌更改以下内容时,在脚本中公开我的密码时,它会运行并在 Jira 中生成 JSON 有效负载。

config.URL
config.Username
config.Token

因此,如果我在 YAML 中有这样的配置文件:

config:
    URL: "<some_URL>"
    Username: "<some_username>"
    Token: "<some_token>"

如何将 YAML 文件加载到我的脚本中? 如何加载 JSON 等价物?

{
  "config": {
    "URL": "<some_URL>"
    "Username": "<some_username>",
    "Token": "<some_token>"
  }
}

好的,这里有几个问题。

  1. 除非使用变量声明语法,否则不能在另一个函数内部声明函数
func main() {
    // This
    var myFunc = func() {
        // ...
    }
    // Not this
    func myFunc() {
        // ...
    }
}
  1. Config 结构告诉 YAML 解组器期待。您的结构应该具有与 yaml 文件的大小写和结构相匹配的 yaml 标签。
// It is expecting this
url: "<some_URL>"
username: "<some_username>"
token: "<some_token>"

// Your yaml looks like this
config:
  Url: "<some_URL>"
  Username: "<some_username>"
  Token: "<some_token>"

以下对我有效:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"

    "gopkg.in/yaml.v2"
)

type YAMLFile struct {
    Config Config `yaml:"config"`
}
type Config struct {
    URL      string `yaml:"url"`
    Username string `yaml:"username"`
    Token    string `yaml:"token"`
}

func main() {
    config, err := readConfig()
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v", config)
    req, err := http.NewRequest("GET", config.URL, nil)
    if err != nil {
        panic(err)
    }
    req.SetBasicAuth(config.Username, config.Token)
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

func readConfig() (*Config, error) {
    config := &YAMLFile{}
    cfgFile, err := ioutil.ReadFile("./config.yaml")
    if err != nil {
        return nil, err
    }
    err = yaml.Unmarshal(cfgFile, config)
    return &config.Config, err
}

巴雷特,

这是我前段时间为解决该问题而制作的配置库:https://github.com/fulldump/goconfig

使用简单:

  1. 使用您需要的所有配置定义结构:
type Config struct {
    URL      string
    Username string
    Token    string
}
  1. 用该类型实例化一个变量并用默认值填充它:
c := &Config{
    URL:     "http://default/url"
    Username: "default username"
}
  1. 使用来自环境、命令行参数 and/or json 文件的数据自动填充您的配置变量,其中包含以下行:
goconfig.Read(c)

例如,在您的情况下,您可以按如下方式传递 JSON 文件 ./my-binary -token "my_secret_token" -config my-config-file.json 以从文件中读取所有配置键,但在使用参数启动之前覆盖令牌。