From 949cd5734212c5b6d6121e6a83b7889fedc8b27e Mon Sep 17 00:00:00 2001 From: Predrag Knezevic Date: Wed, 1 Apr 2026 16:07:56 +0200 Subject: [PATCH] api: replace manual XValidation CEL rule with ExactlyOneOf marker on ClusterObjectSetObject Use the +kubebuilder:validation:ExactlyOneOf={object,ref} marker introduced in controller-tools v0.19.0 instead of a hand-written CEL XValidation rule. The generated CEL expression is semantically equivalent. Co-Authored-By: Claude Opus 4.6 --- api/v1/clusterobjectset_types.go | 2 +- .../olm.operatorframework.io_clusterobjectsets.yaml | 6 ++++-- manifests/experimental-e2e.yaml | 6 ++++-- manifests/experimental.yaml | 6 ++++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/api/v1/clusterobjectset_types.go b/api/v1/clusterobjectset_types.go index a342e02f9e..ed1a4001e0 100644 --- a/api/v1/clusterobjectset_types.go +++ b/api/v1/clusterobjectset_types.go @@ -395,7 +395,7 @@ type ClusterObjectSetPhase struct { // // Exactly one of object or ref must be set. // -// +kubebuilder:validation:XValidation:rule="has(self.object) != has(self.ref)",message="exactly one of object or ref must be set" +// +kubebuilder:validation:ExactlyOneOf={object,ref} type ClusterObjectSetObject struct { // object is an optional embedded Kubernetes object to be applied. // diff --git a/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterobjectsets.yaml b/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterobjectsets.yaml index 4dd703fb2e..eb4f55a9ea 100644 --- a/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterobjectsets.yaml +++ b/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterobjectsets.yaml @@ -232,8 +232,10 @@ spec: type: object type: object x-kubernetes-validations: - - message: exactly one of object or ref must be set - rule: has(self.object) != has(self.ref) + - message: exactly one of the fields in [object ref] must + be set + rule: '[has(self.object),has(self.ref)].filter(x,x==true).size() + == 1' maxItems: 50 type: array required: diff --git a/manifests/experimental-e2e.yaml b/manifests/experimental-e2e.yaml index 45d773af4d..dcb4fac364 100644 --- a/manifests/experimental-e2e.yaml +++ b/manifests/experimental-e2e.yaml @@ -1556,8 +1556,10 @@ spec: type: object type: object x-kubernetes-validations: - - message: exactly one of object or ref must be set - rule: has(self.object) != has(self.ref) + - message: exactly one of the fields in [object ref] must + be set + rule: '[has(self.object),has(self.ref)].filter(x,x==true).size() + == 1' maxItems: 50 type: array required: diff --git a/manifests/experimental.yaml b/manifests/experimental.yaml index 9f8f6d8a9a..dc9a02a4f9 100644 --- a/manifests/experimental.yaml +++ b/manifests/experimental.yaml @@ -1517,8 +1517,10 @@ spec: type: object type: object x-kubernetes-validations: - - message: exactly one of object or ref must be set - rule: has(self.object) != has(self.ref) + - message: exactly one of the fields in [object ref] must + be set + rule: '[has(self.object),has(self.ref)].filter(x,x==true).size() + == 1' maxItems: 50 type: array required: