From 57408d87e437acf36eb05f58e834be08d6559bd6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 07:07:47 +0000 Subject: [PATCH] Add support for ephemeralContainers Collect images from podSpec.EphemeralContainers alongside Containers and InitContainers in GetContainersFromObject. EphemeralContainerCommon is a direct type definition of Container, so each entry converts cleanly without copying fields. Add unit coverage in the k8s and yamlparser packages. For the end-to-end approval layer, fold ephemeralContainers into the existing Pod fixture (the only kind where they are valid, since they are injected into a live Pod via the ephemeralcontainers subresource rather than declared in a workload template), ordered regular -> init -> ephemeral. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013YcWYpbf4mF49SYnbkf28b --- approvals/kir_test.TestKind.Pod.approved.txt | 3 +- approvals/kir_test.TestKind.Pod.input.yaml | 4 +++ k8s/k8s.go | 3 ++ k8s/k8s_test.go | 27 +++++++++++++++ yamlparser/yamlparser_test.go | 36 ++++++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/approvals/kir_test.TestKind.Pod.approved.txt b/approvals/kir_test.TestKind.Pod.approved.txt index 75341eb..297602f 100644 --- a/approvals/kir_test.TestKind.Pod.approved.txt +++ b/approvals/kir_test.TestKind.Pod.approved.txt @@ -1,2 +1,3 @@ nginx -gcr.io/google-containers/sidecar \ No newline at end of file +gcr.io/google-containers/sidecar +busybox:1.28 \ No newline at end of file diff --git a/approvals/kir_test.TestKind.Pod.input.yaml b/approvals/kir_test.TestKind.Pod.input.yaml index 5887cd7..47766bc 100644 --- a/approvals/kir_test.TestKind.Pod.input.yaml +++ b/approvals/kir_test.TestKind.Pod.input.yaml @@ -12,3 +12,7 @@ spec: - name: init-mysidecar image: gcr.io/google-containers/sidecar restartPolicy: Always + ephemeralContainers: + - name: debugger + image: busybox:1.28 + targetContainerName: myapp diff --git a/k8s/k8s.go b/k8s/k8s.go index be14271..52c4566 100644 --- a/k8s/k8s.go +++ b/k8s/k8s.go @@ -47,5 +47,8 @@ func GetContainersFromObject(obj interface{}) ([]corev1.Container, error) { var containers []corev1.Container containers = append(containers, podSpec.Containers...) containers = append(containers, podSpec.InitContainers...) + for _, ec := range podSpec.EphemeralContainers { + containers = append(containers, corev1.Container(ec.EphemeralContainerCommon)) + } return containers, nil } diff --git a/k8s/k8s_test.go b/k8s/k8s_test.go index b37c09d..90e1885 100644 --- a/k8s/k8s_test.go +++ b/k8s/k8s_test.go @@ -220,6 +220,33 @@ func TestGetContainersFromObject(t *testing.T) { }, wantErr: false, }, + { + name: "Pod with ephemeral container", + obj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Name: "container1", Image: "image1"}, + }, + InitContainers: []corev1.Container{ + {Name: "init-container1", Image: "init-image1"}, + }, + EphemeralContainers: []corev1.EphemeralContainer{ + { + EphemeralContainerCommon: corev1.EphemeralContainerCommon{ + Name: "debugger", + Image: "ephemeral-image1", + }, + }, + }, + }, + }, + want: []corev1.Container{ + {Name: "container1", Image: "image1"}, + {Name: "init-container1", Image: "init-image1"}, + {Name: "debugger", Image: "ephemeral-image1"}, + }, + wantErr: false, + }, { name: "Invalid", obj: "invalid", diff --git a/yamlparser/yamlparser_test.go b/yamlparser/yamlparser_test.go index f388c07..aa11435 100644 --- a/yamlparser/yamlparser_test.go +++ b/yamlparser/yamlparser_test.go @@ -32,3 +32,39 @@ spec: } } } + +func TestProcessDataEphemeralContainers(t *testing.T) { + data := ` +apiVersion: v1 +kind: Pod +metadata: + name: test-pod +spec: + containers: + - name: test-container + image: test-image + initContainers: + - name: init-container + image: init-image + ephemeralContainers: + - name: debugger + image: ephemeral-image + targetContainerName: test-container +` + + images, err := ProcessData([]byte(data)) + if err != nil { + t.Fatalf("ProcessData() error = %v", err) + } + + expected := []string{"test-image", "init-image", "ephemeral-image"} + if len(images) != len(expected) { + t.Fatalf("expected %d images, got %d: %v", len(expected), len(images), images) + } + + for i, img := range images { + if img != expected[i] { + t.Errorf("expected image %q, got %q", expected[i], img) + } + } +}