转到yaml如何向yaml文件添加新条目



我需要从结构值config.Sif["snk_prod"]向yaml文件添加条目(我需要在运行时填充它(并尝试以下操作,我尝试了以下操作,但在填充结构时出错了,知道吗?

package main
import "gopkg.in/yaml.v3"
const document = `
spec:
mec:
customConfig:
sif:
prom_exporter:
type: prometheus_exporter
snk_dev:   
type: sk_hc_logs
inputs:
- tesslt
ep: ${NT}
dken: ${SN}
`
type YamlObject map[string]any
type CustomConfig struct {
Sif map[string]interface{} `yaml:"sif,omitempty"`
}
type ecfg struct {
Type   string   `yaml:"type,omitempty"`
Inputs []string `yaml:"inputs,omitempty"`
Ep     string   `yaml:"ep,omitempty"`
Dken   string   `yaml:"dken,omitempty"`
}
func main() {
t := CustomConfig{}
config := &t
// -------I need to add it as struct values as I got the values on runtime dynamically  
config.Sif["snk_prod"] = ecfg{
Type:   "sk_hc_ls",
Inputs: []string{"tesslt"},
Ep:     "${NT}",
}
yamlBytes, err := yaml.Marshal(t)
doc := make(YamlObject)
if err := yaml.Unmarshal([]byte(document), &doc); err != nil {
panic(err)
}
addon := make(YamlObject)
if err := yaml.Unmarshal(yamlBytes, &addon); err != nil {
panic(err)
}
node := findChild(doc, "spec", "mec", "customConfig", "sif")
if node == nil {
panic("Must not happen")
}
for key, val := range addon {
(*node)[key] = val
}
outDoc, err := yaml.Marshal(doc)
if err != nil {
panic(err)
}
println(string(outDoc))
}
func findChild(obj YamlObject, path ...string) *YamlObject {
if len(path) == 0 {
return &obj
}
key := path[0]
child, ok := obj[key]
if !ok {
return nil
}
obj, ok = child.(YamlObject)
if !ok {
return nil
}
return findChild(obj, path[1:]...)
}

https://go.dev/play/p/6CHsOJPXqpw

经过搜索,我找到了这个答案https://stackoverflow.com/a/74089724/6340176这与我的非常相似,变化是我需要将其添加为结构值

最后,我需要在sif下添加新条目

最后输出应如下所示

spec:
mec:
customConfig:
sif:
prom_exporter:
type: prometheus_exporter
snk_dev:   
type: sk_hc_logs
inputs:
- tesslt
ep: ${NT}
dken: ${SN}
snk_prod:   
type: sk_hc_ls
inputs:
- tesslt
ep: ${NT}

替换yamlBytes的创建,如下所示:

t := make(map[string]interface{})
t["snk_prod"] = ecfg{
Type:   "sk_hc_ls",
Inputs: []string{"tesslt"},
Ep:     "${NT}",
}
yamlBytes, err := yaml.Marshal(t)

然后你会得到预期的结果。

BTW:由于您正试图将值插入到未初始化的映射中(config.Sifnil(,因此会触发死机。例如,在分配值之前,您可以简单地使用以下代码行创建一个空映射:

config.Sif = make(map[string]interface{})

但在代码中会有一个额外的不需要的sif节点,例如这样的东西:

...
sif:
prom_exporter:
type: prometheus_exporter
sif:
snk_prod:
...

因此,应该生成要动态添加的yaml片段,如开头所示。

最新更新