From 44dae4a9dd6da96ed56d1fbd163f5c0ff81d5c89 Mon Sep 17 00:00:00 2001 From: Cortney Reed Date: Tue, 31 Mar 2026 10:27:18 -0400 Subject: [PATCH] Add pattern validation for registry entries in image config Invalid registry entries (e.g., with tags like ":latest" or digests like "@sha256:...") in registrySources fields generate an invalid /etc/containers/policy.json, which can cause container runtime failures. Add per-item Pattern validation to insecureRegistries, blockedRegistries, and allowedRegistries fields in the RegistrySources struct using the same regex pattern already used by ImageDigestMirrors.Source. Each entry must match a valid registry scope: hostname[:port][/path], optionally with a wildcard prefix (*.). CRD validation ratcheting ensures pre-existing invalid entries are preserved on update. Includes integration tests demonstrating: - Invalid tagged/digest entries are rejected on create - Valid entries (hostname, path, wildcard, port) are accepted - Ratcheting preserves persisted invalid entries when other fields change - Modifying an atomic list with a persisted invalid entry is rejected Co-Authored-By: Claude Opus 4.6 --- .../AAA_ungated.yaml | 202 ++++++++++++++++++ config/v1/types_image.go | 18 ++ ...0000_10_config-operator_01_images.crd.yaml | 22 +- .../AAA_ungated.yaml | 22 +- .../ImageStreamImportMode.yaml | 22 +- .../v1/zz_generated.swagger_doc_generated.go | 6 +- .../generated_openapi/zz_generated.openapi.go | 6 +- ...0000_10_config-operator_01_images.crd.yaml | 22 +- 8 files changed, 306 insertions(+), 14 deletions(-) diff --git a/config/v1/tests/images.config.openshift.io/AAA_ungated.yaml b/config/v1/tests/images.config.openshift.io/AAA_ungated.yaml index 6d25c018955..1cb754ae64a 100644 --- a/config/v1/tests/images.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/tests/images.config.openshift.io/AAA_ungated.yaml @@ -12,6 +12,102 @@ tests: apiVersion: config.openshift.io/v1 kind: Image spec: {} + - name: Should not allow creating an Image with a tagged registry entry in blockedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + expectedError: "spec.registrySources.blockedRegistries[0]" + - name: Should not allow creating an Image with a tagged registry entry in allowedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: ["registry.io/myrepo:latest"] + expectedError: "spec.registrySources.allowedRegistries[0]" + - name: Should not allow creating an Image with a tagged registry entry in insecureRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + insecureRegistries: ["registry.io/myrepo:latest"] + expectedError: "spec.registrySources.insecureRegistries[0]" + - name: Should not allow creating an Image with a digest registry entry in blockedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo@sha256:abc123"] + expectedError: "spec.registrySources.blockedRegistries[0]" + - name: Should not allow creating an Image with a digest registry entry in allowedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: ["registry.io/myrepo@sha256:abc123"] + expectedError: "spec.registrySources.allowedRegistries[0]" + - name: Should not allow creating an Image with a digest registry entry in insecureRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + insecureRegistries: ["registry.io/myrepo@sha256:abc123"] + expectedError: "spec.registrySources.insecureRegistries[0]" + - name: Should allow creating an Image with valid registry entries in blockedRegistries and insecureRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: + - "registry.io" + - "registry.io/myrepo" + - "*.example.com" + - "localhost:5000/repo" + insecureRegistries: + - "insecure.registry.io" + - "*.insecure.example.com" + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: + - "registry.io" + - "registry.io/myrepo" + - "*.example.com" + - "localhost:5000/repo" + insecureRegistries: + - "insecure.registry.io" + - "*.insecure.example.com" + - name: Should allow creating an Image with valid registry entries in allowedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: + - "registry.io" + - "registry.io/myrepo" + - "*.example.com" + - "localhost:5000/repo" + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: + - "registry.io" + - "registry.io/myrepo" + - "*.example.com" + - "localhost:5000/repo" onUpdate: - name: Should allow updating other fields with an invalid persisted registrySources in spec initialCRDPatches: @@ -114,3 +210,109 @@ tests: allowedRegistries: ["test"] blockedRegistries: ["test"] expectedError: 'Only one of blockedRegistries or allowedRegistries may be set' + - name: Should allow updating other fields when an invalid tagged blockedRegistries entry is persisted + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/blockedRegistries/items/pattern + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + - name: Should allow updating other fields when an invalid tagged allowedRegistries entry is persisted + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/allowedRegistries/items/pattern + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: ["registry.io/myrepo:latest"] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + allowedRegistries: ["registry.io/myrepo:latest"] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + allowedRegistries: ["registry.io/myrepo:latest"] + - name: Should allow updating other fields when an invalid tagged insecureRegistries entry is persisted + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/insecureRegistries/items/pattern + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + insecureRegistries: ["registry.io/myrepo:latest"] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + insecureRegistries: ["registry.io/myrepo:latest"] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + insecureRegistries: ["registry.io/myrepo:latest"] + - name: Should not allow adding a new invalid tagged entry to blockedRegistries even when an invalid entry is already persisted + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/blockedRegistries/items/pattern + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest", "other.com/repo:v1"] + expectedError: "spec.registrySources.blockedRegistries" + - name: Should not allow appending to blockedRegistries when an invalid entry is already persisted because listType atomic re-validates the whole list + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/blockedRegistries/items/pattern + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest"] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: ["registry.io/myrepo:latest", "valid.registry.io"] + expectedError: "spec.registrySources.blockedRegistries" diff --git a/config/v1/types_image.go b/config/v1/types_image.go index 82f46c8b6c9..28a9bc0e583 100644 --- a/config/v1/types_image.go +++ b/config/v1/types_image.go @@ -165,20 +165,38 @@ type RegistryLocation struct { // +kubebuilder:validation:XValidation:rule="has(self.blockedRegistries) ? !has(self.allowedRegistries) : true",message="Only one of blockedRegistries or allowedRegistries may be set" type RegistrySources struct { // insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. + // Each entry must be a valid registry scope in the format hostname[:port][/path], + // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + // The hostname must consist of valid DNS labels separated by dots, where each label + // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + // Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). // +optional // +listType=atomic + // +kubebuilder:validation:items:Pattern=`^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$` InsecureRegistries []string `json:"insecureRegistries,omitempty"` // blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. + // Each entry must be a valid registry scope in the format hostname[:port][/path], + // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + // The hostname must consist of valid DNS labels separated by dots, where each label + // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + // Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic + // +kubebuilder:validation:items:Pattern=`^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$` BlockedRegistries []string `json:"blockedRegistries,omitempty"` // allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. + // Each entry must be a valid registry scope in the format hostname[:port][/path], + // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + // The hostname must consist of valid DNS labels separated by dots, where each label + // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + // Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic + // +kubebuilder:validation:items:Pattern=`^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$` AllowedRegistries []string `json:"allowedRegistries,omitempty"` // containerRuntimeSearchRegistries are registries that will be searched when pulling images that do not have fully qualified // domains in their pull specs. Registries will be searched in the order provided in the list. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml index 52ea2a9a579..9c136080028 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml @@ -129,18 +129,30 @@ spec: allowedRegistries: description: |- allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic blockedRegistries: description: |- blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic @@ -156,9 +168,15 @@ spec: type: array x-kubernetes-list-type: set insecureRegistries: - description: insecureRegistries are registries which do not have - a valid TLS certificates or only support HTTP connections. + description: |- + insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic diff --git a/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml b/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml index 9358a303939..ec555cfa64d 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml @@ -112,18 +112,30 @@ spec: allowedRegistries: description: |- allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic blockedRegistries: description: |- blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic @@ -139,9 +151,15 @@ spec: type: array x-kubernetes-list-type: set insecureRegistries: - description: insecureRegistries are registries which do not have - a valid TLS certificates or only support HTTP connections. + description: |- + insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic diff --git a/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml b/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml index 1fd6a9afee3..fbd8cda5fe3 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml @@ -130,18 +130,30 @@ spec: allowedRegistries: description: |- allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic blockedRegistries: description: |- blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic @@ -157,9 +169,15 @@ spec: type: array x-kubernetes-list-type: set insecureRegistries: - description: insecureRegistries are registries which do not have - a valid TLS certificates or only support HTTP connections. + description: |- + insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 4a5346dba88..ad91591a6fc 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1165,9 +1165,9 @@ func (RegistryLocation) SwaggerDoc() map[string]string { var map_RegistrySources = map[string]string{ "": "RegistrySources holds cluster-wide information about how to handle the registries config.", - "insecureRegistries": "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections.", - "blockedRegistries": "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", - "allowedRegistries": "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + "insecureRegistries": "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").", + "blockedRegistries": "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + "allowedRegistries": "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", "containerRuntimeSearchRegistries": "containerRuntimeSearchRegistries are registries that will be searched when pulling images that do not have fully qualified domains in their pull specs. Registries will be searched in the order provided in the list. Note: this search list only works with the container runtime, i.e CRI-O. Will NOT work with builds or imagestream imports.", } diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 967c191d6be..25666922ea6 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -20072,7 +20072,7 @@ func schema_openshift_api_config_v1_RegistrySources(ref common.ReferenceCallback }, }, SchemaProps: spec.SchemaProps{ - Description: "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections.", + Description: "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -20092,7 +20092,7 @@ func schema_openshift_api_config_v1_RegistrySources(ref common.ReferenceCallback }, }, SchemaProps: spec.SchemaProps{ - Description: "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + Description: "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -20112,7 +20112,7 @@ func schema_openshift_api_config_v1_RegistrySources(ref common.ReferenceCallback }, }, SchemaProps: spec.SchemaProps{ - Description: "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + Description: "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\").\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml index 52ea2a9a579..9c136080028 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml @@ -129,18 +129,30 @@ spec: allowedRegistries: description: |- allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic blockedRegistries: description: |- blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). Only one of BlockedRegistries or AllowedRegistries may be set. items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic @@ -156,9 +168,15 @@ spec: type: array x-kubernetes-list-type: set insecureRegistries: - description: insecureRegistries are registries which do not have - a valid TLS certificates or only support HTTP connections. + description: |- + insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. + Each entry must be a valid registry scope in the format hostname[:port][/path], + optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). + The hostname must consist of valid DNS labels separated by dots, where each label + contains only alphanumeric characters and hyphens and does not start or end with a hyphen. + Entries must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."). items: + pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$ type: string type: array x-kubernetes-list-type: atomic