добавление в файл 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
и маршалинг его.