-1

所以我对 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>"
  }
}
4

2 回答 2

1

好的,这里有几个问题。

  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
}
于 2021-07-07T14:44:58.380 回答
1

巴雷特,

这是我前段时间为解决这些问题而制作的配置库: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. 使用来自环境、命令行参数和/或 json 文件的数据自动填充您的配置变量,并使用以下行:
goconfig.Read(c)

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

于 2021-07-07T23:33:27.243 回答