...
1 package k8s
2
3 import (
4 "encoding/json"
5 "fmt"
6 "strings"
7
8 "github.com/emissary-ingress/emissary/v3/pkg/kates"
9 )
10
11
12 type Map map[string]interface{}
13
14
15
16
17
18 func (m Map) GetMap(name string) map[string]interface{} {
19 v, ok := m[name].(map[string]interface{})
20 if !ok {
21 return map[string]interface{}{}
22 }
23 return v
24 }
25
26
27
28
29
30
31 func (m Map) GetMaps(name string) []map[string]interface{} {
32 v, ok := m[name].([]interface{})
33 if !ok {
34 return nil
35 }
36 result := make([]map[string]interface{}, len(v))
37 for idx, obj := range v {
38 result[idx], ok = obj.(map[string]interface{})
39 if !ok {
40 result[idx] = map[string]interface{}{}
41 }
42 }
43 return result
44 }
45
46
47
48
49
50
51 func (m Map) GetString(key string) string {
52 v, ok := m[key].(string)
53 if !ok {
54 return ""
55 }
56 return v
57 }
58
59
60
61
62
63 func (m Map) GetInt64(key string) int64 {
64 v, ok := m[key].(int64)
65 if !ok {
66 return 0
67 }
68 return v
69 }
70
71
72
73
74
75 func (m Map) GetBool(key string) bool {
76 v, ok := m[key].(bool)
77 if !ok {
78 return false
79 }
80 return v
81 }
82
83
84
85 type Resource map[string]interface{}
86
87 func (r Resource) Kind() string {
88 return Map(r).GetString("kind")
89 }
90
91
92
93 func QKind(gv, k string) string {
94 var g, v string
95 if slash := strings.IndexByte(gv, '/'); slash < 0 {
96 g = ""
97 v = gv
98 } else {
99 g = gv[:slash]
100 v = gv[slash+1:]
101 }
102 return strings.Join([]string{k, v, g}, ".")
103 }
104
105
106 func (r Resource) QKind() string {
107 gv := Map(r).GetString("apiVersion")
108 k := Map(r).GetString("kind")
109 return QKind(gv, k)
110 }
111
112 func (r Resource) Empty() bool {
113 _, ok := r["kind"]
114 return !ok
115 }
116
117 func (r Resource) Status() Map {
118 return Map(r).GetMap("status")
119 }
120
121 func (r Resource) Data() Map {
122 return Map(r).GetMap("data")
123 }
124
125 func (r Resource) Spec() Map {
126 return Map(r).GetMap("spec")
127 }
128
129 type Metadata map[string]interface{}
130
131 func (r Resource) Metadata() Metadata {
132 return Metadata(Map(r).GetMap("metadata"))
133 }
134
135
136 func (m Metadata) Name() string { return Map(m).GetString("name") }
137 func (r Resource) Name() string { return r.Metadata().Name() }
138
139
140 func (m Metadata) Namespace() string { return Map(m).GetString("namespace") }
141 func (r Resource) Namespace() string { return r.Metadata().Namespace() }
142
143
144 func (m Metadata) ResourceVersion() string { return Map(m).GetString("resourceVersion") }
145 func (r Resource) ResourceVersion() string { return r.Metadata().ResourceVersion() }
146
147 func (m Metadata) Annotations() map[string]interface{} {
148 return Map(m).GetMap("annotations")
149 }
150
151 func (m Metadata) QName() string {
152 ns := m.Namespace()
153 if ns == "" {
154 return m.Name()
155 } else {
156 return fmt.Sprintf("%s.%s", m.Name(), ns)
157 }
158 }
159
160 func (r Resource) QName() string { return r.Metadata().QName() }
161
162
163
164
165 func fixup(obj interface{}) interface{} {
166 switch obj := obj.(type) {
167 case []interface{}:
168 return fixupList(obj)
169 case map[interface{}]interface{}:
170 return fixupMap(obj)
171 default:
172 return obj
173 }
174 }
175
176 func fixupList(obj []interface{}) []interface{} {
177 result := make([]interface{}, len(obj))
178 for i, v := range obj {
179 result[i] = fixup(v)
180 }
181 return result
182 }
183
184 func fixupMap(obj map[interface{}]interface{}) map[string]interface{} {
185 result := make(map[string]interface{})
186 for key, val := range obj {
187 if key, ok := key.(string); ok {
188 result[key] = fixup(val)
189 }
190 }
191 return result
192 }
193
194
195
196
197 func NewResourceFromYaml(yaml map[interface{}]interface{}) Resource {
198 return Resource(fixupMap(yaml))
199 }
200
201 func ParseResources(name, input string) (result []Resource, err error) {
202 resultWrongType, err := kates.ParseManifestsToUnstructured(input)
203 if err != nil {
204 return nil, fmt.Errorf("%s: %w", name, err)
205 }
206 bs, err := json.Marshal(resultWrongType)
207 if err != nil {
208 return nil, fmt.Errorf("%s: %w", name, err)
209 }
210 if err := json.Unmarshal(bs, &result); err != nil {
211 return nil, fmt.Errorf("%s: %w", name, err)
212 }
213 return result, nil
214 }
215
View as plain text