• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubescape / k8s-interface / 6643761114

25 Oct 2023 05:07PM UTC coverage: 29.387% (+0.08%) from 29.311%
6643761114

Pull #79

github

web-flow
Merge 948cb6973 into f3bf75165
Pull Request #79: support service selector

12 of 12 new or added lines in 2 files covered. (100.0%)

1457 of 4958 relevant lines covered (29.39%)

4.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.61
/workloadinterface/workloadmethods.go
1
package workloadinterface
2

3
import (
4
        "encoding/json"
5
        "errors"
6
        "fmt"
7
        "strconv"
8
        "strings"
9

10
        "github.com/armosec/armoapi-go/apis"
11
        "github.com/armosec/utils-k8s-go/armometadata"
12
        wlidpkg "github.com/armosec/utils-k8s-go/wlid"
13
        corev1 "k8s.io/api/core/v1"
14
        v1 "k8s.io/api/core/v1"
15
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
        "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
17
        "k8s.io/utils/strings/slices"
18
)
19

20
const TypeWorkloadObject ObjectType = "workload"
21

22
type Workload struct {
23
        workload map[string]interface{}
24
}
25

26
func NewWorkload(bWorkload []byte) (*Workload, error) {
46✔
27
        workload := make(map[string]interface{})
46✔
28
        if bWorkload != nil {
92✔
29
                if err := json.Unmarshal(bWorkload, &workload); err != nil {
46✔
30
                        return nil, err
×
31
                }
×
32
        }
33
        // if !IsTypeWorkload(workload) {
34
        //         return nil, fmt.Errorf("invalid workload - expected k8s workload")
35
        // }
36
        return &Workload{
46✔
37
                workload: workload,
46✔
38
        }, nil
46✔
39
}
40

41
func NewWorkloadObj(workload map[string]interface{}) *Workload {
2✔
42
        return &Workload{
2✔
43
                workload: workload,
2✔
44
        }
2✔
45
}
2✔
46

47
func (w *Workload) GetObjectType() ObjectType {
×
48
        return TypeWorkloadObject
×
49
}
×
50

51
func (w *Workload) Json() string {
×
52
        return w.ToString()
×
53
}
×
54
func (w *Workload) ToString() string {
×
55
        if w.GetWorkload() == nil {
×
56
                return ""
×
57
        }
×
58
        bWorkload, err := json.Marshal(w.GetWorkload())
×
59
        if err != nil {
×
60
                return err.Error()
×
61
        }
×
62
        return string(bWorkload)
×
63
}
64

65
func (workload *Workload) DeepCopy(w map[string]interface{}) {
×
66
        workload.workload = make(map[string]interface{})
×
67
        byt, _ := json.Marshal(w)
×
68
        json.Unmarshal(byt, &workload.workload)
×
69
}
×
70

71
func (w *Workload) ToUnstructured() (*unstructured.Unstructured, error) {
×
72
        obj := &unstructured.Unstructured{}
×
73
        if w.workload == nil {
×
74
                return obj, nil
×
75
        }
×
76
        bWorkload, err := json.Marshal(w.workload)
×
77
        if err != nil {
×
78
                return obj, err
×
79
        }
×
80
        if err := json.Unmarshal(bWorkload, obj); err != nil {
×
81
                return obj, err
×
82

×
83
        }
×
84

85
        return obj, nil
×
86
}
87

88
// ======================================= DELETE ========================================
89

90
func (w *Workload) RemoveJobID() {
×
91
        w.RemovePodAnnotation(armometadata.ArmoJobIDPath)
×
92
        w.RemovePodAnnotation(armometadata.ArmoJobParentPath)
×
93
        w.RemovePodAnnotation(armometadata.ArmoJobActionPath)
×
94

×
95
        w.RemoveAnnotation(armometadata.ArmoJobIDPath)
×
96
        w.RemoveAnnotation(armometadata.ArmoJobParentPath)
×
97
        w.RemoveAnnotation(armometadata.ArmoJobActionPath)
×
98
}
×
99

100
func (w *Workload) RemoveSecretData() {
×
101
        w.RemoveAnnotation("kubectl.kubernetes.io/last-applied-configuration")
×
102
        delete(w.workload, "data")
×
103
}
×
104

105
func (w *Workload) RemovePodStatus() {
×
106
        delete(w.workload, "status")
×
107
}
×
108

