Commit 2fcf4186 authored by yue9944882's avatar yue9944882

drop crd api fields

parent 111d4eac
......@@ -196,18 +196,8 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi
}
allErrs = append(allErrs, ValidateCustomResourceDefinitionNames(&spec.Names, fldPath.Child("names"))...)
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) {
allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(spec.Validation, hasAnyStatusEnabled(spec), fldPath.Child("validation"))...)
} else if spec.Validation != nil {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("validation"), "disabled by feature-gate CustomResourceValidation"))
}
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
allErrs = append(allErrs, ValidateCustomResourceDefinitionSubresources(spec.Subresources, fldPath.Child("subresources"))...)
} else if spec.Subresources != nil {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("subresources"), "disabled by feature-gate CustomResourceSubresources"))
}
allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(spec.Validation, hasAnyStatusEnabled(spec), fldPath.Child("validation"))...)
allErrs = append(allErrs, ValidateCustomResourceDefinitionSubresources(spec.Subresources, fldPath.Child("subresources"))...)
for i := range spec.AdditionalPrinterColumns {
if errs := ValidateCustomResourceColumnDefinition(&spec.AdditionalPrinterColumns[i], fldPath.Child("additionalPrinterColumns").Index(i)); len(errs) > 0 {
......@@ -481,7 +471,7 @@ func ValidateCustomResourceDefinitionValidation(customResourceValidation *apiext
if schema := customResourceValidation.OpenAPIV3Schema; schema != nil {
// if the status subresource is enabled, only certain fields are allowed inside the root schema.
// these fields are chosen such that, if status is extracted as properties["status"], it's validation is not lost.
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && statusSubresourceEnabled {
if statusSubresourceEnabled {
v := reflect.ValueOf(schema).Elem()
for i := 0; i < v.NumField(); i++ {
// skip zero values
......
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
......@@ -47,3 +44,16 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["strategy_test.go"],
embed = [":go_default_library"],
deps = [
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
],
)
......@@ -54,32 +54,7 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
crd.Status = apiextensions.CustomResourceDefinitionStatus{}
crd.Generation = 1
// if the feature gate is disabled, drop the feature.
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) {
crd.Spec.Validation = nil
for i := range crd.Spec.Versions {
crd.Spec.Versions[i].Schema = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
crd.Spec.Subresources = nil
for i := range crd.Spec.Versions {
crd.Spec.Versions[i].Subresources = nil
}
}
// On CREATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear
// the per-version fields. This is to be consistent with the other built-in types, as the
// apiserver drops unknown fields.
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
for i := range crd.Spec.Versions {
crd.Spec.Versions[i].Schema = nil
crd.Spec.Versions[i].Subresources = nil
crd.Spec.Versions[i].AdditionalPrinterColumns = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && crd.Spec.Conversion != nil {
crd.Spec.Conversion.WebhookClientConfig = nil
}
dropDisabledFields(&crd.Spec, nil)
for _, v := range crd.Spec.Versions {
if v.Storage {
......@@ -109,45 +84,7 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
newCRD.Generation = oldCRD.Generation + 1
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) {
newCRD.Spec.Validation = nil
oldCRD.Spec.Validation = nil
for i := range newCRD.Spec.Versions {
newCRD.Spec.Versions[i].Schema = nil
}
for i := range oldCRD.Spec.Versions {
oldCRD.Spec.Versions[i].Schema = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
newCRD.Spec.Subresources = nil
oldCRD.Spec.Subresources = nil
for i := range newCRD.Spec.Versions {
newCRD.Spec.Versions[i].Subresources = nil
}
for i := range oldCRD.Spec.Versions {
oldCRD.Spec.Versions[i].Subresources = nil
}
}
// On UPDATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear
// the per-version fields if the old CRD doesn't use per-version fields already.
// This is to be consistent with the other built-in types, as the apiserver drops unknown
// fields. If the old CRD already uses per-version fields, the CRD is allowed to continue
// use per-version fields.
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) &&
!hasPerVersionField(oldCRD.Spec.Versions) {
for i := range newCRD.Spec.Versions {
newCRD.Spec.Versions[i].Schema = nil
newCRD.Spec.Versions[i].Subresources = nil
newCRD.Spec.Versions[i].AdditionalPrinterColumns = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && newCRD.Spec.Conversion != nil {
if oldCRD.Spec.Conversion == nil || newCRD.Spec.Conversion.WebhookClientConfig == nil {
newCRD.Spec.Conversion.WebhookClientConfig = nil
}
}
dropDisabledFields(&newCRD.Spec, &oldCRD.Spec)
for _, v := range newCRD.Spec.Versions {
if v.Storage {
......@@ -159,16 +96,6 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
}
}
// hasPerVersionField returns true if a CRD uses per-version schema/subresources/columns fields.
func hasPerVersionField(versions []apiextensions.CustomResourceDefinitionVersion) bool {
for _, v := range versions {
if v.Schema != nil || v.Subresources != nil || len(v.AdditionalPrinterColumns) > 0 {
return true
}
}
return false
}
// Validate validates a new CustomResourceDefinition.
func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
return validation.ValidateCustomResourceDefinition(obj.(*apiextensions.CustomResourceDefinition))
......@@ -259,3 +186,102 @@ func MatchCustomResourceDefinition(label labels.Selector, field fields.Selector)
func CustomResourceDefinitionToSelectableFields(obj *apiextensions.CustomResourceDefinition) fields.Set {
return generic.ObjectMetaFieldsSet(&obj.ObjectMeta, true)
}
func dropDisabledFields(crdSpec, oldCrdSpec *apiextensions.CustomResourceDefinitionSpec) {
// if the feature gate is disabled, drop the feature.
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) &&
!validationInUse(oldCrdSpec) {
crdSpec.Validation = nil
for i := range crdSpec.Versions {
crdSpec.Versions[i].Schema = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) &&
!subresourceInUse(oldCrdSpec) {
crdSpec.Subresources = nil
for i := range crdSpec.Versions {
crdSpec.Versions[i].Subresources = nil
}
}
// 1. On CREATE (in which case the old CRD spec is nil), if the CustomResourceWebhookConversion feature gate is off, we auto-clear
// the per-version fields. This is to be consistent with the other built-in types, as the
// apiserver drops unknown fields.
// 2. On UPDATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear
// the per-version fields if the old CRD doesn't use per-version fields already.
// This is to be consistent with the other built-in types, as the apiserver drops unknown
// fields. If the old CRD already uses per-version fields, the CRD is allowed to continue
// use per-version fields.
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) &&
!hasPerVersionField(oldCrdSpec) {
for i := range crdSpec.Versions {
crdSpec.Versions[i].Schema = nil
crdSpec.Versions[i].Subresources = nil
crdSpec.Versions[i].AdditionalPrinterColumns = nil
}
}
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) &&
!conversionWebhookInUse(oldCrdSpec) {
if crdSpec.Conversion != nil {
crdSpec.Conversion.WebhookClientConfig = nil
}
}
}
func validationInUse(crdSpec *apiextensions.CustomResourceDefinitionSpec) bool {
if crdSpec == nil {
return false
}
if crdSpec.Validation != nil {
return true
}
for i := range crdSpec.Versions {
if crdSpec.Versions[i].Schema != nil {
return true
}
}
return false
}
func subresourceInUse(crdSpec *apiextensions.CustomResourceDefinitionSpec) bool {
if crdSpec == nil {
return false
}
if crdSpec.Subresources != nil {
return true
}
for i := range crdSpec.Versions {
if crdSpec.Versions[i].Subresources != nil {
return true
}
}
return false
}
// hasPerVersionField returns true if a CRD uses per-version schema/subresources/columns fields.
//func hasPerVersionField(versions []apiextensions.CustomResourceDefinitionVersion) bool {
func hasPerVersionField(crdSpec *apiextensions.CustomResourceDefinitionSpec) bool {
if crdSpec == nil {
return false
}
for _, v := range crdSpec.Versions {
if v.Schema != nil || v.Subresources != nil || len(v.AdditionalPrinterColumns) > 0 {
return true
}
}
return false
}
func conversionWebhookInUse(crdSpec *apiextensions.CustomResourceDefinitionSpec) bool {
if crdSpec == nil {
return false
}
if crdSpec.Conversion == nil {
return false
}
return crdSpec.Conversion.WebhookClientConfig != nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment