Skip to content

Commit 59fa653

Browse files
committed
Add ClusterAPI observedRevisionGeneration
1 parent c53d954 commit 59fa653

7 files changed

Lines changed: 286 additions & 4 deletions

File tree

openapi/generated_openapi/zz_generated.openapi.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

operator/v1alpha1/tests/clusterapis.operator.openshift.io/ClusterAPIMachineManagement.yaml

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,3 +1188,221 @@ tests:
11881188
components:
11891189
- type: Image
11901190
expectedStatusError: "image is required when type is Image, and forbidden otherwise"
1191+
1192+
# observedRevisionGeneration validation tests
1193+
1194+
- name: Should reject observedGeneration less than 1
1195+
initial: |
1196+
apiVersion: operator.openshift.io/v1alpha1
1197+
kind: ClusterAPI
1198+
metadata:
1199+
name: cluster
1200+
spec: {}
1201+
updated: |
1202+
apiVersion: operator.openshift.io/v1alpha1
1203+
kind: ClusterAPI
1204+
metadata:
1205+
name: cluster
1206+
spec: {}
1207+
status:
1208+
observedRevisionGeneration: 0
1209+
desiredRevision: rev-1
1210+
revisions:
1211+
- name: rev-1
1212+
revision: 1
1213+
contentID: content-1
1214+
components:
1215+
- type: Image
1216+
image:
1217+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1218+
profile: default
1219+
expectedStatusError: "should be greater than or equal to 1"
1220+
1221+
- name: Should accept increasing observedGeneration
1222+
initial: |
1223+
apiVersion: operator.openshift.io/v1alpha1
1224+
kind: ClusterAPI
1225+
metadata:
1226+
name: cluster
1227+
spec: {}
1228+
status:
1229+
observedRevisionGeneration: 1
1230+
desiredRevision: rev-1
1231+
revisions:
1232+
- name: rev-1
1233+
revision: 1
1234+
contentID: content-1
1235+
components:
1236+
- type: Image
1237+
image:
1238+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1239+
profile: default
1240+
updated: |
1241+
apiVersion: operator.openshift.io/v1alpha1
1242+
kind: ClusterAPI
1243+
metadata:
1244+
name: cluster
1245+
spec: {}
1246+
status:
1247+
observedRevisionGeneration: 2
1248+
desiredRevision: rev-1
1249+
revisions:
1250+
- name: rev-1
1251+
revision: 1
1252+
contentID: content-1
1253+
components:
1254+
- type: Image
1255+
image:
1256+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1257+
profile: default
1258+
expected: |
1259+
apiVersion: operator.openshift.io/v1alpha1
1260+
kind: ClusterAPI
1261+
metadata:
1262+
name: cluster
1263+
spec: {}
1264+
status:
1265+
observedRevisionGeneration: 2
1266+
desiredRevision: rev-1
1267+
revisions:
1268+
- name: rev-1
1269+
revision: 1
1270+
contentID: content-1
1271+
components:
1272+
- type: Image
1273+
image:
1274+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1275+
profile: default
1276+
1277+
- name: Should accept keeping observedGeneration the same
1278+
initial: |
1279+
apiVersion: operator.openshift.io/v1alpha1
1280+
kind: ClusterAPI
1281+
metadata:
1282+
name: cluster
1283+
spec: {}
1284+
status:
1285+
observedRevisionGeneration: 1
1286+
desiredRevision: rev-1
1287+
revisions:
1288+
- name: rev-1
1289+
revision: 1
1290+
contentID: content-1
1291+
components:
1292+
- type: Image
1293+
image:
1294+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1295+
profile: default
1296+
updated: |
1297+
apiVersion: operator.openshift.io/v1alpha1
1298+
kind: ClusterAPI
1299+
metadata:
1300+
name: cluster
1301+
spec: {}
1302+
status:
1303+
observedRevisionGeneration: 1
1304+
desiredRevision: rev-1
1305+
revisions:
1306+
- name: rev-1
1307+
revision: 1
1308+
contentID: content-1
1309+
components:
1310+
- type: Image
1311+
image:
1312+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1313+
profile: default
1314+
expected: |
1315+
apiVersion: operator.openshift.io/v1alpha1
1316+
kind: ClusterAPI
1317+
metadata:
1318+
name: cluster
1319+
spec: {}
1320+
status:
1321+
observedRevisionGeneration: 1
1322+
desiredRevision: rev-1
1323+
revisions:
1324+
- name: rev-1
1325+
revision: 1
1326+
contentID: content-1
1327+
components:
1328+
- type: Image
1329+
image:
1330+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1331+
profile: default
1332+
1333+
- name: Should reject decreasing observedGeneration
1334+
initial: |
1335+
apiVersion: operator.openshift.io/v1alpha1
1336+
kind: ClusterAPI
1337+
metadata:
1338+
name: cluster
1339+
spec: {}
1340+
status:
1341+
observedRevisionGeneration: 5
1342+
desiredRevision: rev-1
1343+
revisions:
1344+
- name: rev-1
1345+
revision: 1
1346+
contentID: content-1
1347+
components:
1348+
- type: Image
1349+
image:
1350+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1351+
profile: default
1352+
updated: |
1353+
apiVersion: operator.openshift.io/v1alpha1
1354+
kind: ClusterAPI
1355+
metadata:
1356+
name: cluster
1357+
spec: {}
1358+
status:
1359+
observedRevisionGeneration: 3
1360+
desiredRevision: rev-1
1361+
revisions:
1362+
- name: rev-1
1363+
revision: 1
1364+
contentID: content-1
1365+
components:
1366+
- type: Image
1367+
image:
1368+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1369+
profile: default
1370+
expectedStatusError: "observedRevisionGeneration may not decrease"
1371+
1372+
- name: Should reject unsetting observedGeneration once set
1373+
initial: |
1374+
apiVersion: operator.openshift.io/v1alpha1
1375+
kind: ClusterAPI
1376+
metadata:
1377+
name: cluster
1378+
spec: {}
1379+
status:
1380+
observedRevisionGeneration: 1
1381+
desiredRevision: rev-1
1382+
revisions:
1383+
- name: rev-1
1384+
revision: 1
1385+
contentID: content-1
1386+
components:
1387+
- type: Image
1388+
image:
1389+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1390+
profile: default
1391+
updated: |
1392+
apiVersion: operator.openshift.io/v1alpha1
1393+
kind: ClusterAPI
1394+
metadata:
1395+
name: cluster
1396+
spec: {}
1397+
status:
1398+
desiredRevision: rev-1
1399+
revisions:
1400+
- name: rev-1
1401+
revision: 1
1402+
contentID: content-1
1403+
components:
1404+
- type: Image
1405+
image:
1406+
ref: quay.io/openshift/cluster-api@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1407+
profile: default
1408+
expectedStatusError: "observedRevisionGeneration may not be unset once set"

