如何在Golang中将密钥作为配置文件提取出来

huangapple go评论121阅读模式
英文:

How To Pull Secrets as Config File in Golang

问题

我是你的中文翻译助手,以下是翻译好的内容:

所以我对Go语言还不太熟悉,我想知道如何在不在脚本中暴露密码和URL的情况下动态导入它们。在Python中,我可以通过JSON有效载荷实现这一点,基本上是导入JSON,加载有效载荷,并在需要传递需要保密的规范时指定。

这是我的Go脚本:

  1. package main
  2. import (
  3. "io/ioutil"
  4. "net/http"
  5. "fmt"
  6. "gopkg.in/yaml.v2"
  7. )
  8. func main() {
  9. type Config struct {
  10. URL string `yaml:"url"`
  11. Username string `yaml:"username"`
  12. Token string `yaml:"token"`
  13. }
  14. func readConfig() (*Config, error) {
  15. config := &Config{}
  16. cfgFile, err := ioutil.ReadFile("config.yaml")
  17. if err != nil {
  18. return nil, err
  19. }
  20. err = yaml.Unmarshal(cfgFile, config)
  21. return config, err
  22. }
  23. req, err := http.NewRequest("GET", config.URL, nil)
  24. if err != nil {
  25. // 处理错误
  26. }
  27. req.SetBasicAuth(config.Username, config.Token)
  28. resp, err := http.DefaultClient.Do(req)
  29. if err != nil {
  30. // 处理错误
  31. }
  32. defer resp.Body.Close()
  33. body, _ := ioutil.ReadAll(resp.Body)
  34. fmt.Println(string(body))
  35. }

可以想象,我在加载密码时并没有太多运气,当我将以下内容更改为直接的令牌并在脚本中暴露我的密码时,它可以正常工作并在Jira中生成一个JSON有效载荷。

  1. config.URL
  2. config.Username
  3. config.Token

所以,如果我有一个YAML格式的配置文件,如下所示:

  1. config:
  2. URL: "<some_URL>"
  3. Username: "<some_username>"
  4. Token: "<some_token>"

如何将YAML文件加载到我的脚本中?
如何加载一个等效的JSON?

  1. {
  2. "config": {
  3. "URL": "<some_URL>",
  4. "Username": "<some_username>",
  5. "Token": "<some_token>"
  6. }
  7. }
英文:

So I am pretty new to Go and I am curious about how to import passwords and URLs dynamically without exposing them within my scripts. In python, I was able to implement this with a JSON payload and would basically import JSON, load the payload, and specify whenever I needed to pass a spec that needed secrecy.

Here is My Go Script:

  1. package main
  2. import (
  3. &quot;io/ioutil&quot;
  4. &quot;net/http&quot;
  5. &quot;fmt&quot;
  6. &quot;gopkg.in/yaml.v2&quot;
  7. )
  8. // curl -u &lt;username&gt;:&lt;password&gt; &lt;some_url&gt;
  9. func main() {
  10. type Config struct {
  11. URL string `yaml:&quot;url&quot;`
  12. Username string `yaml:&quot;username&quot;`
  13. Token string `yaml:&quot;token&quot;`
  14. }
  15. func readConfig() (*Config, error) {
  16. config := &amp;Config{}
  17. cfgFile, err := ioutil.ReadFile(&quot;config.yaml&quot;)
  18. if err != nil {
  19. return nil, err
  20. }
  21. err = yaml.Unmarshal(cfgFile, config)
  22. return config, err
  23. }
  24. req, err := http.NewRequest(&quot;GET&quot;, config.URL, nil)
  25. if err != nil {
  26. // handle err
  27. }
  28. req.SetBasicAuth(config.Username, config.Token)
  29. resp, err := http.DefaultClient.Do(req)
  30. if err != nil {
  31. // handle err
  32. }
  33. defer resp.Body.Close()
  34. body, _ := ioutil.ReadAll(resp.Body)
  35. fmt.Println(string(body))
  36. }

As one can imagine I am not having much luck in loading my passwords, when I change the following with direct tokens exposing my passwords in the scripts it functions and produces a JSON payload in Jira.

  1. config.URL
  2. config.Username
  3. config.Token

So if I have a config file in YAML as such:

  1. config:
  2. URL: &quot;&lt;some_URL&gt;&quot;
  3. Username: &quot;&lt;some_username&gt;&quot;
  4. Token: &quot;&lt;some_token&gt;&quot;

How can I load the YAML file into my script?
How can I load a JSON equivalent?

  1. {
  2. &quot;config&quot;: {
  3. &quot;URL&quot;: &quot;&lt;some_URL&gt;&quot;
  4. &quot;Username&quot;: &quot;&lt;some_username&gt;&quot;,
  5. &quot;Token&quot;: &quot;&lt;some_token&gt;&quot;
  6. }
  7. }

答案1

得分: 1

好的,下面是翻译好的内容:

好的,这里有几个问题。

  1. 除非使用变量声明语法,否则不能在另一个函数内部声明函数。
  1. func main() {
  2. // 这样写是可以的
  3. var myFunc = func() {
  4. // ...
  5. }
  6. // 这样写是不可以的
  7. func myFunc() {
  8. // ...
  9. }
  10. }
  1. Config 结构体告诉 YAML 解析器应该期望什么。你的结构体应该有与 YAML 文件相匹配的大小写和结构的 yaml 标签。
  1. // 它期望的是这样的
  2. url: "<some_URL>"
  3. username: "<some_username>"
  4. token: "<some_token>"
  5. // 你的 yaml 文件看起来是这样的
  6. config:
  7. Url: "<some_URL>"
  8. Username: "<some_username>"
  9. Token: "<some_token>"

