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

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

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"
)

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 {
        // 处理错误
    }

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

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        // 处理错误
    }

    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>"
  }
}
英文:

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:

package main

import (
    &quot;io/ioutil&quot;
    &quot;net/http&quot;
    &quot;fmt&quot;

    &quot;gopkg.in/yaml.v2&quot;
)
// curl -u &lt;username&gt;:&lt;password&gt; &lt;some_url&gt;

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

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

    req, err := http.NewRequest(&quot;GET&quot;, 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))
}

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.

config.URL
config.Username
config.Token

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

config:
    URL: &quot;&lt;some_URL&gt;&quot;
    Username: &quot;&lt;some_username&gt;&quot;
    Token: &quot;&lt;some_token&gt;&quot;

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

{
  &quot;config&quot;: {
    &quot;URL&quot;: &quot;&lt;some_URL&gt;&quot;
    &quot;Username&quot;: &quot;&lt;some_username&gt;&quot;,
    &quot;Token&quot;: &quot;&lt;some_token&gt;&quot;
  }
}

答案1

得分: 1

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

好的,这里有几个问题。

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

// 你的 yaml 文件看起来是这样的
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
}

希望对你有帮助!

英文:

Okay so there are a couple problems here.

  1. You can't declare functions inside of another function unless you use variable declaration syntax
func main() {
	// This
	var myFunc = func() {
		// ...
	}
	// Not this
	func myFunc() {
		// ...
	}
}
  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.
// It is expecting this
url: &quot;&lt;some_URL&gt;&quot;
username: &quot;&lt;some_username&gt;&quot;
token: &quot;&lt;some_token&gt;&quot;

// Your yaml looks like this
config:
  Url: &quot;&lt;some_URL&gt;&quot;
  Username: &quot;&lt;some_username&gt;&quot;
  Token: &quot;&lt;some_token&gt;&quot;

The following works for me:

package main

import (
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;net/http&quot;

	&quot;gopkg.in/yaml.v2&quot;
)

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

func main() {
	config, err := readConfig()
	if err != nil {
		panic(err)
	}
	fmt.Printf(&quot;%+v&quot;, config)
	req, err := http.NewRequest(&quot;GET&quot;, 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 := &amp;YAMLFile{}
	cfgFile, err := ioutil.ReadFile(&quot;./config.yaml&quot;)
	if err != nil {
		return nil, err
	}
	err = yaml.Unmarshal(cfgFile, config)
	return &amp;config.Config, err
}

答案2

得分: 1

巴雷特,

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

使用方法很简单:

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

type Config struct {
    URL      string
    Username string
    Token    string
}

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

c := &amp;Config{
    URL:     &quot;http://default/url&quot;
    Username: &quot;default username&quot;
}

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

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:
type Config struct {
    URL      string
    Username string
    Token    string
}
  1. Instantiate a variable with that type and fill it with the default values:
c := &amp;Config{
    URL:     &quot;http://default/url&quot;
    Username: &quot;default username&quot;
}
  1. Automatic fill your config variable with data from environment, command line arguments and/or json file with the folloging line:
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:

确定