From c56f07672bea7f51c74c037764a4d3d63c8c3cd1 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Mon, 4 Nov 2019 11:44:03 +0100 Subject: [PATCH] apiextensions-apiserver: promote defaulting to GA --- pkg/features/kube_features.go | 2 +- .../apiextensions/validation/validation.go | 3 - .../validation/validation_test.go | 505 ------------------ .../pkg/features/kube_features.go | 6 +- 4 files changed, 6 insertions(+), 510 deletions(-) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index a0e6312d152..976595cf7f5 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -593,7 +593,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS apiextensionsfeatures.CustomResourceSubresources: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, apiextensionsfeatures.CustomResourceWebhookConversion: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, apiextensionsfeatures.CustomResourcePublishOpenAPI: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - apiextensionsfeatures.CustomResourceDefaulting: {Default: true, PreRelease: featuregate.Beta}, + apiextensionsfeatures.CustomResourceDefaulting: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // TODO: remove in 1.18 // features that enable backwards compatibility but are scheduled to be removed // ... diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go index c3d29df6f26..688f7b494a0 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go @@ -1048,9 +1048,6 @@ func allowDefaults(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.Cust // don't tighten validation on existing persisted data return true } - if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceDefaulting) { - return false - } if requestGV == apiextensionsv1beta1.SchemeGroupVersion { return false } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go index 3678c485ca2..3359213bfc2 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go @@ -1613,44 +1613,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { invalid("spec", "versions[3]", "subresources", "scale", "labelSelectorPath"), }, }, - { - name: "defaults with disabled feature gate", - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - errors: []validationMatch{ - forbidden("spec", "validation", "openAPIV3Schema", "properties[a]", "default"), // disabled feature-gate - }, - }, { name: "defaults with enabled feature gate via v1beta1", resource: &apiextensions.CustomResourceDefinition{ @@ -5871,473 +5833,6 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { errors: []validationMatch{}, enabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, }, - { - name: "ratcheting validation of defaults with disabled feature gate via v1beta1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - "b": { - Type: "number", - Default: jsonPtr(43.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - }, - { - name: "ratcheting validation of defaults with disabled feature gate via v1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - "b": { - Type: "number", - Default: jsonPtr(43.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - }, - { - name: "ratcheting validation of defaults with disabled feature gate via v1, non-structural, no defaults before", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": {}, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{ - forbidden("spec", "validation", "openAPIV3Schema", "properties[a]", "default"), - }, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - }, - { - name: "ratcheting validation of defaults with disabled feature gate via v1, unpruned => unpruned", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "unknown": "unknown", - }), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "unknown": "unknown", - }), - }, - "b": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "unknown": "unknown", - }), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - }, - { - name: "ratcheting validation of defaults with disabled feature gate via v1, pruned => unpruned", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "foo": "foo", - }), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "foo": "foo", - }), - }, - "b": { - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - Default: jsonPtr(map[string]interface{}{ - "unknown": "unknown", - }), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{ - invalid("spec", "validation", "openAPIV3Schema", "properties[b]", "default"), - }, - disabledFeatures: []featuregate.Feature{features.CustomResourceDefaulting}, - }, { name: "add default with enabled feature gate, structural schema, without pruning", old: &apiextensions.CustomResourceDefinition{ diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go index 178e91eedc2..dd5a3a48a03 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go @@ -62,8 +62,12 @@ const ( // owner: @sttts // alpha: v1.15 + // beta: v1.16 + // GA: v1.17 // // CustomResourceDefaulting enables OpenAPI defaulting in CustomResources. + // + // TODO: remove in 1.18 CustomResourceDefaulting featuregate.Feature = "CustomResourceDefaulting" ) @@ -79,5 +83,5 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS CustomResourceSubresources: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, CustomResourceWebhookConversion: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, CustomResourcePublishOpenAPI: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - CustomResourceDefaulting: {Default: true, PreRelease: featuregate.Beta}, + CustomResourceDefaulting: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }