@@ -108,7 +108,7 @@ data:
108108 ? p[1].hasValue() && p[0].value() == p[1].value()
109109 : !p[1].hasValue()
110110 )
111-
111+
112112 # All validations must evaluate to TRUE
113113 validations:
114114 # Only spec.authoritativeAPI may change
@@ -479,6 +479,83 @@ data:
479479 policyName: openshift-provide-warning-when-not-synchronized
480480 validationActions:
481481 - Warn
482+ ---
483+ apiVersion: admissionregistration.k8s.io/v1
484+ kind: ValidatingAdmissionPolicyBinding
485+ metadata:
486+ name: mapi-authapi-transition-requires-capi-ready
487+ spec:
488+ matchResources:
489+ namespaceSelector:
490+ matchLabels:
491+ kubernetes.io/metadata.name: openshift-machine-api
492+ paramRef:
493+ namespace: openshift-cluster-api
494+ # We 'Allow' here as we don't want to block MAPI Machine
495+ # functionality when no CAPI machine (param) exists.
496+ # This might happen when the synchronisation controller first
497+ # is installed or when an unmigrateable machine is encountered.
498+ parameterNotFoundAction: Allow
499+ selector: {}
500+ policyName: mapi-authapi-transition-requires-capi-ready
501+ validationActions: [Deny]
502+ ---
503+ apiVersion: admissionregistration.k8s.io/v1
504+ kind: ValidatingAdmissionPolicy
505+ metadata:
506+ name: mapi-authapi-transition-requires-capi-ready
507+ spec:
508+ failurePolicy: Fail
509+
510+ paramKind:
511+ apiVersion: cluster.x-k8s.io/v1beta1
512+ kind: Machine
513+
514+ matchConstraints:
515+ resourceRules:
516+ - apiGroups: ["machine.openshift.io"]
517+ apiVersions: ["v1beta1"]
518+ operations: ["UPDATE"]
519+ resources: ["machines"]
520+
521+ # Requests must satisfy every matchCondition to reach the validations
522+ matchConditions:
523+ - name: check-only-non-service-account-requests
524+ expression: >-
525+ !(request.userInfo.username in [
526+ "system:serviceaccount:openshift-machine-api:machine-api-controllers",
527+ "system:serviceaccount:openshift-cluster-api:cluster-capi-operator"
528+ ])
529+ - name: check-param-match
530+ expression: 'object.metadata.name == params.metadata.name'
531+
532+ variables:
533+ - name: authAPIChanged
534+ expression: oldObject.spec.authoritativeAPI != object.spec.authoritativeAPI
535+
536+ - name: capiInfraReady
537+ expression: params.status?.infrastructureReady == true
538+
539+ - name: capiDeleting
540+ expression: has(params.metadata.deletionTimestamp)
541+
542+ # All validations must evaluate to TRUE
543+ validations:
544+ # Don't allow changing the AuthoritativeAPI if the CAPI Machine mirror infrastructureReady is not true
545+ - name: block-when-not-infraReady
546+ expression: >
547+ !(variables.authAPIChanged && !variables.capiInfraReady)
548+ message: |
549+ spec.authoritativeAPI may only be updated when the Cluster API Machine’s
550+ status.infrastructureReady is true.
551+
552+ # Don't allow changing the AuthoritativeAPI if the CAPI Machine mirror is deleting
553+ - name: block-when-capi-deleting
554+ expression: >
555+ !(variables.authAPIChanged && variables.capiDeleting)
556+ message: |
557+ spec.authoritativeAPI cannot be modified while the corresponding
558+ CAPI Machine is being deleted (metadata.deletionTimestamp is set).
482559 ---
483560apiVersion : v1
484561kind : ConfigMap
0 commit comments