使用Go语言向YAML文件追加内容。

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

appending to YAML file using go lang

问题

我正在编写一个使用Golang编写的程序,将规则追加到文件中,如下所示:

所需格式:

customRules:
custom-rules.yaml: |-
- rule: Pod Created in Kube Namespace
append: true
condition: and (k8s_audit_never_true)
source: k8s_audit
- rule: Create files below dev
append: true
condition: and (never_true)
source: syscall

我编写了一个Go程序,但无法按照上述格式进行追加,我不知道我漏掉了什么。

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "gopkg.in/yaml.v2"
  7. )
  8. type AutoGenerated struct {
  9. CustomRules CustomRules `yaml:"customRules"`
  10. }
  11. type CustomRulesYaml struct {
  12. Rule string `yaml:"rule"`
  13. Append bool `yaml:"append"`
  14. Condition string `yaml:"condition"`
  15. Source string `yaml:"source"`
  16. }
  17. type CustomRules struct {
  18. CustomRulesYaml []CustomRulesYaml `yaml:"custom-rules.yaml"`
  19. }
  20. func main() {
  21. // yfile, err := ioutil.ReadFile("/home/revaa/falco/custom_rules.yaml")
  22. // if err != nil {
  23. // log.Fatal(err)
  24. // }
  25. c1 := CustomRulesYaml{"K8s serviceaccount created", false, "(never_true)", "k8s-audit"}
  26. c2 := CustomRulesYaml{"k8s service created", false, "never_true", "k8s-audit"}
  27. c := []CustomRulesYaml{c1, c2}
  28. c3 := CustomRules{c}
  29. data := AutoGenerated{c3}
  30. check, err := yaml.Marshal(&data)
  31. if err != nil {
  32. log.Fatal(err)
  33. }
  34. err2 := ioutil.WriteFile("/home/revaa/falco/custom_rules.yaml", check, 0)
  35. if err2 != nil {
  36. log.Fatal(err2)
  37. }
  38. fmt.Println("data written")
  39. }

这是我的Go代码,运行程序后,YAML文件没有按照所需格式进行追加。而是以以下方式追加了值:

customRules:
custom-rules.yaml:

  • rule: K8s serviceaccount created
    append: false
    condition: (never_true)
    source: k8s-audit
  • rule: k8s service created
    append: false
    condition: never_true
    source: k8s-audit

为什么我没有得到所需格式的YAML文件?

英文:

I writing a golang program which append rule to the file as mentioned below
Required format:

  1. customRules:
  2. custom-rules.yaml: |-
  3. - rule: Pod Created in Kube Namespace
  4. append: true
  5. condition: and (k8s_audit_never_true)
  6. source: k8s_audit
  7. - rule: Create files below dev
  8. append: true
  9. condition: and (never_true)
  10. source: syscall

I wrote a go program which failing to be in the above format I can't get what Iam missing.

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "gopkg.in/yaml.v2"
  7. )
  8. type AutoGenerated struct {
  9. CustomRules CustomRules `yaml:"customRules"`
  10. }
  11. type CustomRulesYaml struct {
  12. Rule string `yaml:"rule"`
  13. Append bool `yaml:"append"`
  14. Condition string `yaml:"condition"`
  15. Source string `yaml:"source"`
  16. }
  17. type CustomRules struct {
  18. CustomRulesYaml []CustomRulesYaml `yaml:"custom-rules.yaml"`
  19. }
  20. func main() {
  21. // yfile, err := ioutil.ReadFile("/home/revaa/falco/custom_rules.yaml")
  22. // if err != nil {
  23. // log.Fatal(err)
  24. // }
  25. c1 := CustomRulesYaml{"K8s serviceaccount created", false, "(never_true)", "k8s-audit"}
  26. c2 := CustomRulesYaml{"k8s service created", false, "never_true", "k8s-audit"}
  27. c := []CustomRulesYaml{c1, c2}
  28. c3 := CustomRules{c}
  29. data := AutoGenerated{c3}
  30. check, err := yaml.Marshal(&data)
  31. if err != nil {
  32. log.Fatal(err)
  33. }
  34. err2 := ioutil.WriteFile("/home/revaa/falco/custom_rules.yaml", check, 0)
  35. if err2 != nil {
  36. log.Fatal(err2)
  37. }
  38. fmt.Println("data written")
  39. }

Here is my go code, on running the program the YAML is not getting appended in the above format. The values are appended as below instead.

  1. customRules:
  2. custom-rules.yaml:
  3. - rule: K8s serviceaccount created
  4. append: false
  5. condition: (never_true)
  6. source: k8s-audit
  7. - rule: k8s service created
  8. append: false
  9. condition: never_true
  10. source: k8s-audit

Why Iam not getting the YAML file in the required format?

答案1

得分: 1

您提供的输入格式表示以下YAML结构:

  • 有一个包含一个键值对的字典。
    • 键是customRules
    • 值是一个字典。

上述值中存储的字典有一个条目:

  • 键是custom-rules.yaml
  • 值是一个字符串。

上述值中存储的字符串是:

  1. "- rule: Pod Created in Kube Namespace\n append: true\n condition: and (k8s_audit_never_true)\n source: k8s_audit\n- rule: Create files below dev\n append: true\n condition: and (never_true)\n source: syscall"

也就是说,这不是一个列表类型。它是一个单独的字符串。

事实上,这个单独的字符串有效的(尽管有点可疑)YAML,如果读取,它将生成一个列表(在Go中是一个切片),其中包含2个元素,每个元素都是一个字典(通常对应于Go中的映射或结构类型)。

如果你确实需要这个,那么你的代码就接近正确了。你不需要将[]CustomRulesYaml包装在一个类型中,而是需要进行两次编组。这是你的代码在Go Playground上的一个变体,它的输出是:

  1. custom-rules.yaml: |
  2. - rule: K8s serviceaccount created
  3. append: false
  4. condition: (never_true)
  5. source: k8s-audit
  6. - rule: k8s service created
  7. append: false
  8. condition: never_true
  9. source: k8s-audit

现在,请注意,此输出中有一个带有管道符号|但没有后缀连字符-。这是因为编组的字符串string(asBytes)以换行符结尾。它可能应该以换行符结尾,这就是为什么yaml.Marshal会生成一个换行符。但是您的示例输入没有以换行符结尾,这就是为什么您的示例输入中有|-而不仅仅是|的原因:-表示“不包括该换行符”。

要从您现有的代码中获得那个,您需要去掉换行符,例如,在构建c3中的字符串之前添加:

  1. asBytes = asBytes[0:len(asBytes)-1] // 删除尾随换行符

然后进行编组。

英文:

Your required input format represents the following YAML structure:

  • There is a dictionary with one key-value pair.
    • The key is customRules.
    • The value is a dictionary.

The dictionary stored in the value above has one entry:

  • The key is custom-rules.yaml.
  • The value is a string.

The string stored in the value above is:

  1. "- rule: Pod Created in Kube Namespace\n append: true\n condition: and (k8s_audit_never_true)\n source: k8s_audit\n- rule: Create files below dev\n append: true\n condition: and (never_true)\n source: syscall"

That is, this is not a list type. It's a single string.

Now, the fact is that this single string is valid—albeit slightly dodgy—YAML, and if read, it will produce a list (a slice, in Go) of 2 elements, each of which is a dictionary (generally corresponding to a map or struct type in Go).

Your code is close to right, then, if you really do need this. Instead of wrapping the []CustomRulesYaml in a type, you need to marshal twice. Here's a variant of your code on the Go Playground whose output is:

  1. custom-rules.yaml: |
  2. - rule: K8s serviceaccount created
  3. append: false
  4. condition: (never_true)
  5. source: k8s-audit
  6. - rule: k8s service created
  7. append: false
  8. condition: never_true
  9. source: k8s-audit

Now, note that this output has a pipe symbol | without a suffix hyphen -. That's because the marshaled string, string(asBytes), ends with a newline. It probably should end with a newline, which is why yaml.Marshal produced one. But your sample input doesn't end with a newline, which is why your sample input has |- instead of just |: the - means "don't include that newline".

To get that from your existing code, you will have to strip off the newline, e.g., add:

  1. asBytes = asBytes[0:len(asBytes)-1] // delete trailing newline

before building the string in c3 and marshaling it.

huangapple
  • 本文由 发表于 2021年11月11日 12:50:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/69923341.html
匿名

发表评论

匿名网友

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

确定