/
patch.go
61 lines (52 loc) · 1.83 KB
/
patch.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
package kube
import (
"encoding/json"
"github.com/mattbaird/jsonpatch"
"github.com/pkg/errors"
)
// PatchRow used to generate the patch JSON for patching
type PatchRow struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value"`
}
// CreatePatchBytes creates a kubernetes PATCH block
func CreatePatchBytes(op string, path string, value interface{}) ([]byte, error) {
payload := &PatchRow{
Op: op,
Path: path,
Value: value,
}
return json.Marshal(payload)
}
// PatchModifier is a function that is function that mutates an entity during JSON patch generation.
// The function should modify the provided value, and can return an non-nil error if something goes wrong.
type PatchModifier func(obj interface{}) error
// BuildJSONPatch builds JSON patch data for an entity mutation, that can then be applied to K8S as a Patch update.
// The mutation is applied via the supplied callback, which modifies the entity it is given. If the supplied
// mutate method returns an error then the process is aborted and the error returned.
func BuildJSONPatch(obj interface{}, mutate PatchModifier) ([]byte, error) {
// Get original JSON.
oJSON, err := json.Marshal(obj)
if err != nil {
return nil, errors.WithMessage(err, "marshalling original data")
}
err = mutate(obj)
if err != nil {
return nil, errors.WithMessage(err, "mutating entity")
}
// Get modified JSON & generate a PATCH to apply.
mJSON, err := json.Marshal(obj)
if err != nil {
return nil, errors.WithMessage(err, "marshalling modified data")
}
patch, err := jsonpatch.CreatePatch(oJSON, mJSON)
if err != nil {
return nil, errors.WithMessage(err, "generating patch data")
}
patchJSON, err := json.MarshalIndent(patch, "", " ")
if err != nil {
return nil, errors.WithMessage(err, "marshalling patch data")
}
return patchJSON, nil
}