-
Notifications
You must be signed in to change notification settings - Fork 216
/
jsonpatch.go
94 lines (84 loc) · 2.35 KB
/
jsonpatch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package normalizers
import (
jsonpatch "github.com/evanphx/json-patch"
"github.com/sirupsen/logrus"
"github.com/rancher/wrangler/v2/pkg/objectset"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type JSONPatch []byte
type JSONPatchNormalizer struct {
patch map[schema.GroupVersionKind]map[objectset.ObjectKey][]JSONPatch
}
func (j *JSONPatchNormalizer) Add(gvk schema.GroupVersionKind, key objectset.ObjectKey, patch JSONPatch) {
if j.patch == nil {
j.patch = map[schema.GroupVersionKind]map[objectset.ObjectKey][]JSONPatch{}
}
if _, ok := j.patch[gvk]; !ok {
j.patch[gvk] = map[objectset.ObjectKey][]JSONPatch{}
}
if _, ok := j.patch[gvk][key]; !ok {
j.patch[gvk][key] = []JSONPatch{}
}
j.patch[gvk][key] = append(j.patch[gvk][key], patch)
}
func (j JSONPatchNormalizer) Normalize(un *unstructured.Unstructured) error {
if un == nil {
return nil
}
gvk := un.GroupVersionKind()
metaObj, err := meta.Accessor(un)
if err != nil {
logrus.Errorf("Failed to normalize obj with json patch, error: %v", err)
return nil
}
key := objectset.ObjectKey{
Namespace: metaObj.GetNamespace(),
Name: metaObj.GetName(),
}
if !j.hasPatches(gvk, key) {
// If there are no patches, skip marshalling and unmarshalling
return nil
}
jsondata, err := un.MarshalJSON()
if err != nil {
logrus.Errorf("Failed to normalize obj with json patch, error: %v", err)
return nil
}
patched := applyPatches(jsondata, j.patch[gvk][key])
if err := un.UnmarshalJSON(patched); err != nil {
logrus.Errorf("Failed to normalize obj with json patch, error: %v", err)
return nil
}
return nil
}
func (j *JSONPatchNormalizer) hasPatches(gvk schema.GroupVersionKind, key objectset.ObjectKey) bool {
gvkPatches, ok := j.patch[gvk]
if !ok {
return false
}
keyPatches, ok := gvkPatches[key]
if !ok {
return false
}
if len(keyPatches) == 0 {
return false
}
return true
}
func applyPatches(jsondata []byte, patches []JSONPatch) []byte {
for _, patch := range patches {
p, err := jsonpatch.DecodePatch(patch)
if err != nil {
logrus.Errorf("Failed to normalize obj with json patch, error: %v", err)
return nil
}
jsondata, err = p.Apply(jsondata)
if err != nil {
logrus.Errorf("Failed to normalize obj with json patch, error: %v", err)
return nil
}
}
return jsondata
}