добавление в файл YAML с помощью 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 в нужном формате?

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произвел один. Но ваш пример ввода не заканчивается новой строкой, поэтому ваш пример ввода имеет |-вместо того, чтобы просто |: -означает «не включать эту новую строку».

Чтобы получить это из существующего кода, вам придется убрать новую строку, например, добавить:

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

перед созданием строки в c3и маршалинг его.

Другие вопросы по тегам