109
func (w *Workload) RemoveResourceVersion() {
×
110
        if _, ok := w.workload["metadata"]; !ok {
×
111
                return
×
112
        }
×
113
        meta, _ := w.workload["metadata"].(map[string]interface{})
×
114
        delete(meta, "resourceVersion")
×
115
}
116

117
func (w *Workload) RemoveLabel(key string) {
1✔
118
        w.RemoveMetadata([]string{"metadata"}, "labels", key)
1✔
119
}
1✔
120

121
func (w *Workload) RemoveAnnotation(key string) {
1✔
122
        w.RemoveMetadata([]string{"metadata"}, "annotations", key)
1✔
123
}
1✔
124

125
func (w *Workload) RemovePodAnnotation(key string) {
×
126
        w.RemoveMetadata(PodMetadata(w.GetKind()), "annotations", key)
×
127
}
×
128

129
func (w *Workload) RemovePodLabel(key string) {
1✔
130
        w.RemoveMetadata(PodMetadata(w.GetKind()), "labels", key)
1✔
131
}
1✔
132

133
func (w *Workload) RemoveMetadata(scope []string, metadata, key string) {
3✔
134

3✔
135
        workload := w.workload
3✔
136
        for i := range scope {
8✔
137
                if _, ok := workload[scope[i]]; !ok {
5✔
138
                        return
×
139
                }
×
140
                workload, _ = workload[scope[i]].(map[string]interface{})
5✔
141
        }
142

143
        if _, ok := workload[metadata]; !ok {
3✔
144
                return
×
145
        }
×
146

147
        labels, _ := workload[metadata].(map[string]interface{})
3✔
148
        delete(labels, key)
3✔
149

150
}
151

152
// ========================================= SET =========================================
153

154
func (w *Workload) SetWorkload(workload map[string]interface{}) {
×
155
        w.SetObject(workload)
×
156
}
×
157

158
func (w *Workload) SetObject(workload map[string]interface{}) {
×
159
        w.workload = workload
×
160
}
×
161

162
func (w *Workload) SetApiVersion(apiVersion string) {
×
163
        w.workload["apiVersion"] = apiVersion
×
164
}
×
165

166
func (w *Workload) SetKind(kind string) {
×
167
        w.workload["kind"] = kind
×
168
}
×
169

170
func (w *Workload) SetJobID(jobTracking apis.JobTracking) {
×
171
        w.SetPodAnnotation(armometadata.ArmoJobIDPath, jobTracking.JobID)
×
172
        w.SetPodAnnotation(armometadata.ArmoJobParentPath, jobTracking.ParentID)
×
173
        w.SetPodAnnotation(armometadata.ArmoJobActionPath, fmt.Sprintf("%d", jobTracking.LastActionNumber))
×
174
}
×
175

176
func (w *Workload) SetNamespace(namespace string) {
1✔
177
        SetInMap(w.workload, []string{"metadata"}, "namespace", namespace)
1✔
178
}
1✔
179

180
func (w *Workload) SetName(name string) {
×
181
        SetInMap(w.workload, []string{"metadata"}, "name", name)
×
182
}
×
183

184
func (w *Workload) SetLabel(key, value string) {
1✔
185
        SetInMap(w.workload, []string{"metadata", "labels"}, key, value)
1✔
186
}
1✔
187

188
func (w *Workload) SetPodLabel(key, value string) {
1✔
189
        SetInMap(w.workload, append(PodMetadata(w.GetKind()), "labels"), key, value)
1✔
190
}
1✔
191
func (w *Workload) SetAnnotation(key, value string) {
1✔
192
        SetInMap(w.workload, []string{"metadata", "annotations"}, key, value)
1✔
193
}
1✔
194
func (w *Workload) SetPodAnnotation(key, value string) {
×
195
        SetInMap(w.workload, append(PodMetadata(w.GetKind()), "annotations"), key, value)
×
196
}
×
197

198
// ========================================= GET =========================================
199
func (w *Workload) GetWorkload() map[string]interface{} {
×
200
        return w.GetObject()
×
201
}
×
202
func (w *Workload) GetObject() map[string]interface{} {
3✔
203
        return w.workload
3✔
204
}
3✔
205
func (w *Workload) GetNamespace() string {
4✔
206
        if v, ok := InspectWorkload(w.workload, "metadata", "namespace"); ok {
7✔
207
                return v.(string)
3✔
208
        }
3✔
209
        return ""
1✔
210
}
211
func (w *Workload) GetID() string {
2✔
212
        return fmt.Sprintf("%s/%s/%s/%s/%s", w.GetGroup(), w.GetVersion(), w.GetNamespace(), w.GetKind(), w.GetName())
2✔
213

2✔
214
        // TODO - return like selfLink - e.g. /apis/apps/v1/namespaces/monitoring/statefulsets/alertmanager-prometheus-
2✔
215
        // return fmt.Sprintf("apps/%s/%s/%s/%s", w.GetApiVersion(), w.GetNamespace(), w.GetKind(), w.GetName())
2✔
216
}
2✔
217
func (w *Workload) GetName() string {
5✔
218
        if v, ok := InspectWorkload(w.workload, "metadata", "name"); ok {
9✔
219
                return v.(string)
4✔
220
        }
4✔
221
        return ""
1✔
222
}
223

224
func (w *Workload) GetData() map[string]interface{} {
×
225
        if v, ok := InspectWorkload(w.workload, "data"); ok {
×
226
                return v.(map[string]interface{})
×
227
        }
×
228
        return nil
×
229
}
230

231
func (w *Workload) GetApiVersion() string {
4✔
232
        if v, ok := InspectWorkload(w.workload, "apiVersion"); ok {
8✔
233
                return v.(string)
4✔
234
        }
4✔
235
        return ""
×
236
}
237

238
func (w *Workload) GetVersion() string {
2✔
239
        apiVersion := w.GetApiVersion()
2✔
240
        splitted := strings.Split(apiVersion, "/")
2✔
241
        if len(splitted) == 1 {
3✔
242
                return splitted[0]
1✔
243
        } else if len(splitted) == 2 {
3✔
244
                return splitted[1]
1✔
245
        }
1✔
246
        return ""
×
247
}
248

249
func (w *Workload) GetGroup() string {
2✔
250
        apiVersion := w.GetApiVersion()
2✔
251
        splitted := strings.Split(apiVersion, "/")
2✔
252
        if len(splitted) == 2 {
3✔
253
                return splitted[0]
1✔
254
        }
1✔
255
        return ""
1✔
256
}
257

258
func (w *Workload) GetGenerateName() string {
×
259
        if v, ok := InspectWorkload(w.workload, "metadata", "generateName"); ok {
×
260
                return v.(string)
×
261
        }
×
262
        return ""
×
263
}
264

265
func (w *Workload) GetReplicas() int {
1✔
266
        if v, ok := InspectWorkload(w.workload, "spec", "replicas"); ok {
2✔
267
                switch n := v.(type) {
1✔
268
                case float64:
×
269
                        return int(n)
×
270
                case int64:
×
271
                        return int(n)
×
272
                case float32:
×
273
                        return int(n)
×
274
                case int32:
×
275
                        return int(n)
×
276
                case int16:
×
277
                        return int(n)
×
278
                case int:
1✔
279
                        return n
1✔
280
                }
281
        }
282
        return 1
×
283
}
284

285
func (w *Workload) GetKind() string {
64✔
286
        if v, ok := InspectWorkload(w.workload, "kind"); ok {
128✔
287
                return v.(string)
64✔
288
        }
64✔
289
        return ""
×
290
}
291

292
func (w *Workload) GetServiceSelector() map[string]string {
1✔
293
        if v, ok := InspectWorkload(w.workload, "spec", "selector"); ok && v != nil {
2✔
294
                selector := make(map[string]string)
1✔
295
                for k, i := range v.(map[string]interface{}) {
2✔
296
                        selector[k] = fmt.Sprintf("%v", i)
1✔
297
                }
1✔
298
                return selector
1✔
299
        }
300
        return nil
×
301
}
302

303
func (w *Workload) GetSelector() (*metav1.LabelSelector, error) {
1✔
304
        selector := &metav1.LabelSelector{}
1✔
305
        if matchLabels, ok := InspectWorkload(w.workload, "spec", "selector", "matchLabels"); ok && matchLabels != nil {
2✔
306
                if m, ok := matchLabels.(map[string]interface{}); ok {
2✔
307
                        selector.MatchLabels = make(map[string]string, len(m))
1✔
308
                        for k, v := range m {
2✔
309
                                selector.MatchLabels[k] = v.(string)
1✔
310
                        }
1✔
311
                }
312
        }
313
        if matchExpressions, ok := InspectWorkload(w.workload, "spec", "selector", "matchExpressions"); ok && matchExpressions != nil {
1✔
314
                b, err := json.Marshal(matchExpressions)
×
315
                if err != nil {
×
316
                        return selector, err
×
317
                }
×
318
                if err := json.Unmarshal(b, &selector.MatchExpressions); err != nil {
×
319
                        return selector, nil
×
320
                }
×
321
        }
322
        return selector, nil
1✔
323
}
324

325
func (w *Workload) GetAnnotation(annotation string) (string, bool) {
2✔
326
        if v, ok := InspectWorkload(w.workload, "metadata", "annotations", annotation); ok {
3✔
327
                return v.(string), ok
1✔
328
        }
1✔
329
        return "", false
1✔
330
}
331
func (w *Workload) GetLabel(label string) (string, bool) {
2✔
332
        if v, ok := InspectWorkload(w.workload, "metadata", "labels", label); ok {
3✔
333
                return v.(string), ok
1✔
334
        }
1✔
335
        return "", false
1✔
336
}
337

338
func (w *Workload) GetPodLabel(label string) (string, bool) {
2✔
339
        if v, ok := InspectWorkload(w.workload, append(PodMetadata(w.GetKind()), "labels", label)...); ok && v != nil {
3✔
340
                return v.(string), ok
1✔
341
        }
1✔
342
        return "", false
1✔
343
}
344

345
func (w *Workload) GetLabels() map[string]string {
1✔
346
        if v, ok := InspectWorkload(w.workload, "metadata", "labels"); ok && v != nil {
2✔
347
                labels := make(map[string]string)
1✔
348
                for k, i := range v.(map[string]interface{}) {
5✔
349
                        // null labels will be ignored
4✔
350
                        if i == nil {
6✔
351
                                continue
2✔
352
                        }
353

354
                        labels[k] = i.(string)
2✔
355
                }
356
                return labels
1✔
357
        }
358
        return nil
×
359
}
360

361
// GetInnerLabels - DEPRECATED
362
func (w *Workload) GetInnerLabels() map[string]string {
×
363
        return w.GetPodLabels()
×
364
}
×
365

366
func (w *Workload) GetPodLabels() map[string]string {
×
367
        if v, ok := InspectWorkload(w.workload, append(PodMetadata(w.GetKind()), "labels")...); ok && v != nil {
×
368
                labels := make(map[string]string)
×
369
                for k, i := range v.(map[string]interface{}) {
×
370
                        labels[k] = i.(string)
×
371
                }
×
372
                return labels
×
373
        }
374
        return nil
×
375
}
376

377
// GetInnerAnnotations - DEPRECATED
378
func (w *Workload) GetInnerAnnotations() map[string]string {
×
379
        return w.GetPodAnnotations()
×
380
}
×
381

382
// GetPodAnnotations
383
func (w *Workload) GetPodAnnotations() map[string]string {
×
384
        if v, ok := InspectWorkload(w.workload, append(PodMetadata(w.GetKind()), "annotations")...); ok && v != nil {
×
385
                annotations := make(map[string]string)
×
386
                for k, i := range v.(map[string]interface{}) {
×
387
                        annotations[k] = fmt.Sprintf("%v", i)
×
388
                }
×
389
                return annotations
×
390
        }
391
        return nil
×
392
}
393

394
// GetInnerAnnotation DEPRECATED
395
func (w *Workload) GetInnerAnnotation(annotation string) (string, bool) {
×
396
        return w.GetPodAnnotation(annotation)
×
397
}
×
398

399
func (w *Workload) GetPodAnnotation(annotation string) (string, bool) {
×
400
        if v, ok := InspectWorkload(w.workload, append(PodMetadata(w.GetKind()), "annotations", annotation)...); ok && v != nil {
×
401
                return v.(string), ok
×
402
        }
×
403
        return "", false
×
404
}
405

406
func (w *Workload) GetAnnotations() map[string]string {
×
407
        if v, ok := InspectWorkload(w.workload, "metadata", "annotations"); ok && v != nil {
×
408
                annotations := make(map[string]string)
×
409
                for k, i := range v.(map[string]interface{}) {
×
410
                        annotations[k] = fmt.Sprintf("%v", i)
×
411
                }
×
412
                return annotations
×
413
        }
414
        return nil
×
415
}
416

417
func (w *Workload) GetServiceAccountName() string {
×
418

×
419
        if v, ok := InspectWorkload(w.workload, append(PodSpec(w.GetKind()), "serviceAccountName")...); ok && v != nil {
×
420
                return v.(string)
×
421
        }
×
422
        return ""
×
423
}
424

425
func (w *Workload) GetPodSpec() (*corev1.PodSpec, error) {
25✔
426
        podSpec := &corev1.PodSpec{}
25✔
427
        podSepcRaw, _ := InspectWorkload(w.workload, PodSpec(w.GetKind())...)
25✔
428
        if podSepcRaw == nil {
25✔
429
                return podSpec, fmt.Errorf("no PodSpec for workload: %v", w)
×
430
        }
×
431
        b, err := json.Marshal(podSepcRaw)
25✔
432
        if err != nil {
25✔
433
                return podSpec, err
×
434
        }
×
435
        err = json.Unmarshal(b, podSpec)
25✔
436

25✔
437
        return podSpec, err
25✔
438
}
439

440
func (w *Workload) GetImagePullSecret() ([]corev1.LocalObjectReference, error) {
×
441
        imgPullSecrets := []corev1.LocalObjectReference{}
×
442

×
443
        iImgPullSecrets, _ := InspectWorkload(w.workload, append(PodSpec(w.GetKind()), "imagePullSecrets")...)
×
444
        b, err := json.Marshal(iImgPullSecrets)
×
445
        if err != nil {
×
446
                return imgPullSecrets, err
×
447
        }
×
448
        err = json.Unmarshal(b, &imgPullSecrets)
×
449

×
450
        return imgPullSecrets, err
×
451
}
452

453
// GetContainers -
454
func (w *Workload) GetContainers() ([]corev1.Container, error) {
27✔
455
        containers := []corev1.Container{}
27✔
456

27✔
457
        interContainers, _ := InspectWorkload(w.workload, append(PodSpec(w.GetKind()), "containers")...)
27✔
458
        if interContainers == nil {
28✔
459
                return containers, nil
1✔
460
        }
1✔
461
        containersBytes, err := json.Marshal(interContainers)
26✔
462
        if err != nil {
26✔
463
                return containers, err
×
464
        }
×
465
        err = json.Unmarshal(containersBytes, &containers)
26✔
466

26✔
467
        return containers, err
26✔
468
}
469

470
// GetInitContainers -
471
func (w *Workload) GetInitContainers() ([]corev1.Container, error) {
×
472
        containers := []corev1.Container{}
×
473

×
474
        interContainers, _ := InspectWorkload(w.workload, append(PodSpec(w.GetKind()), "initContainers")...)
×
475
        if interContainers == nil {
×
476
                return containers, nil
×
477
        }
×
478
        containersBytes, err := json.Marshal(interContainers)
×
479
        if err != nil {
×
480
                return containers, err
×
481
        }
×
482
        err = json.Unmarshal(containersBytes, &containers)
×
483

×
484
        return containers, err
×
485
}
486

487
// GetOwnerReferences -
488
func (w *Workload) GetOwnerReferences() ([]metav1.OwnerReference, error) {
×
489
        ownerReferences := []metav1.OwnerReference{}
×
490
        interOwnerReferences, ok := InspectWorkload(w.workload, "metadata", "ownerReferences")
×
491
        if !ok {
×
492
                return ownerReferences, nil
×
493
        }
×
494

495
        ownerReferencesBytes, err := json.Marshal(interOwnerReferences)
×
496
        if err != nil {
×
497
                return ownerReferences, err
×
498
        }
×
499
        err = json.Unmarshal(ownerReferencesBytes, &ownerReferences)
×
500
        if err != nil {
×
501
                return ownerReferences, err
×
502

×
503
        }
×
504
        return ownerReferences, nil
×
505
}
506
func (w *Workload) GetResourceVersion() string {
1✔
507
        if v, ok := InspectWorkload(w.workload, "metadata", "resourceVersion"); ok {
2✔
508
                return v.(string)
1✔
509
        }
1✔
510
        return ""
×
511
}
512
func (w *Workload) GetUID() string {
1✔
513
        if v, ok := InspectWorkload(w.workload, "metadata", "uid"); ok {
2✔
514
                return v.(string)
1✔
515
        }
1✔
516
        return ""
×
517
}
518
func (w *Workload) GetWlid() string {
×
519
        if wlid, ok := w.GetAnnotation(armometadata.ArmoWlid); ok {
×
520
                return wlid
×
521
        }
×
522
        return ""
×
523
}
524

525
func (w *Workload) GenerateWlid(clusterName string) string {
×
526
        return wlidpkg.GetK8sWLID(clusterName, w.GetNamespace(), w.GetKind(), w.GetName())
×
527
}
×
528

529
func (w *Workload) GetJobID() *apis.JobTracking {
×
530
        jobTracking := apis.JobTracking{}
×
531
        if job, ok := w.GetPodAnnotation(armometadata.ArmoJobIDPath); ok {
×
532
                jobTracking.JobID = job
×
533
        }
×
534
        if parent, ok := w.GetPodAnnotation(armometadata.ArmoJobParentPath); ok {
×
535
                jobTracking.ParentID = parent
×
536
        }
×
537
        if action, ok := w.GetPodAnnotation(armometadata.ArmoJobActionPath); ok {
×
538
                if i, err := strconv.Atoi(action); err == nil {
×
539
                        jobTracking.LastActionNumber = i
×
540
                }
×
541
        }
542
        if jobTracking.LastActionNumber == 0 { // start the counter at 1
×
543
                jobTracking.LastActionNumber = 1
×
544
        }
×
545
        return &jobTracking
×
546
}
547

548
// Returns map of container name to container's secrets
549
func (w *Workload) GetSecretsOfContainer() (map[string][]string, error) {
12✔
550
        mapMountToSecretName := make(map[string]string)
12✔
551
        volumes, err := w.GetVolumes()
12✔
552
        if err != nil {
12✔
553
                return nil, err
×
554
        }
×
555
        for _, volume := range volumes {
55✔
556
                if volume.Secret != nil {
70✔
557
                        mapMountToSecretName[volume.Name] = volume.Secret.SecretName
27✔
558
                }
27✔
559
        }
560

561
        containers, err := w.GetContainers()
12✔
562
        if err != nil {
12✔
563
                return nil, err
×
564
        }
×
565

566
        secretsOfContainer := make(map[string][]string)
12✔
567
        for _, container := range containers {
36✔
568
                secretsOfContainer[container.Name] = []string{}
24✔
569
                for _, volumeMount := range container.VolumeMounts {
76✔
570
                        if secretName, ok := mapMountToSecretName[volumeMount.Name]; ok {
80✔
571
                                if !slices.Contains(secretsOfContainer[container.Name], secretName) {
56✔
572
                                        secretsOfContainer[container.Name] = append(secretsOfContainer[container.Name], secretName)
28✔
573
                                }
28✔
574
                        }
575
                }
576

577
                for _, envFrom := range container.EnvFrom {
26✔
578
                        if envFrom.SecretRef != nil {
4✔
579
                                if !slices.Contains(secretsOfContainer[container.Name], envFrom.SecretRef.Name) {
4✔
580
                                        secretsOfContainer[container.Name] = append(secretsOfContainer[container.Name], envFrom.SecretRef.Name)
2✔
581
                                }
2✔
582
                        }
583
                }
584

585
                for _, env := range container.Env {
28✔
586
                        if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil {
8✔
587
                                if !slices.Contains(secretsOfContainer[container.Name], env.ValueFrom.SecretKeyRef.Name) {
6✔
588
                                        secretsOfContainer[container.Name] = append(secretsOfContainer[container.Name], env.ValueFrom.SecretKeyRef.Name)
2✔
589
                                }
2✔
590
                        }
591
                }
592

593
        }
594
        return secretsOfContainer, nil
12✔
595
}
596

597
// Returns map of container name to container's configmaps
598
func (w *Workload) GetConfigMapsOfContainer() (map[string][]string, error) {
12✔
599
        mapMountToConfigMapName := make(map[string]string)
12✔
600
        volumes, err := w.GetVolumes()
12✔
601
        if err != nil {
12✔
602
                return nil, err
×
603
        }
×
604
        for _, volume := range volumes {
54✔
605
                if volume.ConfigMap != nil {
61✔
606
                        mapMountToConfigMapName[volume.Name] = volume.ConfigMap.Name
19✔
607
                }
19✔
608
        }
609
        containers, err := w.GetContainers()
12✔
610
        if err != nil {
12✔
611
                return nil, err
×
612
        }
×
613

614
        configMapsOfContainer := make(map[string][]string)
12✔
615
        for _, container := range containers {
36✔
616
                configMapsOfContainer[container.Name] = []string{}
24✔
617
                for _, volumeMount := range container.VolumeMounts {
74✔
618
                        if configMapName, ok := mapMountToConfigMapName[volumeMount.Name]; ok {
70✔
619
                                if !slices.Contains(configMapsOfContainer[container.Name], configMapName) {
40✔
620
                                        configMapsOfContainer[container.Name] = append(configMapsOfContainer[container.Name], configMapName)
20✔
621
                                }
20✔
622
                        }
623
                }
624

625
                for _, envFrom := range container.EnvFrom {
26✔
626
                        if envFrom.ConfigMapRef != nil {
4✔
627
                                if !slices.Contains(configMapsOfContainer[container.Name], envFrom.ConfigMapRef.Name) {
4✔
628
                                        configMapsOfContainer[container.Name] = append(configMapsOfContainer[container.Name], envFrom.ConfigMapRef.Name)
2✔
629
                                }
2✔
630
                        }
631
                }
632

633
                for _, env := range container.Env {
28✔
634
                        if env.ValueFrom != nil && env.ValueFrom.ConfigMapKeyRef != nil {
8✔
635
                                if !slices.Contains(configMapsOfContainer[container.Name], env.ValueFrom.ConfigMapKeyRef.Name) {
6✔
636
                                        configMapsOfContainer[container.Name] = append(configMapsOfContainer[container.Name], env.ValueFrom.ConfigMapKeyRef.Name)
2✔
637
                                }
2✔
638
                        }
639
                }
640

641
        }
642
        return configMapsOfContainer, nil
12✔
643
}
644

645
func (w *Workload) GetSecrets() ([]string, error) {
5✔
646
        secretsOfContainer, err := w.GetSecretsOfContainer()
5✔
647
        if err != nil {
5✔
648
                return nil, err
×
649
        }
×
650
        secrets := []string{}
5✔
651
        for _, scrts := range secretsOfContainer {
14✔
652
                for _, scrt := range scrts {
19✔
653
                        if !slices.Contains(secrets, scrt) {
19✔
654
                                secrets = append(secrets, scrt)
9✔
655
                        }
9✔
656
                }
657
        }
658
        return secrets, nil
5✔
659
}
660

661
func (w *Workload) GetConfigMaps() ([]string, error) {
5✔
662
        cfgMapsOfContainer, err := w.GetConfigMapsOfContainer()
5✔
663
        if err != nil {
5✔
664
                return nil, err
×
665
        }
×
666
        configMaps := []string{}
5✔
667
        for _, cfgMaps := range cfgMapsOfContainer {
14✔
668
                for _, cfgMap := range cfgMaps {
17✔
669
                        if !slices.Contains(configMaps, cfgMap) {
15✔
670
                                configMaps = append(configMaps, cfgMap)
7✔
671
                        }
7✔
672
                }
673
        }
674
        return configMaps, nil
5✔
675
}
676

677
func (w *Workload) GetPodStatus() (*corev1.PodStatus, error) {
2✔
678
        status := corev1.PodStatus{}
2✔
679
        if v, ok := InspectWorkload(w.workload, "status"); ok && v != nil {
3✔
680
                vBytes, err := json.Marshal(v)
1✔
681
                if err != nil {
1✔
682
                        return nil, err
×
683
                }
×
684
                err = json.Unmarshal(vBytes, &status)
1✔
685
                if err != nil {
1✔
686
                        return nil, err
×
687
                }
×
688
        }
689
        return &status, nil
2✔
690
}
691

692
// GetHostVolumes returns all host volumes of the workload
693
func (w *Workload) GetVolumes() ([]v1.Volume, error) {
25✔
694
        podSpec, err := w.GetPodSpec()
25✔
695
        if err != nil {
25✔
696
                return nil, err
×
697
        }
×
698

699
        return podSpec.Volumes, nil
25✔
700
}
701

702
// GetSpecPathPrefix returns the path prefix of the workload spec
703
func (w *Workload) GetSpecPath() (string, error) {
3✔
704
        switch w.GetKind() {
3✔
705
        case "Pod":
1✔
706
                return "spec", nil
1✔
707
        case "Deployment", "ReplicaSet", "DaemonSet", "StatefulSet", "Job":
1✔
708
                return "spec.template.spec", nil
1✔
709
        case "CronJob":
1✔
710
                return "spec.jobTemplate.spec.template.spec", nil
1✔
711
        default:
×
712
                return "", errors.New("unsupported workload kind")
×
713
        }
714
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc