Skip to content

Instantly share code, notes, and snippets.

@zoetrope
Created April 6, 2020 05:10
Show Gist options
  • Save zoetrope/4edfcb7c9611d7b62dcb353ddce9502b to your computer and use it in GitHub Desktop.
Save zoetrope/4edfcb7c9611d7b62dcb353ddce9502b to your computer and use it in GitHub Desktop.
diff for Kubernetes Resources
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"github.com/Cside/jsondiff"
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/yaml"
)
func readYaml(filename string) (map[string][]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
result := make(map[string][]byte)
reader := k8syaml.NewYAMLReader(bufio.NewReader(f))
for {
data, err := reader.Read()
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
var res struct {
Kind string `json:"kind"`
Metadata struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
} `json:"metadata"`
}
err = yaml.Unmarshal(data, &res)
if err != nil {
return nil, err
}
result[fmt.Sprintf("%s:%s:%s", res.Kind, res.Metadata.Namespace, res.Metadata.Name)] = data
}
return result, nil
}
func printDiff(data1, data2 map[string][]byte) error {
for k, v1 := range data1 {
if v2, ok := data2[k]; ok {
j1, err := yaml.YAMLToJSON(v1)
if err != nil {
return err
}
j2, err := yaml.YAMLToJSON(v2)
if err != nil {
return err
}
if diff := jsondiff.Diff(j1, j2); diff != "" {
fmt.Printf("diff: %s\n%s\n", k, diff)
}
delete(data1, k)
delete(data2, k)
}
}
for k, v1 := range data1 {
j1, err := yaml.YAMLToJSON(v1)
if err != nil {
return err
}
if diff := jsondiff.Diff(j1, []byte("{}")); diff != "" {
fmt.Printf("diff: %s\n%s\n", k, diff)
}
}
for k, v2 := range data2 {
j2, err := yaml.YAMLToJSON(v2)
if err != nil {
return err
}
if diff := jsondiff.Diff([]byte("{}"), j2); diff != "" {
fmt.Printf("diff: %s\n%s\n", k, diff)
}
}
return nil
}
func main() {
if len(os.Args) != 3 {
fmt.Println("usage: kdiff src dst")
os.Exit(1)
}
data1, err := readYaml(os.Args[1])
if err != nil {
log.Fatal(err)
os.Exit(1)
}
data2, err := readYaml(os.Args[2])
if err != nil {
log.Fatal(err)
os.Exit(1)
}
err = printDiff(data1, data2)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment