diff --git a/pkg/crd/markers/validation.go b/pkg/crd/markers/validation.go index c91f5e6a1..3e7e08a7e 100644 --- a/pkg/crd/markers/validation.go +++ b/pkg/crd/markers/validation.go @@ -666,6 +666,14 @@ func (m XValidation) ApplyToSchema(schema *apiext.JSONSchemaProps) error { } } + // Check if this validation rule already exists to prevent duplication + for _, existingRule := range schema.XValidations { + if existingRule.Rule == m.Rule { + // Rule already exists, don't add it again + return nil + } + } + schema.XValidations = append(schema.XValidations, apiext.ValidationRule{ Rule: m.Rule, Message: m.Message, diff --git a/pkg/crd/testdata/oneof/types.go b/pkg/crd/testdata/oneof/types.go index 430cc3a2d..0ca18f73b 100644 --- a/pkg/crd/testdata/oneof/types.go +++ b/pkg/crd/testdata/oneof/types.go @@ -36,6 +36,9 @@ type OneofSpec struct { TypeWithMultipleAtLeastOneofs *TypeWithMultipleAtLeastOneofs `json:"typeWithMultipleAtLeastOneOf,omitempty"` TypeWithAllOneOf *TypeWithAllOneofs `json:"typeWithAllOneOf,omitempty"` + + // The validation rule on TypeWithOneofs should not be duplicated. + SameTypeWithOneof *TypeWithOneofs `json:"sameTypeWithOneof,omitempty"` } // +kubebuilder:validation:XValidation:message="only one of foo|bar may be set",rule="!(has(self.foo) && has(self.bar))" diff --git a/pkg/crd/testdata/testdata.kubebuilder.io_oneofs.yaml b/pkg/crd/testdata/testdata.kubebuilder.io_oneofs.yaml index 3ae323948..8f11d1fb4 100644 --- a/pkg/crd/testdata/testdata.kubebuilder.io_oneofs.yaml +++ b/pkg/crd/testdata/testdata.kubebuilder.io_oneofs.yaml @@ -60,6 +60,20 @@ spec: - message: at most one of the fields in [foo bar] may be set rule: '[has(self.foo),has(self.bar)].filter(x,x==true).size() <= 1' + sameTypeWithOneof: + description: The validation rule on TypeWithOneofs should not be duplicated. + properties: + bar: + type: string + foo: + type: string + type: object + x-kubernetes-validations: + - message: only one of foo|bar may be set + rule: '!(has(self.foo) && has(self.bar))' + - message: at most one of the fields in [foo bar] may be set + rule: '[has(self.foo),has(self.bar)].filter(x,x==true).size() <= + 1' secondTypeWithExactOneof: properties: a: