Repository: redhat-openshift-ecosystem/openshift-preflight
Pull request #755 (2022-08-05 18:09:52)

Fix bugs in new checks
This PR contains two fixes.

1. Adding the RelatedImages check to the operator policy.
2. Fix the logic in the Certified Images check, so that if an image is not found in Pyxis, it's marked as uncertified.

openshift-ci[bot]: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#" title="Author self-approved">bcrochet</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-openshift-ecosystem%2Fopenshift-preflight).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-openshift-ecosystem/openshift-preflight/blob/main/OWNERS)~~ [bcrochet]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
coveralls: 
[![Coverage Status](https://coveralls.io/builds/51457997/badge)](https://coveralls.io/builds/51457997)

Coverage increased (+0.04%) to 84.008% when pulling **1aa9cba6b32926e7de933cca16d58fd2659ac954 on bcrochet:new-checks** into **244445d894e3a35d8fe5b3c6cb396f5b5a34e457 on redhat-openshift-ecosystem:main**.

dcibot: -  SUCCESS https://www.distributed-ci.io/jobs/7f0dd478-93e8-4d97-8ea3-0508098bb58c/jobStates
 from https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755
openshift-ci[bot]: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1063886283" title="Approved">acornett21</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#" title="Author self-approved">bcrochet</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-openshift-ecosystem%2Fopenshift-preflight).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-openshift-ecosystem/openshift-preflight/blob/main/OWNERS)~~ [acornett21,bcrochet]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-ci[bot]: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1063886283" title="Approved">acornett21</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#" title="Author self-approved">bcrochet</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1065241136" title="Approved">jomkz</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-openshift-ecosystem%2Fopenshift-preflight).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-openshift-ecosystem/openshift-preflight/blob/main/OWNERS)~~ [acornett21,bcrochet,jomkz]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-ci[bot]: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1063886283" title="Approved">acornett21</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#" title="Author self-approved">bcrochet</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1065241136" title="Approved">jomkz</a>*, *<a href="https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/755#pullrequestreview-1065345523" title="LGTM">komish</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-openshift-ecosystem%2Fopenshift-preflight).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-openshift-ecosystem/openshift-preflight/blob/main/OWNERS)~~ [acornett21,bcrochet,jomkz,komish]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/certification/engine/engine.go b/certification/engine/engine.go
index 87ff1be..2298ec4 100644
--- a/certification/engine/engine.go
+++ b/certification/engine/engine.go
@@ -63,6 +63,7 @@ func initializeChecks(ctx context.Context, p policy.Policy, cfg certification.Co
 				&http.Client{Timeout: 60 * time.Second}),
 			),
 			operatorpol.NewSecurityContextConstraintsCheck(),
+			&operatorpol.RelatedImagesCheck{},
 		}, nil
 	case policy.PolicyContainer:
 		return []certification.Check{
diff --git a/certification/internal/policy/operator/certified_images.go b/certification/internal/policy/operator/certified_images.go
index 49d7c9a..ab86a9c 100644
--- a/certification/internal/policy/operator/certified_images.go
+++ b/certification/internal/policy/operator/certified_images.go
@@ -73,7 +73,18 @@ func (p *certifiedImagesCheck) validate(ctx context.Context, imageDigests []stri
 		return false, err
 	}
 
+	foundMap := make(map[string]pyxis.CertImage, len(pyxisImages))
 	for _, img := range pyxisImages {
+		foundMap[img.DockerImageDigest] = img
+	}
+
+	for _, digest := range imageDigests {
+		img, ok := foundMap[digest]
+		if !ok {
+			log.Warningf("Image not found in Pyxis, therefore it is not certified: %s", digest)
+			p.nonCertifiedImages = append(p.nonCertifiedImages, digest)
+			continue
+		}
 		if !img.Certified {
 			fullImg := fmt.Sprintf("%s/%s@%s", img.Repositories[0].Registry, img.Repositories[0].Repository, img.DockerImageDigest)
 			log.Warningf("Image is not certified: %s", fullImg)


Test patch:
diff --git a/certification/internal/policy/operator/certified_images_test.go b/certification/internal/policy/operator/certified_images_test.go
index e5b6d56..4e694af 100644
--- a/certification/internal/policy/operator/certified_images_test.go
+++ b/certification/internal/policy/operator/certified_images_test.go
@@ -26,6 +26,16 @@ func (c *certifiedImageFinder) FindImagesByDigest(ctx context.Context, digests [
 		},
 		DockerImageDigest: "sha256:f000432f07cd187469f0310e3ed9dcf9a5db2be14b8bab9c5293dd1ee8518176",
 	})
+	matchingImages = append(matchingImages, pyxis.CertImage{
+		Certified: true,
+		Repositories: []pyxis.Repository{
+			{
+				Registry:   "registry.example.io",
+				Repository: "foo/proxy",
+			},
+		},
+		DockerImageDigest: "sha256:5e33f9d095952866b9743cc8268fb740cce6d93439f00ce333a2de1e5974837e",
+	})
 	return matchingImages, nil
 }
 
@@ -43,6 +53,33 @@ func (c *uncertifiedImageFinder) FindImagesByDigest(ctx context.Context, digests
 		},
 		DockerImageDigest: "sha256:f000432f07cd187469f0310e3ed9dcf9a5db2be14b8bab9c5293dd1ee8518176",
 	})
+	matchingImages = append(matchingImages, pyxis.CertImage{
+		Certified: true,
+		Repositories: []pyxis.Repository{
+			{
+				Registry:   "registry.example.io",
+				Repository: "foo/proxy",
+			},
+		},
+		DockerImageDigest: "sha256:5e33f9d095952866b9743cc8268fb740cce6d93439f00ce333a2de1e5974837e",
+	})
+	return matchingImages, nil
+}
+
+type missingImageFinder struct{}
+
+func (c *missingImageFinder) FindImagesByDigest(ctx context.Context, digests []string) ([]pyxis.CertImage, error) {
+	var matchingImages []pyxis.CertImage
+	matchingImages = append(matchingImages, pyxis.CertImage{
+		Certified: true,
+		Repositories: []pyxis.Repository{
+			{
+				Registry:   "registry.example.io",
+				Repository: "foo/bar",
+			},
+		},
+		DockerImageDigest: "sha256:f000432f07cd187469f0310e3ed9dcf9a5db2be14b8bab9c5293dd1ee8518176",
+	})
 	return matchingImages, nil
 }
 
@@ -113,6 +150,18 @@ spec:
 			Expect(certifiedImagesCheck.nonCertifiedImages).To(HaveLen(1))
 		})
 	})
+	When("an image in the CSV is not in Pyxis", func() {
+		AfterEach(func() {
+			certifiedImagesCheck.imageFinder = &certifiedImageFinder{}
+		})
+		It("should still succeed", func() {
+			certifiedImagesCheck.imageFinder = &missingImageFinder{}
+			result, err := certifiedImagesCheck.Validate(context.TODO(), imageRef)
+			Expect(err).ToNot(HaveOccurred())
+			Expect(result).To(BeTrue())
+			Expect(certifiedImagesCheck.nonCertifiedImages).To(HaveLen(1))
+		})
+	})
 	When("there is no CSV", func() {
 		It("should fail", func() {
 			Expect(os.RemoveAll(imageRef.ImageFSPath)).To(Succeed())