Skip to content

Commit d2dbde2

Browse files
committed
Add util to determine whether an image is built by Red Hat
Based on registry and remote heuristics. This will be used in upcoming changes to keep the optimization at [1] working even when a signature is present by default: If only 1 signature integration exists, and that is the built-in red hat signature integration, and the image is a red hat image, download the signature. Otherwise skip. [1] https://github.com/stackrox/stackrox/blob/e3180cf49b7e79c31640af08ea571edfc7ffdd28/pkg/images/enricher/enricher_impl.go#L712
1 parent 26ab368 commit d2dbde2

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

pkg/images/utils/utils.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,29 @@ func FilterSuppressedCVEsNoClone(img *storage.Image) {
264264
}
265265
}
266266
}
267+
268+
func IsRedHatImage(img *storage.Image) bool {
269+
// First consider registries where all images are built by Red Hat
270+
imageRegistry := img.GetName().GetRegistry()
271+
redHatRegistries := set.NewStringSet(
272+
"registry.access.redhat.com",
273+
"registry.redhat.io",
274+
)
275+
if redHatRegistries.Contains(imageRegistry) {
276+
return true
277+
}
278+
279+
// The only remaining possibility is quay.io, where certain remotes are all Red Hat
280+
if imageRegistry != "quay.io" {
281+
return false
282+
}
283+
284+
quayIoRedHatRemotes := set.NewStringSet(
285+
"openshift-release-dev/ocp-release",
286+
"openshift-release-dev/ocp-v4.0-art-dev",
287+
)
288+
if quayIoRedHatRemotes.Contains(img.GetName().GetRemote()) {
289+
return true
290+
}
291+
return false
292+
}

pkg/images/utils/utils_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,66 @@ func TestNormalizeImageFullName(t *testing.T) {
283283
})
284284
}
285285
}
286+
287+
func TestIsRedHatImage(t *testing.T) {
288+
tcs := []struct {
289+
name string
290+
imagesStr []string
291+
want bool
292+
}{
293+
{
294+
"images in registries assumed contain all-redhat images are classified as Red Hat images",
295+
[]string{
296+
"registry.redhat.io/openshift4/ose-csi-external-provisioner@sha256:395a5a4aa4cfe3a0093d2225ce2e67acdcec0fd894e4b61e30a750f22931448d",
297+
"registry.access.redhat.com/ubi8/openjdk-21@sha256:441897a1f691c7d4b3a67bb3e0fea83e18352214264cb383fd057bbbd5ed863c",
298+
},
299+
true,
300+
},
301+
{
302+
"images in Red Hat registries that contain third party images are not classified as Red Hat images",
303+
[]string{
304+
"registry.connect.redhat.com/nvidia-network-operator/nvidia-network-operator@sha256:2418015d00846dd0d7a8aca11927f1e89b4d8d525e6ae936360e3e3b3bd9e22f",
305+
"registry.marketplace.redhat.com/rhm/seldonio/alibi-detect-server@sha256:4b0edf72477f54bdcb850457582f12bcb1338ca64dc94ebca056897402708306",
306+
},
307+
false,
308+
},
309+
{
310+
"images in quay.io remotes that are known to contain all-redhat images are classified as Red Hat images",
311+
[]string{
312+
"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:c896b5d4b05343dfe94c0f75c9232a2a68044d0fa7a21b5f51ed796d23f1fcc5",
313+
"quay.io/openshift-release-dev/ocp-release@sha256:3482dbdce3a6fb2239684d217bba6fc87453eff3bdb72f5237be4beb22a2160b",
314+
},
315+
true,
316+
},
317+
{
318+
"images in quay.io remotes that contain third-party images are not classified as Red Hat images",
319+
[]string{
320+
"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:c896b5d4b05343dfe94c0f75c9232a2a68044d0fa7a21b5f51ed796d23f1fcc5",
321+
"quay.io/openshift-release-dev/ocp-release@sha256:3482dbdce3a6fb2239684d217bba6fc87453eff3bdb72f5237be4beb22a2160b",
322+
},
323+
true,
324+
},
325+
{
326+
"images outside quay.io with quay-io Red Hat-specific remotes are not classified as Red Hat images",
327+
[]string{
328+
"not-quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:c896b5d4b05343dfe94c0f75c9232a2a68044d0fa7a21b5f51ed796d23f1fcc5",
329+
"not-quay.io/openshift-release-dev/ocp-release@sha256:3482dbdce3a6fb2239684d217bba6fc87453eff3bdb72f5237be4beb22a2160b",
330+
},
331+
false,
332+
},
333+
//TODO
334+
// - special cases of missing registry, missing "name", etc
335+
}
336+
337+
for _, tc := range tcs {
338+
t.Run(tc.name, func(t *testing.T) {
339+
for _, imageStr := range tc.imagesStr {
340+
imgName, _, err := GenerateImageNameFromString(imageStr)
341+
assert.NoError(t, err)
342+
img := &storage.Image{Name: imgName}
343+
got := IsRedHatImage(img)
344+
assert.Equal(t, tc.want, got)
345+
}
346+
})
347+
}
348+
}

0 commit comments

Comments
 (0)