Skip to content

Commit c00c122

Browse files
committed
Add CRIOCredentialProviderConfig API and related functionality
- Add feature gate for CRIOCredentialProviderConfig in various feature gate manifests. Signed-off-by: Qi Wang <[email protected]>
1 parent 1b67472 commit c00c122

19 files changed

+1281
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
2+
name: "CRIOCredentialProviderConfig"
3+
crdName: "criocredentialproviderconfigs.config.openshift.io"
4+
featureGates:
5+
- CRIOCredentialProviderConfig
6+
tests:
7+
onCreate:
8+
- name: Should create a valid CRIOCredentialProviderConfig
9+
initial: |
10+
apiVersion: config.openshift.io/v1alpha1
11+
kind: CRIOCredentialProviderConfig
12+
spec:
13+
matchImages:
14+
- 123456789.dkr.ecr.us-east-1.amazonaws.com
15+
- "*.azurecr.io"
16+
- gcr.io
17+
- "*.*.registry.io"
18+
- registry.io:8080/path
19+
expected: |
20+
apiVersion: config.openshift.io/v1alpha1
21+
kind: CRIOCredentialProviderConfig
22+
spec:
23+
matchImages:
24+
- 123456789.dkr.ecr.us-east-1.amazonaws.com
25+
- "*.azurecr.io"
26+
- gcr.io
27+
- "*.*.registry.io"
28+
- registry.io:8080/path
29+
- name: Should reject matchImages wildcard in the path
30+
initial: |
31+
apiVersion: config.openshift.io/v1alpha1
32+
kind: CRIOCredentialProviderConfig
33+
spec:
34+
matchImages:
35+
- "registry.io:8080/pa*th"
36+
expectedError: "spec.matchImages[0]: Invalid value: \"string\": invalid matchImages value, must be a valid fully qualified domain name with optional wildcard, port, and path"
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package v1alpha1
2+
3+
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4+
5+
// +genclient
6+
// +genclient:nonNamespaced
7+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
8+
9+
// CRIOCredentialProviderConfig holds cluster-wide configurations for CRI-O credential provider. CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources.
10+
// 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.
11+
// 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.
12+
//
13+
// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
14+
// +kubebuilder:object:root=true
15+
// +kubebuilder:resource:path=criocredentialproviderconfigs,scope=Cluster
16+
// +kubebuilder:subresource:status
17+
// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1929
18+
// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
19+
// +openshift:enable:FeatureGate=CRIOCredentialProviderConfig
20+
// +openshift:compatibility-gen:level=4
21+
type CRIOCredentialProviderConfig struct {
22+
metav1.TypeMeta `json:",inline"`
23+
24+
// metadata is the standard object's metadata.
25+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
26+
metav1.ObjectMeta `json:"metadata,omitempty"`
27+
28+
// Spec defines the desired configuration of the CRIO Credential Provider.
29+
// +required
30+
Spec CRIOCredentialProviderConfigSpec `json:"spec,omitempty"`
31+
32+
// Status represents the current state of the CRIOCredentialProviderConfig.
33+
// +optional
34+
Status CRIOCredentialProviderConfigStatus `json:"status,omitempty"`
35+
}
36+
37+
// CRIOCredentialProviderConfigSpec defines the desired configuration of the CRI-O Credential Provider.
38+
type CRIOCredentialProviderConfigSpec struct {
39+
// matchImages is a required list of string patterns used to determine whether
40+
// the CRI-O credential provider should be invoked for a given image. This list is
41+
// passed to the kubelet CredentialProviderConfig, and if any pattern matches
42+
// the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling
43+
// that image or its mirrors.
44+
//
45+
// For more details, see:
46+
// - https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/
47+
// - https://github.com/cri-o/crio-credential-provider#architecture
48+
//
49+
// Each entry in matchImages is a pattern which can optionally contain a port and a path.
50+
// Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io',
51+
// and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net').
52+
// Wildcards are not allowed in the port or path, nor may they appear in the middle of a hostname label.
53+
// For example, '*.example.com' is valid, but 'example*.*.com' is not.
54+
// Each wildcard matches only a single domain label,
55+
// so '*.io' does **not** match '*.k8s.io'.
56+
//
57+
// A match exists between an image and a matchImage when all of the below are true:
58+
// - Both contain the same number of domain parts and each part matches.
59+
// - The URL path of an matchImages must be a prefix of the target image URL path.
60+
// - If the matchImages contains a port, then the port must match in the image as well.
61+
//
62+
// Example values of matchImages:
63+
// - 123456789.dkr.ecr.us-east-1.amazonaws.com
64+
// - *.azurecr.io
65+
// - gcr.io
66+
// - *.*.registry.io
67+
// - registry.io:8080/path
68+
//
69+
// +kubebuilder:validation:MaxItems=50
70+
// +listType=set
71+
// +kubebuilder:validation:Required
72+
MatchImages []MatchImage `json:"matchImages"`
73+
}
74+
75+
// +kubebuilder:validation:MaxLength=512
76+
// +kubebuilder:validation: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])?))*)(:[0-9]+)?(/[-a-zA-Z0-9_/]*)?$')`,message="invalid matchImages value, must be a valid fully qualified domain name with optional wildcard, port, and path"
77+
type MatchImage string
78+
79+
// +k8s:deepcopy-gen=true
80+
// CRIOCredentialProviderConfigStatus defines the observed state of CRIOCredentialProviderConfig
81+
type CRIOCredentialProviderConfigStatus struct {
82+
// Conditions represent the latest available observations of the configuration state
83+
// +optional
84+
// +listType=map
85+
// +listMapKey=type
86+
Conditions []metav1.Condition `json:"conditions,omitempty"`
87+
}
88+
89+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
90+
91+
// CRIOCredentialProviderConfigList contains a list of CRIOCredentialProviderConfig resources
92+
//
93+
// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
94+
// +openshift:compatibility-gen:level=4
95+
type CRIOCredentialProviderConfigList struct {
96+
metav1.TypeMeta `json:",inline"`
97+
98+
// metadata is the standard list's metadata.
99+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
100+
metav1.ListMeta `json:"metadata"`
101+
102+
Items []CRIOCredentialProviderConfig `json:"items"`
103+
}
104+
105+
const (
106+
// ConditionTypeValidated indicates whether the configuration is failed, or partially valid
107+
ConditionTypeValidated = "Validated"
108+
109+
// ReasonValidationFailed indicates the MatchImages configuration contains invalid patterns
110+
ReasonValidationFailed = "ValidationFailed"
111+
112+
// ReasonConfigurationPartiallyApplied indicates some matchImage entries were ignored due to conflicts
113+
ReasonConfigurationPartiallyApplied = "ConfigurationPartiallyApplied"
114+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
apiVersion: apiextensions.k8s.io/v1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
annotations:
5+
api-approved.openshift.io: https://github.com/openshift/api/pull/1929
6+
api.openshift.io/merged-by-featuregates: "true"
7+
include.release.openshift.io/ibm-cloud-managed: "true"
8+
include.release.openshift.io/self-managed-high-availability: "true"
9+
release.openshift.io/feature-set: CustomNoUpgrade
10+
name: criocredentialproviderconfigs.config.openshift.io
11+
spec:
12+
group: config.openshift.io
13+
names:
14+
kind: CRIOCredentialProviderConfig
15+
listKind: CRIOCredentialProviderConfigList
16+
plural: criocredentialproviderconfigs
17+
singular: criocredentialproviderconfig
18+
scope: Cluster
19+
versions:
20+
- name: v1alpha1
21+
schema:
22+
openAPIV3Schema:
23+
description: |-
24+
CRIOCredentialProviderConfig holds cluster-wide configurations for CRI-O credential provider. CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources.
25+
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.
26+
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.
27+
28+
Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
29+
properties:
30+
apiVersion:
31+
description: |-
32+
APIVersion defines the versioned schema of this representation of an object.
33+
Servers should convert recognized schemas to the latest internal value, and
34+
may reject unrecognized values.
35+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
36+
type: string
37+
kind:
38+
description: |-
39+
Kind is a string value representing the REST resource this object represents.
40+
Servers may infer this from the endpoint the client submits requests to.
41+
Cannot be updated.
42+
In CamelCase.
43+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
44+
type: string
45+
metadata:
46+
type: object
47+
spec:
48+
description: Spec defines the desired configuration of the CRIO Credential
49+
Provider.
50+
properties:
51+
matchImages:
52+
description: |-
53+
matchImages is a required list of string patterns used to determine whether
54+
the CRI-O credential provider should be invoked for a given image. This list is
55+
passed to the kubelet CredentialProviderConfig, and if any pattern matches
56+
the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling
57+
that image or its mirrors.
58+
59+
For more details, see:
60+
- https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/
61+
- https://github.com/cri-o/crio-credential-provider#architecture
62+
63+
Each entry in matchImages is a pattern which can optionally contain a port and a path.
64+
Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io',
65+
and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net').
66+
Wildcards are not allowed in the port or path, nor may they appear in the middle of a hostname label.
67+
For example, '*.example.com' is valid, but 'example*.*.com' is not.
68+
Each wildcard matches only a single domain label,
69+
so '*.io' does **not** match '*.k8s.io'.
70+
71+
A match exists between an image and a matchImage when all of the below are true:
72+
- Both contain the same number of domain parts and each part matches.
73+
- The URL path of an matchImages must be a prefix of the target image URL path.
74+
- If the matchImages contains a port, then the port must match in the image as well.
75+
76+
Example values of matchImages:
77+
- 123456789.dkr.ecr.us-east-1.amazonaws.com
78+
- *.azurecr.io
79+
- gcr.io
80+
- *.*.registry.io
81+
- registry.io:8080/path
82+
items:
83+
maxLength: 512
84+
type: string
85+
x-kubernetes-validations:
86+
- message: invalid matchImages value, must be a valid fully qualified
87+
domain name with optional wildcard, port, and path
88+
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])?))*)(:[0-9]+)?(/[-a-zA-Z0-9_/]*)?$')
89+
maxItems: 50
90+
type: array
91+
x-kubernetes-list-type: set
92+
required:
93+
- matchImages
94+
type: object
95+
status:
96+
description: Status represents the current state of the CRIOCredentialProviderConfig.
97+
properties:
98+
conditions:
99+
description: Conditions represent the latest available observations
100+
of the configuration state
101+
items:
102+
description: Condition contains details for one aspect of the current
103+
state of this API Resource.
104+
properties:
105+
lastTransitionTime:
106+
description: |-
107+
lastTransitionTime is the last time the condition transitioned from one status to another.
108+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
109+
format: date-time
110+
type: string
111+
message:
112+
description: |-
113+
message is a human readable message indicating details about the transition.
114+
This may be an empty string.
115+
maxLength: 32768
116+
type: string
117+
observedGeneration:
118+
description: |-
119+
observedGeneration represents the .metadata.generation that the condition was set based upon.
120+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
121+
with respect to the current state of the instance.
122+
format: int64
123+
minimum: 0
124+
type: integer
125+
reason:
126+
description: |-
127+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
128+
Producers of specific condition types may define expected values and meanings for this field,
129+
and whether the values are considered a guaranteed API.
130+
The value should be a CamelCase string.
131+
This field may not be empty.
132+
maxLength: 1024
133+
minLength: 1
134+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
135+
type: string
136+
status:
137+
description: status of the condition, one of True, False, Unknown.
138+
enum:
139+
- "True"
140+
- "False"
141+
- Unknown
142+
type: string
143+
type:
144+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
145+
maxLength: 316
146+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
147+
type: string
148+
required:
149+
- lastTransitionTime
150+
- message
151+
- reason
152+
- status
153+
- type
154+
type: object
155+
type: array
156+
x-kubernetes-list-map-keys:
157+
- type
158+
x-kubernetes-list-type: map
159+
type: object
160+
required:
161+
- spec
162+
type: object
163+
served: true
164+
storage: true
165+
subresources:
166+
status: {}

0 commit comments

Comments
 (0)