@@ -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,79 @@ 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: openshift-mapi-authoritative-api-transition-requires-capi-infrastructure-ready-and-not-deleting
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: openshift-mapi-authoritative-api-transition-requires-capi-infrastructure-ready-and-not-deleting
501+ validationActions: [Deny]
502+ ---
503+ apiVersion: admissionregistration.k8s.io/v1
504+ kind: ValidatingAdmissionPolicy
505+ metadata:
506+ name: openshift-mapi-authoritative-api-transition-requires-capi-infrastructure-ready-and-not-deleting
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.orValue(false)
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: "spec.authoritativeAPI may only be updated when the Cluster API Machine's status.infrastructureReady is true."
549+
550+ # Don't allow changing the AuthoritativeAPI if the CAPI Machine mirror is deleting
551+ - name: block-when-capi-deleting
552+ expression: >
553+ !(variables.authAPIChanged && variables.capiDeleting)
554+ message: "spec.authoritativeAPI cannot be modified while the corresponding CAPI Machine is being deleted (metadata.deletionTimestamp is set)."
482555 ---
483556apiVersion : v1
484557kind : ConfigMap
0 commit comments