diff --git a/apiextensions/v1alpha1/tests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml b/apiextensions/v1alpha1/tests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml index 22c4707c2df..0edca863fb8 100644 --- a/apiextensions/v1alpha1/tests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml +++ b/apiextensions/v1alpha1/tests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml @@ -205,6 +205,43 @@ tests: versions: - v1alpha1 + - name: Should not be able to create CompatibilityRequirement with excluded fields with duplicate paths + initial: | + apiVersion: apiextensions.openshift.io/v1alpha1 + kind: CompatibilityRequirement + metadata: + name: test-requirement + spec: + compatibilitySchema: + customResourceDefinition: + type: YAML + data: | + apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + metadata: + name: testrequirements.example.com + spec: + group: example.com + names: + kind: TestRequirement + plural: testrequirements + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + requiredVersions: + defaultSelection: StorageOnly + excludedFields: + - path: spec.fieldToExclude + - path: spec.fieldToExclude + versions: + - v1alpha1 + expectedError: "spec.compatibilitySchema.excludedFields: Invalid value: \"array\": each path in the list must be unique." + - name: Should not be able to create CompatibilityRequirement with invalid excluded field path initial: | apiVersion: apiextensions.openshift.io/v1alpha1 diff --git a/apiextensions/v1alpha1/types_compatibilityrequirement.go b/apiextensions/v1alpha1/types_compatibilityrequirement.go index 5abbfec7c1a..0da25370a9b 100644 --- a/apiextensions/v1alpha1/types_compatibilityrequirement.go +++ b/apiextensions/v1alpha1/types_compatibilityrequirement.go @@ -185,9 +185,11 @@ type CompatibilitySchema struct { // excludedFields is a set of fields in the schema which will not be validated by // crdSchemaValidation or objectSchemaValidation. // The list may contain at most 64 fields. + // Each path in the list must be unique. // When not specified, all fields in the schema will be validated. // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=64 + // +kubebuilder:validation:XValidation:rule="self.all(x, self.exists_one(y, y.path == x.path))",message="each path in the list must be unique." // +listType=atomic // +optional ExcludedFields []APIExcludedField `json:"excludedFields,omitempty"` diff --git a/apiextensions/v1alpha1/zz_generated.crd-manifests/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml b/apiextensions/v1alpha1/zz_generated.crd-manifests/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml index 3b9564d2eef..8ae4185ee2f 100644 --- a/apiextensions/v1alpha1/zz_generated.crd-manifests/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml +++ b/apiextensions/v1alpha1/zz_generated.crd-manifests/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml @@ -84,6 +84,7 @@ spec: excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. + Each path in the list must be unique. When not specified, all fields in the schema will be validated. items: description: |- @@ -142,6 +143,9 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each path in the list must be unique. + rule: self.all(x, self.exists_one(y, y.path == x.path)) requiredVersions: description: |- requiredVersions specifies a subset of the CRD's API versions which will be asserted for compatibility. diff --git a/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml b/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml index fcd0f8c704e..72ce9442a1e 100644 --- a/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml +++ b/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests/compatibilityrequirements.apiextensions.openshift.io/CRDCompatibilityRequirementOperator.yaml @@ -85,6 +85,7 @@ spec: excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. + Each path in the list must be unique. When not specified, all fields in the schema will be validated. items: description: |- @@ -143,6 +144,9 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each path in the list must be unique. + rule: self.all(x, self.exists_one(y, y.path == x.path)) requiredVersions: description: |- requiredVersions specifies a subset of the CRD's API versions which will be asserted for compatibility. diff --git a/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go b/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go index a9a4e707e7a..d615ef28563 100644 --- a/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go @@ -88,7 +88,7 @@ var map_CompatibilitySchema = map[string]string{ "": "CompatibilitySchema defines the schema used by crdSchemaValidation and objectSchemaValidation.", "customResourceDefinition": "customResourceDefinition contains the complete definition of the CRD for schema and object validation purposes. This field is required.", "requiredVersions": "requiredVersions specifies a subset of the CRD's API versions which will be asserted for compatibility. This field is required.", - "excludedFields": "excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. When not specified, all fields in the schema will be validated.", + "excludedFields": "excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. Each path in the list must be unique. When not specified, all fields in the schema will be validated.", } func (CompatibilitySchema) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 7a4f6aabe13..c1e19bee92a 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -2042,7 +2042,7 @@ func schema_openshift_api_apiextensions_v1alpha1_CompatibilitySchema(ref common. }, }, SchemaProps: spec.SchemaProps{ - Description: "excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. When not specified, all fields in the schema will be validated.", + Description: "excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. Each path in the list must be unique. When not specified, all fields in the schema will be validated.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/payload-manifests/crds/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml b/payload-manifests/crds/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml index 3b9564d2eef..8ae4185ee2f 100644 --- a/payload-manifests/crds/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml +++ b/payload-manifests/crds/0000_20_crd-compatibility-checker_01_compatibilityrequirements.crd.yaml @@ -84,6 +84,7 @@ spec: excludedFields is a set of fields in the schema which will not be validated by crdSchemaValidation or objectSchemaValidation. The list may contain at most 64 fields. + Each path in the list must be unique. When not specified, all fields in the schema will be validated. items: description: |- @@ -142,6 +143,9 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: each path in the list must be unique. + rule: self.all(x, self.exists_one(y, y.path == x.path)) requiredVersions: description: |- requiredVersions specifies a subset of the CRD's API versions which will be asserted for compatibility.