如何在yaml包的Go和API v3中生成配置文件时对注释进行编码



我正在尝试在封送结构以配置YAML时使用YAML v3。

注:更新:我最初的例子有点过于简化了。我的实际要求如下:

例如,我有:

package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v3"
)
type Ec2 struct {
Class string `yaml:"class"`
Ip    string `yaml:"ip"`
}
type Vpc struct {
Subnet string `yaml:"subnet"`
Igw    interface{} `yaml:"igw"`
}
type Config struct {
Ec2 Ec2 `yaml:"ec2"`
Vpc Vpc `yaml:"vpc"`
}
func main() {
c := Config{}
bytes, err := yaml.Marshal(c)
if err != nil {
fmt.Println(err)
}
ioutil.WriteFile("config.yaml", bytes, 0644)
}

pwd中创建一个名为config.yaml的文件,如:

ec2:
class: ""
ip: ""
vpc:
subnet: ""
igw: null

但我正在尝试生成配置文件(在本例中为config.yaml(,如:


ec2:
# This section is for EC2
class: ""
ip: ""
vpc:
# This section is for VPC
subnet: ""
igw: null

使用V.3可以实现这一点吗?

有两种方法可以利用yaml.v3及其注释功能:

  • 手工构建yaml.Node树(繁琐的维护;精确的值更新(
  • 将模板解析为yaml.Node树(易于维护;难以更新值(

方法1:

手工制作YAML节点树:

config = &yaml.Node{
Kind: yaml.DocumentNode,
Content: []*yaml.Node{
&yaml.Node{
Kind: yaml.MappingNode,
Content: []*yaml.Node{
&yaml.Node{
Kind:        yaml.ScalarNode,
Value:       "ec2",
HeadComment: "# This section is for EC2",
},
&yaml.Node{
Kind:  yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
Value: "", // <- field value goes here
},
&yaml.Node{
Kind:        yaml.ScalarNode,
Value:       "vpc",
HeadComment: "# This section is for VPC",
},
&yaml.Node{
Kind:  yaml.ScalarNode,
Style: yaml.DoubleQuotedStyle,
Value: "", // <- field value goes here
},
},
},
},
}

工作游乐场示例:https://play.golang.org/p/Z6iw29rHZXk

输出:

# This section is for EC2
ec2: ""
# This section is for VPC
vpc: ""

方法2:

阅读YAML模式的模板,例如

var yamlSchema = []byte(`
# EC2 header-comment
ec2: ""
# This section is for VPC
vpc: ""
`)

然后在运行时将其解析为yaml.Node树,如下所示:

var c yaml.Node
err := yaml.Unmarshal(yamlSchema, &c)

但是,作为一个yaml.Node树——它嵌套了yaml.Node的片段——你需要以编程的方式找到你的字段值,所以当你为写作封送配置时,这些值会与正确的字段配对。

例如,这个今天可能有效:

c.Content[0].Content[1].Value = ec2Value // dangerous

但不是明天,当模式改变时。

遍历映射并查找字段值ec2,然后将其值放置在相邻节点中是正确的方法。

Playground示例显示了如何将页眉/页脚/内联注释添加到架构中,例如

# This section is for EC2
ec2: ""          # <-- place user input here
# footer EC2
# This section is for VPC
vpc: ""

最新更新