0

我编写了一个 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")

}

这是我的代码,在运行程序时,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 文件?

4

1 回答 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,如果读取,它将产生一个包含 2 个元素的列表(一个切片,在 Go 中),每个元素都是一个字典(通常对应于一个地图或 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产生一个。但是您的示例输入以换行符结尾,这就是为什么您的示例输入|-不只是|-意味着“不包括该换行符”。

要从现有代码中获取,您必须去掉换行符,例如,添加:

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

在构建字符串c3并对其进行编组之前。

于 2021-11-11T16:14:48.800 回答