From 93c183f73dff4d507cbe28a71109ac55fb161559 Mon Sep 17 00:00:00 2001 From: Erik Godding Boye Date: Wed, 18 Jan 2023 16:23:22 +0100 Subject: [PATCH] fix: obtain image tags from pod container spec (#86) --- internal/controller/stas/suite_test.go | 1 + internal/controller/stas/types.go | 38 +++++- internal/controller/stas/types_test.go | 117 +++++++++++++++--- .../controller/stas/workload_controller.go | 17 --- 4 files changed, 131 insertions(+), 42 deletions(-) diff --git a/internal/controller/stas/suite_test.go b/internal/controller/stas/suite_test.go index 7c752e90..cae952c1 100644 --- a/internal/controller/stas/suite_test.go +++ b/internal/controller/stas/suite_test.go @@ -174,6 +174,7 @@ func newPod(owner client.Object, s *runtime.Scheme) *corev1.Pod { } p.Status.ContainerStatuses = []corev1.ContainerStatus{ { + Name: "foo", Image: "my.registry/repository/app:f54a333e", ImageID: "my.registry/repository/app@sha256:4b59f7dacd37c688968756d176139715df69d89eb0be1802e059316f9d58d9ef", }, diff --git a/internal/controller/stas/types.go b/internal/controller/stas/types.go index 2b6addef..e37020c4 100644 --- a/internal/controller/stas/types.go +++ b/internal/controller/stas/types.go @@ -37,11 +37,39 @@ func newImageFromContainerStatus(containerStatus corev1.ContainerStatus) (podCon image.Digest = ref.Digest() } - if ref, ok := idRef.(reference.Tagged); ok { - image.Tag = ref.Tag() - } else if ref, ok := nameRef.(reference.Tagged); ok { - image.Tag = ref.Tag() + return image, nil +} + +func containerImages(pod *corev1.Pod) (map[string]*podContainerImage, error) { + images := make(map[string]*podContainerImage) + + for _, containerStatus := range pod.Status.ContainerStatuses { + if containerStatus.Image != "" && containerStatus.ImageID != "" { + image, err := newImageFromContainerStatus(containerStatus) + if err != nil { + return nil, err + } + + images[containerStatus.Name] = &image + } } - return image, nil + for _, container := range pod.Spec.Containers { + image, ok := images[container.Name] + if !ok { + // We only want to add tag to images that are resolved by CRI + continue + } + + ref, err := reference.ParseAnyReference(container.Image) + if err != nil { + return nil, err + } + + if taggedRef, ok := ref.(reference.Tagged); ok { + image.Tag = taggedRef.Tag() + } + } + + return images, nil } diff --git a/internal/controller/stas/types_test.go b/internal/controller/stas/types_test.go index abb747d9..3b3ee94a 100644 --- a/internal/controller/stas/types_test.go +++ b/internal/controller/stas/types_test.go @@ -9,16 +9,34 @@ import ( ) var _ = Describe("ImageReference", func() { - DescribeTable("Creating from container status", - func(containerStatus corev1.ContainerStatus, expectedImage podContainerImage) { - actualImage, err := newImageFromContainerStatus(containerStatus) + DescribeTable("Creating from pod", + func(pod *corev1.Pod, expectedImage podContainerImage) { + images, err := containerImages(pod) Expect(err).To(Succeed()) - Expect(actualImage).To(Equal(expectedImage)) + Expect(images).To(HaveLen(1)) + for _, image := range images { + Expect(*image).To(Equal(expectedImage)) + } }, Entry("Standard FQ image", - corev1.ContainerStatus{ - Image: "my.registry/repository/app:f54a333e", - ImageID: "my.registry/repository/app@sha256:4b59f7dacd37c688968756d176139715df69d89eb0be1802e059316f9d58d9ef", + &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "standard-fq", + Image: "my.registry/repository/app:f54a333e", + }, + }, + }, + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: "standard-fq", + Image: "my.registry/repository/app:f54a333e", + ImageID: "my.registry/repository/app@sha256:4b59f7dacd37c688968756d176139715df69d89eb0be1802e059316f9d58d9ef", + }, + }, + }, }, podContainerImage{ Image: stasv1alpha1.Image{ @@ -28,9 +46,24 @@ var _ = Describe("ImageReference", func() { Tag: "f54a333e", }), Entry("Standard digested image", - corev1.ContainerStatus{ - Image: "stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", - ImageID: "docker.io/stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "standard-digested", + Image: "stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + }, + }, + }, + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: "standard-digested", + Image: "stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + ImageID: "docker.io/stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + }, + }, + }, }, podContainerImage{ Image: stasv1alpha1.Image{ @@ -39,9 +72,24 @@ var _ = Describe("ImageReference", func() { }, }), Entry("Standard digested image in k3s", - corev1.ContainerStatus{ - Image: "sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", - ImageID: "docker.io/stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "ks3-digested", + Image: "stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + }, + }, + }, + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: "ks3-digested", + Image: "sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + ImageID: "docker.io/stas/echo-server@sha256:793485b42b5c6d97ab10f8cea08467b77711b865e4512aae6a7e70a38145469e", + }, + }, + }, }, podContainerImage{ Image: stasv1alpha1.Image{ @@ -50,9 +98,24 @@ var _ = Describe("ImageReference", func() { }, }), Entry("Image imported into k3s", - corev1.ContainerStatus{ - Image: "docker.io/application-operator/controller:latest", - ImageID: "sha256:f991b3a7a93c5c0070dde555a1542d5a34508f16e52eced9237f0967e28ddaff", + &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "ks3-imported", + Image: "application-operator/controller:latest", + }, + }, + }, + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: "ks3-imported", + Image: "docker.io/application-operator/controller:latest", + ImageID: "sha256:f991b3a7a93c5c0070dde555a1542d5a34508f16e52eced9237f0967e28ddaff", + }, + }, + }, }, podContainerImage{ Image: stasv1alpha1.Image{ @@ -62,16 +125,30 @@ var _ = Describe("ImageReference", func() { Tag: "latest", }), Entry("Untagged Docker Hub image on corporate OCP", - corev1.ContainerStatus{ - Image: "dummy.registry.mycorp.com/mysql:latest", - ImageID: "dummy.registry.mycorp.com/mysql@sha256:83469837189400492f32d23cadbfc97fae3dc019871337a841609f0b71a34907", + &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "ocp-corp", + Image: "mysql", + }, + }, + }, + Status: corev1.PodStatus{ + ContainerStatuses: []corev1.ContainerStatus{ + { + Name: "ocp-corp", + Image: "dummy.registry.mycorp.com/mysql:latest", + ImageID: "dummy.registry.mycorp.com/mysql@sha256:83469837189400492f32d23cadbfc97fae3dc019871337a841609f0b71a34907", + }, + }, + }, }, podContainerImage{ Image: stasv1alpha1.Image{ Name: "dummy.registry.mycorp.com/mysql", Digest: "sha256:83469837189400492f32d23cadbfc97fae3dc019871337a841609f0b71a34907", }, - Tag: "latest", }), ) }) diff --git a/internal/controller/stas/workload_controller.go b/internal/controller/stas/workload_controller.go index e9c5cb9d..41d112d0 100644 --- a/internal/controller/stas/workload_controller.go +++ b/internal/controller/stas/workload_controller.go @@ -216,23 +216,6 @@ func (r *PodReconciler) getImageScansOwnedByPodContainer(ctx context.Context, po return CISes, nil } -func containerImages(pod *corev1.Pod) (map[string]podContainerImage, error) { - images := make(map[string]podContainerImage) - - for _, containerStatus := range pod.Status.ContainerStatuses { - if containerStatus.Image != "" && containerStatus.ImageID != "" { - image, err := newImageFromContainerStatus(containerStatus) - if err != nil { - return nil, err - } - - images[containerStatus.Name] = image - } - } - - return images, nil -} - func imageScanName(podController client.Object, containerName string, image stasv1alpha1.Image) string { kindPart := strings.ToLower(podController.GetObjectKind().GroupVersionKind().Kind) imagePart := hash.NewString(image.Name, image.Digest)[0:ImageShortSHALength]