-
Notifications
You must be signed in to change notification settings - Fork 592
OCPNODE-4125: Upgrade to v1 CRIOCredentialProviderConfig #2725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
QiWang19
wants to merge
3
commits into
openshift:master
Choose a base branch
from
QiWang19:upgrade-v1-criocp
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
...tests/criocredentialproviderconfigs.config.openshift.io/CRIOCredentialProviderConfig.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this | ||
| name: "CRIOCredentialProviderConfig" | ||
| crdName: "criocredentialproviderconfigs.config.openshift.io" | ||
| featureGates: | ||
| - CRIOCredentialProviderConfig | ||
| tests: | ||
| onCreate: | ||
| - name: Should create a minimal CRIOCredentialProviderConfig | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: {} | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: {} | ||
| - name: Should create a valid CRIOCredentialProviderConfig | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - 123456789.dkr.ecr.us-east-1.amazonaws.com | ||
| - "*.azurecr.io" | ||
| - gcr.io | ||
| - "*.*.registry.io" | ||
| - registry.io:8080/path | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - 123456789.dkr.ecr.us-east-1.amazonaws.com | ||
| - "*.azurecr.io" | ||
| - gcr.io | ||
| - "*.*.registry.io" | ||
| - registry.io:8080/path | ||
| - name: Should reject matchImages with invalid characters | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "reg!stry.io" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| - name: Should reject matchImages with uppercase hostname | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "Registry.COM" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| - name: Should reject matchImages with uppercase in the path | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "registry.io/PaTh" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| - name: Should reject matchImages wildcard in the path | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "registry.io:8080/pa*th" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| - name: Should reject wildcard for partial subdomains | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "example.app*.com" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| - name: Should reject global wildcard '*' | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: CRIOCredentialProviderConfig | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| matchImages: | ||
| - "*" | ||
| expectedError: "spec.matchImages[0]: Invalid value: \"string\": global wildcard '*' is not allowed" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| package v1 | ||
|
|
||
| import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
|
||
| // +genclient | ||
| // +genclient:nonNamespaced | ||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
|
|
||
| // CRIOCredentialProviderConfig holds cluster-wide singleton resource configurations for CRI-O credential provider, the name of this instance is "cluster". CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources. | ||
| // For example, it can be used to fetch mirror registry credentials from secrets resources in the cluster within the same namespace the pod will be running in. | ||
| // CRIOCredentialProviderConfig configuration specifies the pod image sources registries that should trigger the CRI-O credential provider execution, which will resolve the CRI-O mirror configurations and obtain the necessary credentials for pod creation. | ||
| // Note: Configuration changes will only take effect after the kubelet restarts, which is automatically managed by the cluster during rollout. | ||
| // | ||
| // The resource is a singleton named "cluster". | ||
| // | ||
| // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). | ||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:resource:path=criocredentialproviderconfigs,scope=Cluster | ||
| // +kubebuilder:subresource:status | ||
| // +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/2725 | ||
| // +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01 | ||
| // +openshift:enable:FeatureGate=CRIOCredentialProviderConfig | ||
| // +openshift:compatibility-gen:level=1 | ||
| // +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="criocredentialproviderconfig is a singleton, .metadata.name must be 'cluster'" | ||
| type CRIOCredentialProviderConfig struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
|
|
||
| // metadata is the standard object's metadata. | ||
| // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata | ||
| // +optional | ||
| metav1.ObjectMeta `json:"metadata,omitzero"` | ||
|
|
||
| // spec defines the desired configuration of the CRI-O Credential Provider. | ||
| // This field is required and must be provided when creating the resource. | ||
| // +required | ||
| Spec *CRIOCredentialProviderConfigSpec `json:"spec,omitempty,omitzero"` | ||
|
|
||
| // status represents the current state of the CRIOCredentialProviderConfig. | ||
| // When omitted or nil, it indicates that the status has not yet been set by the controller. | ||
| // The controller will populate this field with validation conditions and operational state. | ||
| // +optional | ||
| Status CRIOCredentialProviderConfigStatus `json:"status,omitzero,omitempty"` | ||
| } | ||
|
|
||
| // CRIOCredentialProviderConfigSpec defines the desired configuration of the CRI-O Credential Provider. | ||
| // +kubebuilder:validation:MinProperties=0 | ||
| type CRIOCredentialProviderConfigSpec struct { | ||
| // matchImages is a list of string patterns used to determine whether | ||
| // the CRI-O credential provider should be invoked for a given image. This list is | ||
| // passed to the kubelet CredentialProviderConfig, and if any pattern matches | ||
| // the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling | ||
| // that image or its mirrors. | ||
| // Depending on the platform, the CRI-O credential provider may be installed alongside an existing platform specific provider. | ||
| // Conflicts between the existing platform specific provider image match configuration and this list will be handled by | ||
| // the following precedence rule: credentials from built-in kubelet providers (e.g., ECR, GCR, ACR) take precedence over those | ||
| // from the CRIOCredentialProviderConfig when both match the same image. | ||
| // To avoid uncertainty, it is recommended to avoid configuring your private image patterns to overlap with | ||
| // existing platform specific provider config(e.g., the entries from https://github.com/openshift/machine-config-operator/blob/main/templates/common/aws/files/etc-kubernetes-credential-providers-ecr-credential-provider.yaml). | ||
| // You can check the resource's Status conditions | ||
| // to see if any entries were ignored due to exact matches with known built-in provider patterns. | ||
| // | ||
| // This field is optional, the items of the list must contain between 1 and 50 entries. | ||
| // The list is treated as a set, so duplicate entries are not allowed. | ||
| // | ||
| // For more details, see: | ||
| // https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/ | ||
| // https://github.com/cri-o/crio-credential-provider#architecture | ||
| // | ||
| // Each entry in matchImages is a pattern which can optionally contain a port and a path. Each entry must be no longer than 512 characters. | ||
| // Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io', | ||
| // and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net'). | ||
| // A global wildcard '*' (matching any domain) is not allowed. | ||
| // Wildcards may replace an entire hostname label (e.g., *.example.com), but they cannot appear within a label (e.g., f*oo.example.com) and are not allowed in the port or path. | ||
| // For example, 'example.*.com' is valid, but 'exa*mple.*.com' is not. | ||
| // Each wildcard matches only a single domain label, | ||
| // so '*.io' does **not** match '*.k8s.io'. | ||
| // | ||
| // A match exists between an image and a matchImage when all of the below are true: | ||
| // Both contain the same number of domain parts and each part matches. | ||
| // The URL path of an matchImages must be a prefix of the target image URL path. | ||
| // If the matchImages contains a port, then the port must match in the image as well. | ||
| // | ||
| // Example values of matchImages: | ||
| // - 123456789.dkr.ecr.us-east-1.amazonaws.com | ||
| // - *.azurecr.io | ||
| // - gcr.io | ||
| // - *.*.registry.io | ||
| // - registry.io:8080/path | ||
| // | ||
| // +kubebuilder:validation:MaxItems=50 | ||
| // +kubebuilder:validation:MinItems=1 | ||
| // +listType=set | ||
| // +optional | ||
| MatchImages []MatchImage `json:"matchImages,omitempty"` | ||
| } | ||
|
|
||
| // MatchImage is a string pattern used to match container image registry addresses. | ||
| // It must be a valid fully qualified domain name with optional wildcard, port, and path. | ||
| // The maximum length is 512 characters. | ||
| // | ||
| // Wildcards ('*') are supported for full subdomain labels and top-level domains. | ||
| // Each entry can optionally contain a port (e.g., :8080) and a path (e.g., /path). | ||
| // Wildcards are not allowed in the port or path portions. | ||
| // | ||
| // Examples: | ||
| // - "registry.io" - matches exactly registry.io | ||
| // - "*.azurecr.io" - matches any single subdomain of azurecr.io | ||
| // - "registry.io:8080/path" - matches with specific port and path prefix | ||
| // | ||
| // +kubebuilder:validation:MaxLength=512 | ||
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:XValidation:rule="self != '*'",message="global wildcard '*' is not allowed" | ||
| // +kubebuilder:validation:XValidation:rule=`self.matches('^((\\*|[a-z0-9]([a-z0-9-]*[a-z0-9])?)(\\.(\\*|[a-z0-9]([a-z0-9-]*[a-z0-9])?))*)(:[0-9]+)?(/[-a-z0-9._/]*)?$')`,message="invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" | ||
| type MatchImage string | ||
|
|
||
| // +k8s:deepcopy-gen=true | ||
| // CRIOCredentialProviderConfigStatus defines the observed state of CRIOCredentialProviderConfig | ||
| // +kubebuilder:validation:MinProperties=1 | ||
| type CRIOCredentialProviderConfigStatus struct { | ||
| // conditions represent the latest available observations of the configuration state. | ||
| // When omitted, it indicates that no conditions have been reported yet. | ||
| // The maximum number of conditions is 16. | ||
| // Conditions are stored as a map keyed by condition type, ensuring uniqueness. | ||
| // | ||
| // Expected condition types include: | ||
| // "Validated": indicates whether the matchImages configuration is valid | ||
| // +optional | ||
| // +kubebuilder:validation:MaxItems=16 | ||
| // +kubebuilder:validation:MinItems=1 | ||
| // +listType=map | ||
| // +listMapKey=type | ||
| Conditions []metav1.Condition `json:"conditions,omitempty"` | ||
| } | ||
|
|
||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
|
|
||
| // CRIOCredentialProviderConfigList contains a list of CRIOCredentialProviderConfig resources | ||
| // | ||
| // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). | ||
| // +openshift:compatibility-gen:level=1 | ||
| type CRIOCredentialProviderConfigList struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
|
|
||
| // metadata is the standard list's metadata. | ||
| // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata | ||
| metav1.ListMeta `json:"metadata"` | ||
|
|
||
| Items []CRIOCredentialProviderConfig `json:"items"` | ||
| } | ||
|
|
||
| const ( | ||
| // ConditionTypeValidated is a condition type that indicates whether the CRIOCredentialProviderConfig | ||
| // matchImages configuration has been validated successfully. | ||
| // When True, all matchImage patterns are valid and have been applied. | ||
| // When False, the configuration contains errors (see Reason for details). | ||
| // Possible reasons for False status: | ||
| // - ValidationFailed: matchImages contains invalid patterns | ||
| // - ConfigurationPartiallyApplied: some matchImage entries were ignored due to conflicts | ||
| ConditionTypeValidated = "Validated" | ||
|
|
||
| // ReasonValidationFailed is a condition reason used with ConditionTypeValidated=False | ||
| // to indicate that the matchImages configuration contains one or more invalid registry patterns | ||
| // that do not conform to the required format (valid FQDN with optional wildcard, port, and path). | ||
| ReasonValidationFailed = "ValidationFailed" | ||
|
|
||
| // ReasonConfigurationPartiallyApplied is a condition reason used with ConditionTypeValidated=False | ||
| // to indicate that some matchImage entries were ignored due to conflicts or overlapping patterns. | ||
| // The condition message will contain details about which entries were ignored and why. | ||
| ReasonConfigurationPartiallyApplied = "ConfigurationPartiallyApplied" | ||
|
|
||
| // ConditionTypeMachineConfigRendered is a condition type that indicates whether | ||
| // the CRIOCredentialProviderConfig has been successfully rendered into a | ||
| // MachineConfig object. | ||
| // When True, the corresponding MachineConfig is present in the cluster. | ||
| // When False, rendering failed. | ||
| ConditionTypeMachineConfigRendered = "MachineConfigRendered" | ||
|
|
||
| // ReasonMachineConfigRenderingSucceeded is a condition reason used with ConditionTypeMachineConfigRendered=True | ||
| // to indicate that the MachineConfig was successfully created/updated in the API server. | ||
| ReasonMachineConfigRenderingSucceeded = "MachineConfigRenderingSucceeded" | ||
|
|
||
| // ReasonMachineConfigRenderingFailed is a condition reason used with ConditionTypeMachineConfigRendered=False | ||
| // to indicate that the MachineConfig creation/update failed. | ||
| // The condition message will contain details about the failure. | ||
| ReasonMachineConfigRenderingFailed = "MachineConfigRenderingFailed" | ||
| ) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the feature-gate annotation if this API is GA.
Line 22 still gates the v1 resource behind
CRIOCredentialProviderConfig. That conflicts with the GA objective and can keep CRD exposure conditional instead of unconditional.Proposed fix
-// +openshift:enable:FeatureGate=CRIOCredentialProviderConfig📝 Committable suggestion
🤖 Prompt for AI Agents