operator/v1alpha1/types_clusterapi.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
// 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.
2121
// +openshift:compatibility-gen:level=4
2222
// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="clusterapi is a singleton, .metadata.name must be 'cluster'"
23+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.status) || has(self.status)",message="status may not be removed once set"
2324
type ClusterAPI struct {
2425
metav1.TypeMeta `json:",inline"`
2526

@@ -78,6 +79,7 @@ type RevisionName string
7879
// ClusterAPIStatus describes the current state of the capi-operator.
7980
// +kubebuilder:validation:XValidation:rule="self.revisions.exists(r, r.name == self.desiredRevision && self.revisions.all(s, s.revision <= r.revision))",message="desiredRevision must be the name of the revision with the highest revision number"
8081
// +kubebuilder:validation:XValidation:rule="!has(self.currentRevision) || self.revisions.exists(r, r.name == self.currentRevision)",message="currentRevision must correspond to an entry in the revisions list"
82+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.observedRevisionGeneration) || has(self.observedRevisionGeneration)",message="observedRevisionGeneration may not be unset once set"
8183
type ClusterAPIStatus struct {
8284
// currentRevision is the name of the most recently fully applied revision.
8385
// It is written by the installer controller. If it is absent, it indicates
@@ -111,6 +113,15 @@ type ClusterAPIStatus struct {
111113
// +kubebuilder:validation:XValidation:rule="self.all(new, oldSelf.exists(old, old.name == new.name) || oldSelf.all(old, new.revision > old.revision))",message="new revisions must have a revision number greater than all existing revisions"
112114
// +kubebuilder:validation:XValidation:rule="oldSelf.all(old, !self.exists(new, new.name == old.name) || self.exists(new, new == old))",message="existing revisions are immutable, but may be removed"
113115
Revisions []ClusterAPIInstallerRevision `json:"revisions,omitempty"`
116+
117+
// observedRevisionGeneration is the generation of the ClusterAPI object that was last observed by the revision controller.
118+
// If specified it must be greater than or equal to 1, and less than 2^53. It may not decrease or be unset once set.
119+
//
120+
// +optional
121+
// +kubebuilder:validation:Minimum=1
122+
// +kubebuilder:validation:Maximum=9007199254740991
123+
// +kubebuilder:validation:XValidation:rule="self >= oldSelf",message="observedRevisionGeneration may not decrease"
124+
ObservedRevisionGeneration int64 `json:"observedRevisionGeneration,omitempty"`
114125
}
115126

116127
// +structType=atomic

operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ spec:
106106
maxLength: 255
107107
minLength: 1
108108
type: string
109+
observedRevisionGeneration:
110+
description: |-
111+
observedRevisionGeneration is the generation of the ClusterAPI object that was last observed by the revision controller.
112+
If specified it must be greater than or equal to 1, and less than 2^53. It may not decrease or be unset once set.
113+
format: int64
114+
maximum: 9007199254740991
115+
minimum: 1
116+
type: integer
117+
x-kubernetes-validations:
118+
- message: observedRevisionGeneration may not decrease
119+
rule: self >= oldSelf
109120
revisions:
110121
description: |-
111122
revisions is a list of all currently active revisions. A revision is
@@ -315,13 +326,17 @@ spec:
315326
list
316327
rule: '!has(self.currentRevision) || self.revisions.exists(r, r.name
317328
== self.currentRevision)'
329+
- message: observedRevisionGeneration may not be unset once set
330+
rule: '!has(oldSelf.observedRevisionGeneration) || has(self.observedRevisionGeneration)'
318331
required:
319332
- metadata
320333
- spec
321334
type: object
322335
x-kubernetes-validations:
323336
- message: clusterapi is a singleton, .metadata.name must be 'cluster'
324337
rule: self.metadata.name == 'cluster'
338+
- message: status may not be removed once set
339+
rule: '!has(oldSelf.status) || has(self.status)'
325340
served: true
326341
storage: true
327342
subresources:

operator/v1alpha1/zz_generated.featuregated-crd-manifests/clusterapis.operator.openshift.io/ClusterAPIMachineManagement.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ spec:
107107
maxLength: 255
108108
minLength: 1
109109
type: string
110+
observedRevisionGeneration:
111+
description: |-
112+
observedRevisionGeneration is the generation of the ClusterAPI object that was last observed by the revision controller.
113+
If specified it must be greater than or equal to 1, and less than 2^53. It may not decrease or be unset once set.
114+
format: int64
115+
maximum: 9007199254740991
116+
minimum: 1
117+
type: integer
118+
x-kubernetes-validations:
119+
- message: observedRevisionGeneration may not decrease
120+
rule: self >= oldSelf
110121
revisions:
111122
description: |-
112123
revisions is a list of all currently active revisions. A revision is
@@ -316,13 +327,17 @@ spec:
316327
list
317328
rule: '!has(self.currentRevision) || self.revisions.exists(r, r.name
318329
== self.currentRevision)'
330+
- message: observedRevisionGeneration may not be unset once set
331+
rule: '!has(oldSelf.observedRevisionGeneration) || has(self.observedRevisionGeneration)'
319332
required:
320333
- metadata
321334
- spec
322335
type: object
323336
x-kubernetes-validations:
324337
- message: clusterapi is a singleton, .metadata.name must be 'cluster'
325338
rule: self.metadata.name == 'cluster'
339+
- message: status may not be removed once set
340+
rule: '!has(oldSelf.status) || has(self.status)'
326341
served: true
327342
storage: true
328343
subresources:

operator/v1alpha1/zz_generated.swagger_doc_generated.go

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

payload-manifests/crds/0000_30_cluster-api_01_clusterapis.crd.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ spec:
106106
maxLength: 255
107107
minLength: 1
108108
type: string
109+
observedRevisionGeneration:
110+
description: |-
111+
observedRevisionGeneration is the generation of the ClusterAPI object that was last observed by the revision controller.
112+
If specified it must be greater than or equal to 1, and less than 2^53. It may not decrease or be unset once set.
113+
format: int64
114+
maximum: 9007199254740991
115+
minimum: 1
116+
type: integer
117+
x-kubernetes-validations:
118+
- message: observedRevisionGeneration may not decrease
119+
rule: self >= oldSelf
109120
revisions:
110121
description: |-
111122
revisions is a list of all currently active revisions. A revision is
@@ -315,13 +326,17 @@ spec:
315326
list
316327
rule: '!has(self.currentRevision) || self.revisions.exists(r, r.name
317328
== self.currentRevision)'
329+
- message: observedRevisionGeneration may not be unset once set
330+
rule: '!has(oldSelf.observedRevisionGeneration) || has(self.observedRevisionGeneration)'
318331
required:
319332
- metadata
320333
- spec
321334
type: object
322335
x-kubernetes-validations:
323336
- message: clusterapi is a singleton, .metadata.name must be 'cluster'
324337
rule: self.metadata.name == 'cluster'
338+
- message: status may not be removed once set
339+
rule: '!has(oldSelf.status) || has(self.status)'
325340
served: true
326341
storage: true
327342
subresources:

0 commit comments

Comments
 (0)