4
4
# SPDX-License-Identifier: Apache-2.0
5
5
-->
6
6
7
- # Custom Resource Definitions
7
+ # Custom Resource Definition Schemas
8
8
9
- These directories contain Go types that serve as [ DTO] s for communicating with the Kubernetes API.
10
- We use the [ controller-gen] tool to produce [ CRD] s with schemas that match the Go types.
9
+ These directories contain Go types that [ controller-gen] uses to generate matching [ CRD] schemas.
11
10
The CRD schema tells Kubernetes what fields and values are allowed in our API objects and how to handle changes to values.
12
11
13
12
> [ !TIP]
14
13
> The CRD schema is * most* of the UX of our API
15
14
16
15
CRD schemas are modified OpenAPI 3.0 [ validation] schemas.
17
16
Much of the schema defines what fields, types, and values are * allowed* .
18
- ` controller-gen ` considers the [ Go type] of a field and its [ validation markers] for this.
17
+ ` controller-gen ` considers the field's [ Go type] and [ validation markers] for this.
19
18
20
19
Kubernetes uses its own algorithm to consider and accept changes to API objects: [ Server-Side Apply] , SSA.
21
20
CRD schemas contain non-standard attributes that affect SSA.
@@ -25,9 +24,6 @@ CRD schemas contain non-standard attributes that affect SSA.
25
24
26
25
[ controller-gen ] : https://book.kubebuilder.io/reference/controller-gen
27
26
[ CRD ] : https://docs.k8s.io/tasks/extend-kubernetes/custom-resources/custom-resource-definitions
28
- [ DTO ] : https://martinfowler.com/eaaCatalog/dataTransferObject.html
29
- [ Go type ] : https://go.dev/ref/spec#Types
30
- [ Kubernetes API ] : https://docs.k8s.io/concepts/overview/kubernetes-api
31
27
[ processing markers ] : https://book.kubebuilder.io/reference/markers/crd-processing
32
28
[ Server-Side Apply ] : https://docs.k8s.io/reference/using-api/server-side-apply
33
29
[ validation ] : https://docs.k8s.io/tasks/extend-kubernetes/custom-resources/custom-resource-definitions#validation
@@ -92,7 +88,7 @@ The `additionalProperties` property indicates that the keys are unknown; these f
92
88
# CEL Rules
93
89
94
90
> [ !IMPORTANT]
95
- > When possible, use [ OpenAPI properties] ( #FIXME ) rather than CEL rules.
91
+ > When possible, use [ OpenAPI properties] ( #openapi-properties ) rather than CEL rules.
96
92
> The former do not affect the CRD [ validation budget] ( #FIXME ) . <!-- https://imgur.com/CzpJn3j -->
97
93
98
94
## Optional field syntax
@@ -109,3 +105,88 @@ likewise be considered optional.
109
105
The optional field syntax is only available in K8s 1.29+.
110
106
111
107
[ optional field marker ] : https://pkg.go.dev/github.com/google/cel-go/cel#hdr-Syntax_Changes-OptionalTypes.
108
+
109
+ ## CEL Availability
110
+
111
+ Kubernetes' capabilities with CEL are continuously expanding.
112
+ Different versions of Kubernetes have different CEL functions, syntax, and features.
113
+
114
+ ``` asciidoc
115
+ :controller-tools: https://github.com/kubernetes-sigs/controller-tools/releases
116
+
117
+ [cols=",,", options="header"]
118
+ |===
119
+ | Kubernetes | OpenShift | `controller-gen`
120
+
121
+ | 1.25 Beta, `CustomResourceValidationExpressions` gate
122
+ | OCP 4.12
123
+ | link:{controller-tools}/v0.9.0[v0.9.0] has `rule` and `message` fields on the `XValidation` marker
124
+
125
+ | 1.27 adds `messageExpression`
126
+ | OCP 4.14
127
+ | link:{controller-tools}/v0.15.0[v0.15.0] adds `messageExpression` field to the `XValidation` marker
128
+
129
+ | 1.28 adds `reason` and `fieldPath`
130
+ | OCP 4.15
131
+ | link:{controller-tools}/v0.16.0[v0.16.0] adds `reason` and `fieldPath` to the `XValidation` marker
132
+
133
+ | 1.29 GA | OCP 4.16 |
134
+
135
+ | 1.30 enables link:#validation-ratcheting[validation ratcheting]; link:https://pr.k8s.io/123475[fixes fieldPath]...
136
+ | OCP 4.17
137
+ | link:{controller-tools}/v0.17.3[v0.17.3] adds `optionalOldSelf` to the `XValidation` marker
138
+
139
+ | 1.34 link:https://pr.k8s.io/132837[fixes IntOrString cost]
140
+ | ?
141
+ | link:{controller-tools}/v0.18.0[v0.18.0] allows validation on IntOrString
142
+
143
+ | 1.35 link:https://pr.k8s.io/132798[shows values when validation fails]
144
+ | ?
145
+ | n/a
146
+
147
+ |===
148
+ ```
149
+
150
+ <!-- TODO: long-form; describe each library -->
151
+
152
+ Some details are missing from the Go package documentation: https://pr.k8s.io/130660
153
+
154
+ | CEL [libraries](https://code.k8s.io/staging/src/k8s.io/apiserver/pkg/cel/library), extensions, etc. | Kubernetes | OpenShift |
155
+ | --- | --- | --- |
156
+ | kubernetes.authz | 1.28 |
157
+ | kubernetes.authzSelectors | 1.32 |
158
+ | kubernetes.format | 1.32 | [4.18](https://github.com/openshift/kubernetes/pull/2140) |
159
+ | kubernetes.lists | 1.24 | 4.12 |
160
+ | kubernetes.net.cidr | 1.31 | [4.16](https://github.com/openshift/kubernetes/pull/1828) |
161
+ | kubernetes.net.ip | 1.31 | [4.16](https://github.com/openshift/kubernetes/pull/1828) |
162
+ | kubernetes.quantity | 1.29 | 4.16 |
163
+ | kubernetes.regex | 1.24 | 4.12 |
164
+ | kubernetes.urls | 1.24 | 4.12 |
165
+ | [cross-type numeric comparison](https://pkg.go.dev/github.com/google/cel-go/cel#CrossTypeNumericComparisons) | 1.29 | 4.16 |
166
+ | [optional types](https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes) | 1.29 | 4.16 |
167
+ | [strings](https://pkg.go.dev/github.com/google/cel-go/ext#Strings) v0 | 1.24 | 4.12 |
168
+ | [strings](https://pkg.go.dev/github.com/google/cel-go/ext#Strings) v2 | 1.30 | 4.17 |
169
+ | [sets](https://pkg.go.dev/github.com/google/cel-go/ext#Sets) | 1.30 | 4.17 |
170
+ | [two-variable comprehension](https://pkg.go.dev/github.com/google/cel-go/ext#TwoVarComprehensions) | 1.33 |
171
+
172
+
173
+ # Validation Ratcheting
174
+
175
+ > **Feature Gate:** `CRDValidationRatcheting`
176
+ >
177
+ > Enabled in Kubernetes 1.30 and GA in 1.33 (OpenShift 4.17 and ~4.20)
178
+
179
+ [Validation ratcheting] allows update operations to succeed when unchanged fields are invalid.
180
+ This allows CRDs to add or "tighten" validation without breaking existing CR objects.
181
+
182
+ Some schema changes are not ratcheted:
183
+
184
+ - OpenAPI `allOf` , `oneOf` , `anyOf` , `not` ; values in fields with these must be valid
185
+ - OpenAPI `required` ; required fields are always required
186
+ - Removing `additionalProperties` ; undefined fields are always dropped
187
+ - Adding or removing fields (names) in `properties` ; undefined fields are dropped, and values in new fields must be valid
188
+ - Changes to `x-kubernetes-list-type` or `x-kubernetes-list-map-keys` ; values in these fields must be valid
189
+ - Rules containing `oldSelf` ; these are [transition rules] and should do their own ratcheting
190
+
191
+ [transition rules]: https://docs.k8s.io/tasks/extend-kubernetes/custom-resources/custom-resource-definitions#transition-rules
192
+ [Validation ratcheting]: https://docs.k8s.io/tasks/extend-kubernetes/custom-resources/custom-resource-definitions#validation-ratcheting
0 commit comments