Skip to content

Commit 7b49b14

Browse files
authored
Merge pull request #21 from armosec/fix-labels-extraction
fix labels extraction
2 parents 0f29e39 + 5e4cd72 commit 7b49b14

File tree

4 files changed

+103
-3
lines changed

4 files changed

+103
-3
lines changed

armometadata/k8sutils.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type Metadata struct {
115115
Kind string
116116
ApiVersion string
117117
PodSelectorMatchLabels map[string]string
118+
PodSpecLabels map[string]string
118119
}
119120

120121
// ExtractMetadataFromBytes extracts metadata from the JSON bytes of a Kubernetes object
@@ -124,6 +125,7 @@ func ExtractMetadataFromJsonBytes(input []byte) (Metadata, error) {
124125
Annotations: map[string]string{},
125126
Labels: map[string]string{},
126127
OwnerReferences: map[string]string{},
128+
PodSpecLabels: map[string]string{},
127129
PodSelectorMatchLabels: map[string]string{},
128130
}
129131
// ujson parsing
@@ -144,10 +146,14 @@ func ExtractMetadataFromJsonBytes(input []byte) (Metadata, error) {
144146
m.ResourceVersion = unquote(value)
145147
case strings.HasPrefix(jsonPath, "metadata.annotations."):
146148
m.Annotations[unquote(key)] = unquote(value)
147-
case strings.Contains(jsonPath, "metadata.labels."):
149+
case strings.HasPrefix(jsonPath, "metadata.labels."):
148150
m.Labels[unquote(key)] = unquote(value)
149151
case strings.HasPrefix(jsonPath, "metadata.ownerReferences.."):
150152
m.OwnerReferences[unquote(key)] = unquote(value)
153+
case strings.HasPrefix(jsonPath, "spec.template.metadata.labels."):
154+
m.PodSpecLabels[unquote(key)] = unquote(value)
155+
case strings.HasPrefix(jsonPath, "spec.jobTemplate.spec.template.metadata.labels."):
156+
m.PodSpecLabels[unquote(key)] = unquote(value)
151157
case m.ApiVersion == "cilium.io/v2" && strings.HasPrefix(jsonPath, "spec.endpointSelector.matchLabels."):
152158
addCiliumMatchLabels(m.PodSelectorMatchLabels, key, value)
153159
case m.ApiVersion == "networking.k8s.io/v1" && strings.HasPrefix(jsonPath, "spec.podSelector.matchLabels."):

armometadata/k8sutils_test.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,21 +134,48 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
134134
kind string
135135
apiVersion string
136136
podSelectorMatchLabels map[string]string
137+
podSpecLabels map[string]string
137138
}{
139+
{
140+
name: "testcronjob",
141+
annotations: map[string]string{},
142+
labels: map[string]string{
143+
"app": "backup-system",
144+
"team": "platform",
145+
"cost-center": "platform-123",
146+
},
147+
ownerReferences: map[string]string{},
148+
creationTs: "",
149+
resourceVersion: "",
150+
kind: "CronJob",
151+
apiVersion: "batch/v1",
152+
podSelectorMatchLabels: map[string]string{},
153+
podSpecLabels: map[string]string{
154+
"app": "backup-job",
155+
"type": "scheduled-backup",
156+
"environment": "prod",
157+
"component": "database",
158+
"version": "v1.2",
159+
},
160+
},
138161
{
139162
name: "testdeployment",
140163
annotations: map[string]string{
141164
"deployment.kubernetes.io/revision": "1",
142165
},
143166
labels: map[string]string{
144-
"app": "emailservice",
167+
"label-key-1": "label-value-1",
145168
},
146169
ownerReferences: map[string]string{},
147170
creationTs: "2024-07-18T19:58:44Z",
148171
resourceVersion: "6486",
149172
kind: "Deployment",
150173
apiVersion: "apps/v1",
151174
podSelectorMatchLabels: map[string]string{},
175+
podSpecLabels: map[string]string{
176+
"app": "emailservice",
177+
"pod_label_key": "pod_label_value",
178+
},
152179
},
153180
{
154181
name: "networkpolicy_withoutmatching_labels",
@@ -160,6 +187,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
160187
kind: "NetworkPolicy",
161188
apiVersion: "networking.k8s.io/v1",
162189
podSelectorMatchLabels: map[string]string{},
190+
podSpecLabels: map[string]string{},
163191
},
164192
{
165193
name: "networkpolicy_withmatching_labels",
@@ -174,6 +202,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
174202
"role": "frontend",
175203
"tier": "tier1",
176204
},
205+
podSpecLabels: map[string]string{},
177206
},
178207
{
179208
name: "applicationactivity",
@@ -194,6 +223,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
194223
kind: "ApplicationActivity",
195224
apiVersion: "spdx.softwarecomposition.kubescape.io/v1beta1",
196225
podSelectorMatchLabels: map[string]string{},
226+
podSpecLabels: map[string]string{},
197227
},
198228
{
199229
name: "pod",
@@ -225,6 +255,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
225255
kind: "Pod",
226256
apiVersion: "v1",
227257
podSelectorMatchLabels: map[string]string{},
258+
podSpecLabels: map[string]string{},
228259
},
229260
{
230261
name: "sbom",
@@ -242,6 +273,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
242273
kind: "SBOMSPDXv2p3",
243274
apiVersion: "spdx.softwarecomposition.kubescape.io/v1beta1",
244275
podSelectorMatchLabels: map[string]string{},
276+
podSpecLabels: map[string]string{},
245277
},
246278
{
247279
name: "caliconetworkpolicy",
@@ -251,6 +283,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
251283
kind: "NetworkPolicy",
252284
apiVersion: "projectcalico.org/v3",
253285
podSelectorMatchLabels: map[string]string{"role": "database"},
286+
podSpecLabels: map[string]string{},
254287
},
255288
{
256289
name: "ciliumnetworkpolicy",
@@ -260,6 +293,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
260293
kind: "CiliumNetworkPolicy",
261294
apiVersion: "cilium.io/v2",
262295
podSelectorMatchLabels: map[string]string{"any:app": "frontend", "app": "frontend"},
296+
podSpecLabels: map[string]string{},
263297
},
264298
{
265299
name: "istionetworkpolicy",
@@ -269,6 +303,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
269303
kind: "AuthorizationPolicy",
270304
apiVersion: "security.istio.io/v1",
271305
podSelectorMatchLabels: map[string]string{"app": "myapi"},
306+
podSpecLabels: map[string]string{},
272307
},
273308
}
274309
for _, tt := range tests {
@@ -285,6 +320,7 @@ func TestExtractMetadataFromJsonBytes(t *testing.T) {
285320
assert.Equal(t, tt.kind, m.Kind)
286321
assert.Equal(t, tt.apiVersion, m.ApiVersion)
287322
assert.Equal(t, tt.podSelectorMatchLabels, m.PodSelectorMatchLabels)
323+
assert.Equal(t, tt.podSpecLabels, m.PodSpecLabels)
288324
})
289325
}
290326
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"apiVersion": "batch/v1",
3+
"kind": "CronJob",
4+
"metadata": {
5+
"name": "data-backup",
6+
"labels": {
7+
"app": "backup-system",
8+
"team": "platform",
9+
"cost-center": "platform-123"
10+
}
11+
},
12+
"spec": {
13+
"schedule": "0 * * * *",
14+
"concurrencyPolicy": "Forbid",
15+
"successfulJobsHistoryLimit": 3,
16+
"failedJobsHistoryLimit": 1,
17+
"jobTemplate": {
18+
"metadata": {
19+
"labels": {
20+
"generated-by": "cronjob",
21+
"type": "backup-job",
22+
"criticality": "high"
23+
}
24+
},
25+
"spec": {
26+
"template": {
27+
"metadata": {
28+
"labels": {
29+
"app": "backup-job",
30+
"type": "scheduled-backup",
31+
"environment": "prod",
32+
"component": "database",
33+
"version": "v1.2"
34+
}
35+
},
36+
"spec": {
37+
"containers": [
38+
{
39+
"name": "backup-container",
40+
"image": "backup-image:v1",
41+
"command": [
42+
"/bin/sh",
43+
"-c",
44+
"echo performing backup"
45+
]
46+
}
47+
],
48+
"restartPolicy": "OnFailure"
49+
}
50+
}
51+
}
52+
}
53+
}
54+
}

armometadata/testdata/testdeployment.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"annotations": {
66
"deployment.kubernetes.io/revision": "1"
77
},
8+
"labels": {
9+
"label-key-1": "label-value-1"
10+
},
811
"creationTimestamp": "2024-07-18T19:58:44Z",
912
"generation": 1,
1013
"name": "emailservice",
@@ -32,7 +35,8 @@
3235
"metadata": {
3336
"creationTimestamp": null,
3437
"labels": {
35-
"app": "emailservice"
38+
"app": "emailservice",
39+
"pod_label_key": "pod_label_value"
3640
}
3741
},
3842
"spec": {

0 commit comments

Comments
 (0)