From cbe3d897629691507c2992659ca748e32366da1a Mon Sep 17 00:00:00 2001 From: Cici Huang Date: Thu, 19 Oct 2023 20:31:17 +0000 Subject: [PATCH 1/2] Promote CRD validation rule to stable --- pkg/features/kube_features.go | 2 +- staging/src/k8s.io/apiserver/pkg/features/kube_features.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 65765d3e8d9..d78e2da640b 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -1126,7 +1126,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS genericfeatures.ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Beta}, - genericfeatures.CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.Beta}, + genericfeatures.CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31 genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta}, diff --git a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go index c7d699d5405..65ec542de50 100644 --- a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go +++ b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go @@ -100,6 +100,7 @@ const ( // kep: https://kep.k8s.io/2876 // alpha: v1.23 // beta: v1.25 + // stable: v1.29 // // Enables expression validation for Custom Resource CustomResourceValidationExpressions featuregate.Feature = "CustomResourceValidationExpressions" @@ -284,7 +285,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Beta}, - CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.Beta}, + CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31 EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, From f71040f620eaa4d98813681bf14558912d55f388 Mon Sep 17 00:00:00 2001 From: Cici Huang Date: Wed, 25 Oct 2023 17:05:00 +0000 Subject: [PATCH 2/2] Remove the usage of feature gate --- .../customresourcedefinition/strategy.go | 57 -- .../customresourcedefinition/strategy_test.go | 485 ------------------ .../crd_validation_expressions_test.go | 34 -- 3 files changed, 576 deletions(-) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go index 396fedc114c..1144d4225d7 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go @@ -30,11 +30,9 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" - utilfeature "k8s.io/apiserver/pkg/util/feature" ) // strategy implements behavior for CustomResources. @@ -80,8 +78,6 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { break } } - - dropDisabledFields(crd, nil) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -110,8 +106,6 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { break } } - - dropDisabledFields(newCRD, oldCRD) } // Validate validates a new CustomResourceDefinition. @@ -229,54 +223,3 @@ func MatchCustomResourceDefinition(label labels.Selector, field fields.Selector) func CustomResourceDefinitionToSelectableFields(obj *apiextensions.CustomResourceDefinition) fields.Set { return generic.ObjectMetaFieldsSet(&obj.ObjectMeta, true) } - -// dropDisabledFields drops disabled fields that are not used if their associated feature gates -// are not enabled. -func dropDisabledFields(newCRD *apiextensions.CustomResourceDefinition, oldCRD *apiextensions.CustomResourceDefinition) { - if !utilfeature.DefaultFeatureGate.Enabled(features.CustomResourceValidationExpressions) && (oldCRD == nil || (oldCRD != nil && !specHasXValidations(&oldCRD.Spec))) { - if newCRD.Spec.Validation != nil { - dropXValidationsField(newCRD.Spec.Validation.OpenAPIV3Schema) - } - for _, v := range newCRD.Spec.Versions { - if v.Schema != nil { - dropXValidationsField(v.Schema.OpenAPIV3Schema) - } - } - } -} - -// dropXValidationsField drops field XValidations from CRD schema -func dropXValidationsField(schema *apiextensions.JSONSchemaProps) { - if schema == nil { - return - } - schema.XValidations = nil - if schema.AdditionalProperties != nil { - dropXValidationsField(schema.AdditionalProperties.Schema) - } - for def, jsonSchema := range schema.Properties { - dropXValidationsField(&jsonSchema) - schema.Properties[def] = jsonSchema - } - if schema.Items != nil { - dropXValidationsField(schema.Items.Schema) - for i, jsonSchema := range schema.Items.JSONSchemas { - dropXValidationsField(&jsonSchema) - schema.Items.JSONSchemas[i] = jsonSchema - } - } - for def, jsonSchemaPropsOrStringArray := range schema.Dependencies { - dropXValidationsField(jsonSchemaPropsOrStringArray.Schema) - schema.Dependencies[def] = jsonSchemaPropsOrStringArray - } -} - -func specHasXValidations(spec *apiextensions.CustomResourceDefinitionSpec) bool { - return validation.HasSchemaWith(spec, schemaHasXValidations) -} - -func schemaHasXValidations(s *apiextensions.JSONSchemaProps) bool { - return validation.SchemaHas(s, func(s *apiextensions.JSONSchemaProps) bool { - return s.XValidations != nil - }) -} diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go index a1699302333..54362768c09 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go @@ -20,16 +20,11 @@ import ( "context" "testing" - "github.com/google/go-cmp/cmp" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/utils/pointer" ) @@ -194,483 +189,3 @@ func TestValidateAPIApproval(t *testing.T) { }) } } - -// TestDropDisabledFields tests if the drop functionality is working fine or not with feature gate switch -func TestDropDisabledFields(t *testing.T) { - testCases := []struct { - name string - enableXValidations bool - crd *apiextensions.CustomResourceDefinition - oldCRD *apiextensions.CustomResourceDefinition - expectedCRD *apiextensions.CustomResourceDefinition - }{ - { - name: "For creation, FG disabled, no XValidations, no field drop", - enableXValidations: false, - crd: &apiextensions.CustomResourceDefinition{}, - oldCRD: nil, - expectedCRD: &apiextensions.CustomResourceDefinition{}, - }, - { - name: "For creation, FG disabled, empty XValidations, no field drop", - enableXValidations: false, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{}, - }, - }, - oldCRD: nil, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{}, - }, - }, - }, - { - name: "For creation, FG disabled, set XValidations, drop XValidations", - enableXValidations: false, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "isTest == true", - Message: "isTest should be true.", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - oldCRD: nil, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "For creation, FG enabled, set XValidations, update with XValidations", - enableXValidations: true, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "isTest == true", - Message: "isTest should be true.", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - oldCRD: nil, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "isTest == true", - Message: "isTest should be true.", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "For update, FG disabled, oldCRD XValidation in use, don't drop XValidations", - enableXValidations: false, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "isTest == true", - Message: "isTest should be true.", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - oldCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - }, - }, - }, - }, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - Dependencies: apiextensions.JSONSchemaDependencies{ - "test": apiextensions.JSONSchemaPropsOrStringArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "size of scoped field should be greater than 0.", - }, - }, - }, - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "subRule": { - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "isTest == true", - Message: "isTest should be true.", - }, - }, - Properties: map[string]apiextensions.JSONSchemaProps{ - "isTest": { - Type: "boolean", - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "For update, FG disabled, oldCRD has no XValidations, drop XValidations", - enableXValidations: false, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - }, - }, - }, - }, - oldCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - }, - }, - }, - }, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - }, - }, - }, - }, - }, - { - name: "For update, FG enabled, oldCRD has XValidations, updated to newCRD", - enableXValidations: true, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - }, - }, - }, - }, - oldCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "old data", - Message: "old data", - }, - }, - }, - }, - }, - }, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - }, - }, - }, - }, - }, - { - name: "For update, FG enabled, oldCRD has no XValidations, updated to newCRD", - enableXValidations: true, - crd: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - }, - }, - }, - }, - oldCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - }, - }, - }, - }, - expectedCRD: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "foos.sigs.k8s.io", Annotations: map[string]string{v1beta1.KubeAPIApprovedAnnotation: "valid"}, ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - XValidations: apiextensions.ValidationRules{ - { - Rule: "size(self) > 0", - Message: "openAPIV3Schema should contain more than 0 element.", - }, - }, - }, - }, - }, - }, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceValidationExpressions, tc.enableXValidations)() - old := tc.oldCRD.DeepCopy() - - dropDisabledFields(tc.crd, tc.oldCRD) - - // old crd should never be changed - if diff := cmp.Diff(tc.oldCRD, old); diff != "" { - t.Fatalf("old crd changed from %v to %v", tc.oldCRD, old) - } - - if diff := cmp.Diff(tc.expectedCRD, tc.crd); diff != "" { - t.Fatalf("unexpected crd: %v", tc.crd) - } - }) - } -} diff --git a/test/integration/apiserver/crd_validation_expressions_test.go b/test/integration/apiserver/crd_validation_expressions_test.go index 9d1848e0969..778d99046d8 100644 --- a/test/integration/apiserver/crd_validation_expressions_test.go +++ b/test/integration/apiserver/crd_validation_expressions_test.go @@ -40,40 +40,6 @@ import ( "k8s.io/kubernetes/test/integration/framework" ) -// TestCustomResourceValidatorsWithDisabledFeatureGate test that x-kubernetes-validations work as expected when the -// feature gate is disabled. -func TestCustomResourceValidatorsWithDisabledFeatureGate(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.CustomResourceValidationExpressions, false)() - - server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) - if err != nil { - t.Fatal(err) - } - defer server.TearDownFn() - config := server.ClientConfig - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - dynamicClient, err := dynamic.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - - t.Run("x-kubernetes-validations fields MUST be dropped from CRDs that are created when feature gate is disabled", func(t *testing.T) { - schemaWithFeatureGateOff := crdWithSchema(t, "WithFeatureGateOff", structuralSchemaWithValidators) - crdWithFeatureGateOff, err := fixtures.CreateNewV1CustomResourceDefinition(schemaWithFeatureGateOff, apiExtensionClient, dynamicClient) - if err != nil { - t.Fatal(err) - } - s := crdWithFeatureGateOff.Spec.Versions[0].Schema.OpenAPIV3Schema - if len(s.XValidations) != 0 { - t.Errorf("Expected CRD to have no x-kubernetes-validatons rules but got: %v", s.XValidations) - } - }) -} - // TestCustomResourceValidators tests x-kubernetes-validations compile and validate as expected when the feature gate // is enabled. func TestCustomResourceValidators(t *testing.T) {