以下代码对我来说是可行的:

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "net/http"
  6. "gopkg.in/yaml.v2"
  7. )
  8. type YAMLFile struct {
  9. Config Config `yaml:"config"`
  10. }
  11. type Config struct {
  12. URL string `yaml:"url"`
  13. Username string `yaml:"username"`
  14. Token string `yaml:"token"`
  15. }
  16. func main() {
  17. config, err := readConfig()
  18. if err != nil {
  19. panic(err)
  20. }
  21. fmt.Printf("%+v", config)
  22. req, err := http.NewRequest("GET", config.URL, nil)
  23. if err != nil {
  24. panic(err)
  25. }
  26. req.SetBasicAuth(config.Username, config.Token)
  27. resp, err := http.DefaultClient.Do(req)
  28. if err != nil {
  29. panic(err)
  30. }
  31. defer resp.Body.Close()
  32. body, err := ioutil.ReadAll(resp.Body)
  33. if err != nil {
  34. panic(err)
  35. }
  36. fmt.Println(string(body))
  37. }
  38. func readConfig() (*Config, error) {
  39. config := &YAMLFile{}
  40. cfgFile, err := ioutil.ReadFile("./config.yaml")
  41. if err != nil {
  42. return nil, err
  43. }
  44. err = yaml.Unmarshal(cfgFile, config)
  45. return &config.Config, err
  46. }

希望对你有帮助!

英文:

Okay so there are a couple problems here.

  1. You can't declare functions inside of another function unless you use variable declaration syntax
  1. func main() {
  2. // This
  3. var myFunc = func() {
  4. // ...
  5. }
  6. // Not this
  7. func myFunc() {
  8. // ...
  9. }
  10. }
  1. The Config struct is telling the YAML unmarshaler to expect. Your struct should have yaml tags that match the casing and structure of the yaml file.
  1. // It is expecting this
  2. url: &quot;&lt;some_URL&gt;&quot;
  3. username: &quot;&lt;some_username&gt;&quot;
  4. token: &quot;&lt;some_token&gt;&quot;
  5. // Your yaml looks like this
  6. config:
  7. Url: &quot;&lt;some_URL&gt;&quot;
  8. Username: &quot;&lt;some_username&gt;&quot;
  9. Token: &quot;&lt;some_token&gt;&quot;

The following works for me:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;io/ioutil&quot;
  5. &quot;net/http&quot;
  6. &quot;gopkg.in/yaml.v2&quot;
  7. )
  8. type YAMLFile struct {
  9. Config Config `yaml:&quot;config&quot;`
  10. }
  11. type Config struct {
  12. URL string `yaml:&quot;url&quot;`
  13. Username string `yaml:&quot;username&quot;`
  14. Token string `yaml:&quot;token&quot;`
  15. }
  16. func main() {
  17. config, err := readConfig()
  18. if err != nil {
  19. panic(err)
  20. }
  21. fmt.Printf(&quot;%+v&quot;, config)
  22. req, err := http.NewRequest(&quot;GET&quot;, config.URL, nil)
  23. if err != nil {
  24. panic(err)
  25. }
  26. req.SetBasicAuth(config.Username, config.Token)
  27. resp, err := http.DefaultClient.Do(req)
  28. if err != nil {
  29. panic(err)
  30. }
  31. defer resp.Body.Close()
  32. body, err := ioutil.ReadAll(resp.Body)
  33. if err != nil {
  34. panic(err)
  35. }
  36. fmt.Println(string(body))
  37. }
  38. func readConfig() (*Config, error) {
  39. config := &amp;YAMLFile{}
  40. cfgFile, err := ioutil.ReadFile(&quot;./config.yaml&quot;)
  41. if err != nil {
  42. return nil, err
  43. }
  44. err = yaml.Unmarshal(cfgFile, config)
  45. return &amp;config.Config, err
  46. }

答案2

得分: 1

巴雷特,

这是我一段时间前制作的一个配置库,用于解决这些问题:https://github.com/fulldump/goconfig。

使用方法很简单:

1)定义一个包含所有所需配置的结构体:

  1. type Config struct {
  2. URL string
  3. Username string
  4. Token string
  5. }

2)用该类型实例化一个变量,并用默认值填充它:

  1. c := &amp;Config{
  2. URL: &quot;http://default/url&quot;
  3. Username: &quot;default username&quot;
  4. }

3)使用以下代码自动从环境变量、命令行参数和/或JSON文件中填充配置变量:

  1. goconfig.Read(c)

例如,在你的情况下,你可以通过以下方式传递一个JSON文件:./my-binary -token &quot;my_secret_token&quot; -config my-config-file.json,从文件中读取所有配置键,但在启动前用参数覆盖令牌。

英文:

Barrett,

Here is a config library I made some time ago to solve that problems: https://github.com/fulldump/goconfig.

The use is simple:

  1. Define a struct with all the config you need:
  1. type Config struct {
  2. URL string
  3. Username string
  4. Token string
  5. }
  1. Instantiate a variable with that type and fill it with the default values:
  1. c := &amp;Config{
  2. URL: &quot;http://default/url&quot;
  3. Username: &quot;default username&quot;
  4. }
  1. Automatic fill your config variable with data from environment, command line arguments and/or json file with the folloging line:
  1. goconfig.Read(c)

For example, in your case, you can pass a JSON file as follows ./my-binary -token &quot;my_secret_token&quot; -config my-config-file.json to read all config keys from a file but overwrite the token just before launching with an argument.

huangapple
  • 本文由 发表于 2021年7月7日 22:14:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/68287726.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定