Skip to content

Commit e623504

Browse files
authored
Merge pull request openshift#81656 from adellape/crd_upgrade_safety
OSDOCS#11979: Add CRD upgrade safety for OLMv1
2 parents a907293 + 88d514a commit e623504

8 files changed

+351
-2
lines changed

_topic_maps/_topic_map.yml

+2
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,8 @@ Topics:
20222022
File: managing-ce
20232023
- Name: Upgrade edges
20242024
File: upgrade-edges
2025+
- Name: CRD upgrade safety
2026+
File: crd-upgrade-safety
20252027
---
20262028
Name: CI/CD
20272029
Dir: cicd

extensions/ce/crd-upgrade-safety.adoc

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
:_mod-docs-content-type: ASSEMBLY
2+
[id="crd-upgrade-safety"]
3+
= Custom resource definition (CRD) upgrade safety
4+
include::_attributes/common-attributes.adoc[]
5+
:context: crd-upgrade-safety
6+
7+
toc::[]
8+
9+
:FeatureName: {olmv1-first}
10+
include::snippets/technology-preview.adoc[]
11+
12+
When you update a custom resource definition (CRD) that is provided by a cluster extension, {olmv1-first} runs a CRD upgrade safety preflight check to ensure backwards compatibility with previous versions of that CRD. The CRD update must pass the validation checks before the change is allowed to progress on a cluster.
13+
14+
[role="_additional-resources"]
15+
.Additional resources
16+
* xref:../../extensions/ce/managing-ce.adoc#olmv1-updating-an-operator_managing-ce[Updating a cluster extension]
17+
18+
include::modules/prohibited-crd-upgrades.adoc[leveloffset=+1]
19+
include::modules/allowed-crd-upgrades.adoc[leveloffset=+1]
20+
include::modules/disabling-crd-preflight.adoc[leveloffset=+1]
21+
include::modules/examples-unsafe-crd-upgrades.adoc[leveloffset=+1]

modules/allowed-crd-upgrades.adoc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * extensions/ce/crd-upgrade-safety.adoc
4+
5+
:_mod-docs-content-type: REFERENCE
6+
7+
[id="allowed-crd-changes_{context}"]
8+
= Allowed CRD upgrade changes
9+
10+
The following changes to an existing custom resource definition (CRD) are safe for backwards compatibility and will not cause the CRD upgrade safety preflight check to halt the upgrade:
11+
12+
- Adding new enum values to the list of allowed enum values in a field
13+
- An existing required field is changed to optional in an existing version
14+
- The minimum value of an existing field is decreased in an existing version
15+
- The maximum value of an existing field is increased in an existing version
16+
- A new version of the CRD is added with no modifications to existing versions

modules/disabling-crd-preflight.adoc

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * extensions/ce/crd-upgrade-safety.adoc
4+
5+
:_mod-docs-content-type: PROCEDURE
6+
7+
[id="disabling-crd-preflight_{context}"]
8+
= Disabling CRD upgrade safety preflight check
9+
10+
The custom resource definition (CRD) upgrade safety preflight check can be disabled by adding the `preflight.crdUpgradeSafety.disabled` field with a value of `true` to the `ClusterExtension` object that provides the CRD.
11+
12+
[WARNING]
13+
====
14+
Disabling the CRD upgrade safety preflight check could break backwards compatibility with stored versions of the CRD and cause other unintended consequences on the cluster.
15+
====
16+
17+
You cannot disable individual field validators. If you disable the CRD upgrade safety preflight check, all field validators are disabled.
18+
19+
[NOTE]
20+
====
21+
The following checks are handled by the Kubernetes API server:
22+
23+
* The scope changes from `Cluster` to `Namespace` or from `Namespace` to `Cluster`
24+
* An existing stored version of the CRD is removed
25+
26+
After disabling the CRD upgrade safety preflight check via {olmv1-first}, these two operations are still prevented by Kubernetes.
27+
====
28+
29+
.Prerequisites
30+
31+
* You have a cluster extension installed.
32+
33+
.Procedure
34+
35+
. Edit the `ClusterExtension` object of the CRD:
36+
+
37+
[source,terminal]
38+
----
39+
$ oc edit clusterextension <clusterextension_name>
40+
----
41+
42+
. Set the `preflight.crdUpgradeSafety.disabled` field to `true`:
43+
+
44+
.Example `ClusterExtension` object
45+
[%collapsible]
46+
====
47+
[source,yaml]
48+
----
49+
apiVersion: olm.operatorframework.io/v1alpha1
50+
kind: ClusterExtension
51+
metadata:
52+
name: clusterextension-sample
53+
spec:
54+
installNamespace: default
55+
packageName: argocd-operator
56+
version: 0.6.0
57+
preflight:
58+
crdUpgradeSafety:
59+
disabled: true <1>
60+
----
61+
<1> Set to `true`.
62+
====
63+
+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * extensions/ce/crd-upgrade-safety.adoc
4+
5+
:_mod-docs-content-type: REFERENCE
6+
7+
[id="examples-unsafe_{context}"]
8+
= Examples of unsafe CRD changes
9+
10+
The following examples demonstrate specific changes to sections of an example custom resource definition (CRD) that would be caught by the CRD upgrade safety preflight check.
11+
12+
For the following examples, consider a CRD object in the following starting state:
13+
14+
.Example CRD object
15+
[%collapsible]
16+
====
17+
[source,yaml]
18+
----
19+
apiVersion: apiextensions.k8s.io/v1
20+
kind: CustomResourceDefinition
21+
metadata:
22+
annotations:
23+
controller-gen.kubebuilder.io/version: v0.13.0
24+
name: example.test.example.com
25+
spec:
26+
group: test.example.com
27+
names:
28+
kind: Sample
29+
listKind: SampleList
30+
plural: samples
31+
singular: sample
32+
scope: Namespaced
33+
versions:
34+
- name: v1alpha1
35+
schema:
36+
openAPIV3Schema:
37+
properties:
38+
apiVersion:
39+
type: string
40+
kind:
41+
type: string
42+
metadata:
43+
type: object
44+
spec:
45+
type: object
46+
status:
47+
type: object
48+
pollInterval:
49+
type: string
50+
type: object
51+
served: true
52+
storage: true
53+
subresources:
54+
status: {}
55+
----
56+
====
57+
58+
[id="scope-change_{context}"]
59+
== Scope change
60+
61+
In the following custom resource definition (CRD) example, the `scope` field is changed from `Namespaced` to `Cluster`:
62+
63+
.Example scope change in a CRD
64+
[%collapsible]
65+
====
66+
[source,yaml]
67+
----
68+
spec:
69+
group: test.example.com
70+
names:
71+
kind: Sample
72+
listKind: SampleList
73+
plural: samples
74+
singular: sample
75+
scope: Cluster
76+
versions:
77+
- name: v1alpha1
78+
----
79+
====
80+
81+
.Example error output
82+
[%collapsible]
83+
====
84+
[source,text]
85+
----
86+
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoScopeChange" validation failed: scope changed from "Namespaced" to "Cluster"
87+
----
88+
====
89+
90+
[id="stored-version-removal_{context}"]
91+
== Removal of a stored version
92+
93+
In the following custom resource definition (CRD) example, the existing stored version, `v1alpha1`, is removed:
94+
95+
.Example removal of a stored version in a CRD
96+
[%collapsible]
97+
====
98+
[source,yaml]
99+
----
100+
versions:
101+
- name: v1alpha2
102+
schema:
103+
openAPIV3Schema:
104+
properties:
105+
apiVersion:
106+
type: string
107+
kind:
108+
type: string
109+
metadata:
110+
type: object
111+
spec:
112+
type: object
113+
status:
114+
type: object
115+
pollInterval:
116+
type: string
117+
type: object
118+
----
119+
====
120+
121+
.Example error output
122+
[%collapsible]
123+
====
124+
[source,text]
125+
----
126+
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoStoredVersionRemoved" validation failed: stored version "v1alpha1" removed
127+
----
128+
====
129+
130+
[id="removal-existing-field_{context}"]
131+
== Removal of an existing field
132+
133+
In the following custom resource definition (CRD) example, the `pollInterval` property field is removed from the `v1alpha1` schema:
134+
135+
.Example removal of an existing field in a CRD
136+
[%collapsible]
137+
====
138+
[source,yaml]
139+
----
140+
versions:
141+
- name: v1alpha1
142+
schema:
143+
openAPIV3Schema:
144+
properties:
145+
apiVersion:
146+
type: string
147+
kind:
148+
type: string
149+
metadata:
150+
type: object
151+
spec:
152+
type: object
153+
status:
154+
type: object
155+
type: object
156+
----
157+
====
158+
159+
.Example error output
160+
[%collapsible]
161+
====
162+
[source,text]
163+
----
164+
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "NoExistingFieldRemoved" validation failed: crd/test.example.com version/v1alpha1 field/^.spec.pollInterval may not be removed
165+
----
166+
====
167+
168+
[id="addition-required-field_{context}"]
169+
== Addition of a required field
170+
171+
In the following custom resource definition (CRD) example, the `pollInterval` property has been changed to a required field:
172+
173+
.Example addition of a required field in a CRD
174+
[%collapsible]
175+
====
176+
[source,yaml]
177+
----
178+
versions:
179+
- name: v1alpha2
180+
schema:
181+
openAPIV3Schema:
182+
properties:
183+
apiVersion:
184+
type: string
185+
kind:
186+
type: string
187+
metadata:
188+
type: object
189+
spec:
190+
type: object
191+
status:
192+
type: object
193+
pollInterval:
194+
type: string
195+
type: object
196+
required:
197+
- pollInterval
198+
----
199+
====
200+
201+
.Example error output
202+
[%collapsible]
203+
====
204+
[source,text]
205+
----
206+
validating upgrade for CRD "test.example.com" failed: CustomResourceDefinition test.example.com failed upgrade safety validation. "ChangeValidator" validation failed: version "v1alpha1", field "^": new required fields added: [pollInterval]
207+
----
208+
====

