From 5bf7e018525452146ef526dc9e9fdec8b204684e Mon Sep 17 00:00:00 2001 From: Brandt Keller <43887158+brandtkeller@users.noreply.github.com> Date: Fri, 17 May 2024 10:13:48 -0700 Subject: [PATCH] fix(agent): missing path for pod without labels (#2518) ## Description identify when a pod has no labels (and thus has no `/metadata/labels` for jsonpatch replace operations. use the `add` jsonpath operation to add the labels path with the map[string]string value of `{"zarf-agent": "patched"}` ## Related Issue Fixes #2517 ## Testing Deploy a pod without labels to test: ``` apiVersion: v1 kind: Pod metadata: creationTimestamp: null name: test namespace: test spec: containers: - image: nginx name: test resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} ``` ## Checklist before merging - [x] Test, docs, adr added or updated as needed - [x] [Contributor Guide Steps](https://github.com/defenseunicorns/zarf/blob/main/.github/CONTRIBUTING.md#developer-workflow) followed --- src/internal/agent/hooks/pods.go | 10 +++++- src/test/e2e/37_pod_without_labels_test.go | 35 +++++++++++++++++++ .../packages/37-pod-without-labels/pod.yaml | 13 +++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/test/e2e/37_pod_without_labels_test.go create mode 100644 src/test/packages/37-pod-without-labels/pod.yaml diff --git a/src/internal/agent/hooks/pods.go b/src/internal/agent/hooks/pods.go index 2e90709bfd..a7b6911991 100644 --- a/src/internal/agent/hooks/pods.go +++ b/src/internal/agent/hooks/pods.go @@ -99,7 +99,15 @@ func mutatePod(r *v1.AdmissionRequest) (*operations.Result, error) { } // Add a label noting the zarf mutation - patchOperations = append(patchOperations, operations.ReplacePatchOperation("/metadata/labels/zarf-agent", "patched")) + if pod.Labels == nil { + // If the labels path does not exist - create with map[string]string value + patchOperations = append(patchOperations, operations.AddPatchOperation("/metadata/labels", + map[string]string{ + "zarf-agent": "patched", + })) + } else { + patchOperations = append(patchOperations, operations.ReplacePatchOperation("/metadata/labels/zarf-agent", "patched")) + } return &operations.Result{ Allowed: true, diff --git a/src/test/e2e/37_pod_without_labels_test.go b/src/test/e2e/37_pod_without_labels_test.go new file mode 100644 index 0000000000..4d249dd3ee --- /dev/null +++ b/src/test/e2e/37_pod_without_labels_test.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package test provides e2e tests for Zarf. +package test + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPodWithoutLabels(t *testing.T) { + t.Log("E2E: Pod Without Labels") + e2e.SetupWithCluster(t) + + // Path to pod manifest containing 0 lavbels + buildPath := filepath.Join("src", "test", "packages", "37-pod-without-labels", "pod.yaml") + + // Create the testing namespace + _, _, err := e2e.Kubectl("create", "ns", "pod-label") + require.NoError(t, err) + + // Create the pod without labels + // This is not an image zarf will have in the registry - but the agent was failing to admit on an internal server error before completing admission + _, _, err = e2e.Kubectl("create", "-f", buildPath, "-n", "pod-label") + require.NoError(t, err) + + // Cleanup + _, _, err = e2e.Kubectl("delete", "-f", buildPath, "-n", "pod-label") + require.NoError(t, err) + _, _, err = e2e.Kubectl("delete", "ns", "pod-label") + require.NoError(t, err) +} diff --git a/src/test/packages/37-pod-without-labels/pod.yaml b/src/test/packages/37-pod-without-labels/pod.yaml new file mode 100644 index 0000000000..a1ea2ac32b --- /dev/null +++ b/src/test/packages/37-pod-without-labels/pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: null + name: test +spec: + containers: + - image: nginx + name: test + resources: {} + dnsPolicy: ClusterFirst + restartPolicy: Always +status: {} \ No newline at end of file