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

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

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程序,但无法按照上述格式进行追加,我不知道我漏掉了什么。

package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"gopkg.in/yaml.v2"
)

type AutoGenerated struct {
	CustomRules CustomRules `yaml:"customRules"`
}

type CustomRulesYaml struct {
	Rule      string `yaml:"rule"`
	Append    bool   `yaml:"append"`
	Condition string `yaml:"condition"`
	Source    string `yaml:"source"`
}

type CustomRules struct {
	CustomRulesYaml []CustomRulesYaml `yaml:"custom-rules.yaml"`
}

func main() {
	// yfile, err := ioutil.ReadFile("/home/revaa/falco/custom_rules.yaml")
	// if err != nil {
	// 	log.Fatal(err)
	// }

	c1 := CustomRulesYaml{"K8s serviceaccount created", false, "(never_true)", "k8s-audit"}
	c2 := CustomRulesYaml{"k8s service created", false, "never_true", "k8s-audit"}
	c := []CustomRulesYaml{c1, c2}
	c3 := CustomRules{c}
	data := AutoGenerated{c3}
	check, err := yaml.Marshal(&data)

	if err != nil {
		log.Fatal(err)
	}

	err2 := ioutil.WriteFile("/home/revaa/falco/custom_rules.yaml", check, 0)

	if err2 != nil {
		log.Fatal(err2)
	}

	fmt.Println("data written")
}

这是我的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:

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

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

package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"gopkg.in/yaml.v2"
)

type AutoGenerated struct {
	CustomRules CustomRules `yaml:"customRules"`
}
type CustomRulesYaml struct {
	Rule      string `yaml:"rule"`
	Append    bool   `yaml:"append"`
	Condition string `yaml:"condition"`
	Source    string `yaml:"source"`
}
type CustomRules struct {
	CustomRulesYaml []CustomRulesYaml `yaml:"custom-rules.yaml"`
}

func main() {
	// yfile, err := ioutil.ReadFile("/home/revaa/falco/custom_rules.yaml")
	// if err != nil {
	// 	log.Fatal(err)
	// }
	c1 := CustomRulesYaml{"K8s serviceaccount created", false, "(never_true)", "k8s-audit"}
	c2 := CustomRulesYaml{"k8s service created", false, "never_true", "k8s-audit"}
	c := []CustomRulesYaml{c1, c2}
	c3 := CustomRules{c}
	data := AutoGenerated{c3}
	check, err := yaml.Marshal(&data)

	if err != nil {

		log.Fatal(err)
	}

	err2 := ioutil.WriteFile("/home/revaa/falco/custom_rules.yaml", check, 0)

	if err2 != nil {

		log.Fatal(err2)
	}

	fmt.Println("data written")

}

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.

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

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

答案1

得分: 1

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

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

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

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

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

"- 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上的一个变体,它的输出是:

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  

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

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

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:

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

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  

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:

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:

确定