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..96c5d287487 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,126 @@ 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 not allow creating an Image with an empty string in blockedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: [""] + expectedError: "spec.registrySources.blockedRegistries[0]" + - name: Should not allow creating an Image with an empty string in allowedRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: [""] + expectedError: "spec.registrySources.allowedRegistries[0]" + - name: Should not allow creating an Image with an empty string in insecureRegistries + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + insecureRegistries: [""] + 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 +234,187 @@ 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/x-kubernetes-validations + 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/x-kubernetes-validations + 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/x-kubernetes-validations + 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/x-kubernetes-validations + 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/x-kubernetes-validations + 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" + - name: Should allow updating other fields when an empty string is persisted in blockedRegistries + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/blockedRegistries/items/minLength + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/blockedRegistries/items/x-kubernetes-validations + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + blockedRegistries: [""] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + blockedRegistries: [""] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + blockedRegistries: [""] + - name: Should allow updating other fields when an empty string is persisted in allowedRegistries + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/allowedRegistries/items/minLength + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/allowedRegistries/items/x-kubernetes-validations + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + allowedRegistries: [""] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + allowedRegistries: [""] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + allowedRegistries: [""] + - name: Should allow updating other fields when an empty string is persisted in insecureRegistries + initialCRDPatches: + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/insecureRegistries/items/minLength + - op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/registrySources/properties/insecureRegistries/items/x-kubernetes-validations + initial: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + registrySources: + insecureRegistries: [""] + updated: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + insecureRegistries: [""] + expected: | + apiVersion: config.openshift.io/v1 + kind: Image + spec: + externalRegistryHostnames: ["registry.example.com"] + registrySources: + insecureRegistries: [""] diff --git a/config/v1/types_image.go b/config/v1/types_image.go index 82f46c8b6c9..cc70a5137fe 100644 --- a/config/v1/types_image.go +++ b/config/v1/types_image.go @@ -165,20 +165,50 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + // and must be at most 512 characters in length. The list may contain at most 128 entries. // +optional // +listType=atomic + // +kubebuilder:validation:MaxItems=128 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=512 + // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[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]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + // and must be at most 512 characters in length. The list may contain at most 128 entries. // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic + // +kubebuilder:validation:MaxItems=128 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=512 + // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[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]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + // and must be at most 512 characters in length. The list may contain at most 128 entries. // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic + // +kubebuilder:validation:MaxItems=128 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=512 + // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[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]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" 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..4575cca6617 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,19 +129,45 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic containerRuntimeSearchRegistries: @@ -156,10 +182,23 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic type: object 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..771ff893255 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,19 +112,45 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic containerRuntimeSearchRegistries: @@ -139,10 +165,23 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic type: object 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..91328e9cb44 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,19 +130,45 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic containerRuntimeSearchRegistries: @@ -157,10 +183,23 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic type: object diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 4a5346dba88..4aa5abf4036 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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.", + "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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.\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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.\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..397f60751c0 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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.", 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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.\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 be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 512 characters in length. The list may contain at most 128 entries.\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..4575cca6617 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,19 +129,45 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. Only one of BlockedRegistries or AllowedRegistries may be set. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic containerRuntimeSearchRegistries: @@ -156,10 +182,23 @@ 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 be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), + and must be at most 512 characters in length. The list may contain at most 128 entries. items: + maxLength: 512 + minLength: 1 type: string + x-kubernetes-validations: + - message: each registry must be a valid hostname[:port][/path] + or wildcard *.hostname format without tags or digests + rule: self.matches('^\\*(?:\\.(?:[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]+)+)?)+)?$') + maxItems: 128 type: array x-kubernetes-list-type: atomic type: object