Skip to content

Tools to deal with YAML files and embedded data within k8s manifests

License

Notifications You must be signed in to change notification settings

rkosegi/yaml-toolkit

Repository files navigation

YAML toolkit

codecov Go Report Card Quality Gate Status Technical Debt Vulnerabilities Maintainability Rating Security Rating Go Reference Apache 2.0 License

Go library to deal with (not only) YAML documents.

Usage

Loading configuration file with defaults

given configuration file

config.yaml

---
listen_address: 0.0.0.0:8080
read_timeout: 15s
package main

import (
	"time"

	"github.com/rkosegi/yaml-toolkit/dom"
	"github.com/rkosegi/yaml-toolkit/fluent"
)

type Config struct {
	Address     string        `yaml:"listen_address"`
	ReadTimeout time.Duration `yaml:"read_timeout"`
}

var defConfig = &Config{
	Address: "0.0.0.0:8081",
}

func main() {
	cfg := fluent.NewConfigHelper[Config]().
		Add(defConfig).         // add defaults
		Load("config.yaml").    // override with values loaded from YAML document
		Result()                // get merged results

	// ... use cfg
}

Opening embedded YAML

example.yaml

---
kind: ConfigMap
metadata:
  name: cm1
  namespace: default
apiVersion: v1
data:
  application.yaml: |
    xyz: 456
    abc:
      def:
        leaf1: 123
        leaf2: Hello

code

package main

import (
    ydom "github.com/rkosegi/yaml-toolkit/dom"
    yk8s "github.com/rkosegi/yaml-toolkit/k8s"
)

func main() {
	d, err := yk8s.YamlDoc("example.yaml", "application.yaml")
	if err != nil {
		panic(err)
	}
	print (d.Document().Child("xyz").(ydom.Leaf).Value()) // 456
	d.Document().AddValue("another-key", ydom.LeafNode("789")) // add new child node
	err = d.Save()
	if err != nil {
		panic(err)
	}
}

Compute difference between 2 documents

LeftRight
left.yamlright.yaml
---
root:
  sub1:
    leaf1: abc
    leaf2: 123
  list:
    - 1
    - 2
---
root:
  sub1:
    leaf1: def
    leaf3: 789
  list:
    - 3
package main

import (
	"fmt"
	yta "github.com/rkosegi/yaml-toolkit/analytics"
	ytc "github.com/rkosegi/yaml-toolkit/common"
	ydiff "github.com/rkosegi/yaml-toolkit/diff"
)

func main() {
	dp := ytc.DefaultFileDecoderProvider(".yaml")
	ds := yta.NewDocumentSet()
	err := ds.AddDocumentFromFile("left.yaml", dp, yta.WithTags("left"))
	if err != nil {
		panic(err)
	}
	err = ds.AddDocumentFromFile("right.yaml", dp, yta.WithTags("right"))
	if err != nil {
		panic(err)
	}
	changes := ydiff.Diff(
		ds.TaggedSubset("right").Merged(),
		ds.TaggedSubset("left").Merged(),
	)
	fmt.Printf("All changes: %d\n", len(*changes))
	for _, change := range *changes {
		fmt.Printf("%s: %s => %v\n", change.Type, change.Path, change.Value)
	}
}

output:

All changes: 5
Delete: root.list => <nil>
Add: root.list[0] => 3
Change: root.sub1.leaf1 => abc
Delete: root.sub1.leaf2 => <nil>
Add: root.sub1.leaf3 => 789