...
1
16
17 package v1beta1
18
19 import (
20 "bytes"
21 "io"
22 "strings"
23
24 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25 "k8s.io/apimachinery/pkg/runtime"
26 "k8s.io/apimachinery/pkg/runtime/schema"
27 "k8s.io/apimachinery/pkg/util/yaml"
28 )
29
30
31
32 type Snapshot struct {
33
34
35 Checksum string `json:"checksum"`
36
37
38
39 Entries []SnapshotEntry `json:"entries"`
40 }
41
42
43
44 type SnapshotEntry struct {
45
46
47 Namespace string `json:"namespace"`
48
49
50
51 Kinds map[string]string `json:"kinds"`
52 }
53
54 func NewSnapshot(manifests []byte, checksum string) (*Snapshot, error) {
55 snapshot := Snapshot{
56 Checksum: checksum,
57 Entries: []SnapshotEntry{},
58 }
59
60 reader := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(manifests), 2048)
61 for {
62 var obj unstructured.Unstructured
63 err := reader.Decode(&obj)
64 if err == io.EOF {
65 break
66 } else if err != nil {
67 return nil, err
68 }
69 if obj.IsList() {
70 err := obj.EachListItem(func(item runtime.Object) error {
71 snapshot.addEntry(item.(*unstructured.Unstructured))
72 return nil
73 })
74 if err != nil {
75 return nil, err
76 }
77 } else {
78 snapshot.addEntry(&obj)
79 }
80 }
81
82 return &snapshot, nil
83 }
84
85 func (s *Snapshot) addEntry(item *unstructured.Unstructured) {
86 found := false
87 for _, tracker := range s.Entries {
88 if tracker.Namespace == item.GetNamespace() {
89 tracker.Kinds[item.GroupVersionKind().String()] = item.GetKind()
90 found = true
91 break
92 }
93 }
94 if !found {
95 s.Entries = append(s.Entries, SnapshotEntry{
96 Namespace: item.GetNamespace(),
97 Kinds: map[string]string{
98 item.GroupVersionKind().String(): item.GetKind(),
99 },
100 })
101 }
102 }
103
104 func (s *Snapshot) NonNamespacedKinds() []schema.GroupVersionKind {
105 kinds := make([]schema.GroupVersionKind, 0)
106
107 for _, tracker := range s.Entries {
108 if tracker.Namespace == "" {
109 for gvk, kind := range tracker.Kinds {
110 if strings.Contains(gvk, ",") {
111 gv, err := schema.ParseGroupVersion(strings.Split(gvk, ",")[0])
112 if err == nil {
113 kinds = append(kinds, gv.WithKind(kind))
114 }
115 }
116 }
117 }
118 }
119 return kinds
120 }
121
122 func (s *Snapshot) NamespacedKinds() map[string][]schema.GroupVersionKind {
123 nsk := make(map[string][]schema.GroupVersionKind)
124 for _, tracker := range s.Entries {
125 if tracker.Namespace != "" {
126 var kinds []schema.GroupVersionKind
127 for gvk, kind := range tracker.Kinds {
128 if strings.Contains(gvk, ",") {
129 gv, err := schema.ParseGroupVersion(strings.Split(gvk, ",")[0])
130 if err == nil {
131 kinds = append(kinds, gv.WithKind(kind))
132 }
133 }
134 }
135 nsk[tracker.Namespace] = kinds
136 }
137 }
138 return nsk
139 }
140
View as plain text