-
Notifications
You must be signed in to change notification settings - Fork 214
/
helpers.go
144 lines (122 loc) · 3.16 KB
/
helpers.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package object_patch
import (
"bytes"
"encoding/json"
"fmt"
"io"
"github.com/flant/kube-client/manifest"
"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
k8yaml "sigs.k8s.io/yaml"
"github.com/flant/shell-operator/pkg/app"
"github.com/flant/shell-operator/pkg/jq"
)
func unmarshalFromJSONOrYAML(specs []byte) ([]OperationSpec, error) {
fromJsonSpecs, err := unmarshalFromJson(specs)
if err != nil {
return unmarshalFromYaml(specs)
}
return fromJsonSpecs, nil
}
func unmarshalFromJson(jsonSpecs []byte) ([]OperationSpec, error) {
var specSlice []OperationSpec
dec := json.NewDecoder(bytes.NewReader(jsonSpecs))
for {
var doc OperationSpec
err := dec.Decode(&doc)
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
specSlice = append(specSlice, doc)
}
return specSlice, nil
}
func unmarshalFromYaml(yamlSpecs []byte) ([]OperationSpec, error) {
var specSlice []OperationSpec
dec := yaml.NewDecoder(bytes.NewReader(yamlSpecs))
for {
var doc OperationSpec
err := dec.Decode(&doc)
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
specSlice = append(specSlice, doc)
}
return specSlice, nil
}
func applyJQPatch(jqFilter string, obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
objBytes, err := obj.MarshalJSON()
if err != nil {
return nil, err
}
filterResult, err := jq.ApplyJqFilter(jqFilter, objBytes, app.JqLibraryPath)
if err != nil {
return nil, fmt.Errorf("failed to apply jqFilter:\n%sto Object:\n%s\n"+
"error: %s", jqFilter, obj, err)
}
var retObj = &unstructured.Unstructured{}
_, _, err = unstructured.UnstructuredJSONScheme.Decode([]byte(filterResult), nil, retObj)
if err != nil {
return nil, fmt.Errorf("failed to convert filterResult:\n%s\nto Unstructured Object\nerror: %s", filterResult, err)
}
return retObj, nil
}
func generateSubresources(subresource string) (ret []string) {
if subresource != "" {
ret = append(ret, subresource)
}
return
}
func toUnstructured(obj interface{}) (*unstructured.Unstructured, error) {
switch v := obj.(type) {
case []byte:
mft, err := manifest.NewFromYAML(string(v))
if err != nil {
return nil, err
}
return mft.Unstructured(), nil
case string:
mft, err := manifest.NewFromYAML(v)
if err != nil {
return nil, err
}
return mft.Unstructured(), nil
case map[string]interface{}:
return &unstructured.Unstructured{Object: v}, nil
default:
objectContent, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
return nil, fmt.Errorf("convert to unstructured: %v", err)
}
return &unstructured.Unstructured{Object: objectContent}, nil
}
}
func convertPatchToBytes(patch interface{}) ([]byte, error) {
var err error
var intermediate interface{}
switch v := patch.(type) {
case []byte:
err = k8yaml.Unmarshal(v, &intermediate)
case string:
err = k8yaml.Unmarshal([]byte(v), &intermediate)
default:
intermediate = v
}
if err != nil {
return nil, err
}
// Try to encode to JSON.
var patchBytes []byte
patchBytes, err = json.Marshal(intermediate)
if err != nil {
return nil, err
}
return patchBytes, nil
}