modules/olmv1-finding-operators-to-install.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
After you add a catalog to your cluster, you can query the catalog to find Operators and extensions to install. Before you can query catalogs, you must port forward the catalog server service.
1111

12-
.Prerequisite
12+
.Prerequisites
1313

1414
* You have added a catalog to your cluster.
1515
* You have installed the `jq` CLI tool.

modules/olmv1-installing-an-operator.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
include::snippets/olmv1-tp-extension-support.adoc[]
1313

14-
.Prerequisite
14+
.Prerequisites
1515

1616
* You have added a catalog to your cluster.
1717
* You have downloaded a local copy of the catalog file.

modules/prohibited-crd-upgrades.adoc

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * extensions/ce/crd-upgrade-safety.adoc
4+
5+
:_mod-docs-content-type: REFERENCE
6+
7+
[id="prohibited-crd-upgrades_{context}"]
8+
= Prohibited CRD upgrade changes
9+
10+
The following changes to an existing custom resource definition (CRD) are caught by the CRD upgrade safety preflight check and prevent the upgrade:
11+
12+
- A new required field is added to an existing version of the CRD
13+
- An existing field is removed from an existing version of the CRD
14+
- An existing field type is changed in an existing version of the CRD
15+
- A new default value is added to a field that did not previously have a default value
16+
- The default value of a field is changed
17+
- An existing default value of a field is removed
18+
- New enum restrictions are added to an existing field which did not previously have enum restrictions
19+
- Existing enum values from an existing field are removed
20+
- The minimum value of an existing field is increased in an existing version
21+
- The maximum value of an existing field is decreased in an existing version
22+
- Minimum or maximum field constraints are added to a field that did not previously have constraints
23+
24+
[NOTE]
25+
====
26+
The rules for changes to minimum and maximum values apply to `minimum`, `minLength`, `minProperties`, `minItems`, `maximum`, `maxLength`, `maxProperties`, and `maxItems` constraints.
27+
====
28+
29+
The following changes to an existing CRD are reported by the CRD upgrade safety preflight check and prevent the upgrade, though the operations are technically handled by the Kubernetes API server:
30+
31+
- The scope changes from `Cluster` to `Namespace` or from `Namespace` to `Cluster`
32+
- An existing stored version of the CRD is removed
33+
34+
If the CRD upgrade safety preflight check encounters one of the prohibited upgrade changes, it logs an error for each prohibited change detected in the CRD upgrade.
35+
36+
[TIP]
37+
====
38+
In cases where a change to the CRD does not fall into one of the prohibited change categories, but is also unable to be properly detected as allowed, the CRD upgrade safety preflight check will prevent the upgrade and log an error for an "unknown change".
39+
====

0 commit comments

Comments
 (0)