Commit 9e8ab90d authored by Darren Shepherd's avatar Darren Shepherd

Remove CustomResourceWebhookConversion

parent 5931adaa
...@@ -298,7 +298,6 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS ...@@ -298,7 +298,6 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
// unintentionally on either side: // unintentionally on either side:
apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
apiextensionsfeatures.CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, apiextensionsfeatures.CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta},
apiextensionsfeatures.CustomResourceWebhookConversion: {Default: false, PreRelease: utilfeature.Alpha},
// features that enable backwards compatibility but are scheduled to be removed // features that enable backwards compatibility but are scheduled to be removed
// ... // ...
......
...@@ -244,11 +244,7 @@ func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceCo ...@@ -244,11 +244,7 @@ func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceCo
allErrs = append(allErrs, validateEnumStrings(fldPath.Child("strategy"), string(conversion.Strategy), []string{string(apiextensions.NoneConverter), string(apiextensions.WebhookConverter)}, true)...) allErrs = append(allErrs, validateEnumStrings(fldPath.Child("strategy"), string(conversion.Strategy), []string{string(apiextensions.NoneConverter), string(apiextensions.WebhookConverter)}, true)...)
if conversion.Strategy == apiextensions.WebhookConverter { if conversion.Strategy == apiextensions.WebhookConverter {
if conversion.WebhookClientConfig == nil { if conversion.WebhookClientConfig == nil {
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook"))
} else {
allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook, but not allowed because the CustomResourceWebhookConversion feature is disabled")) allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook, but not allowed because the CustomResourceWebhookConversion feature is disabled"))
}
} else { } else {
cc := conversion.WebhookClientConfig cc := conversion.WebhookClientConfig
switch { switch {
......
...@@ -20,31 +20,19 @@ import ( ...@@ -20,31 +20,19 @@ import (
"fmt" "fmt"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/util/webhook" "k8s.io/apiserver/pkg/util/webhook"
) )
// CRConverterFactory is the factory for all CR converters. // CRConverterFactory is the factory for all CR converters.
type CRConverterFactory struct { type CRConverterFactory struct {
// webhookConverterFactory is the factory for webhook converters.
// This field should not be used if CustomResourceWebhookConversion feature is disabled.
webhookConverterFactory *webhookConverterFactory
} }
// NewCRConverterFactory creates a new CRConverterFactory // NewCRConverterFactory creates a new CRConverterFactory
func NewCRConverterFactory(serviceResolver webhook.ServiceResolver, authResolverWrapper webhook.AuthenticationInfoResolverWrapper) (*CRConverterFactory, error) { func NewCRConverterFactory(serviceResolver webhook.ServiceResolver, authResolverWrapper webhook.AuthenticationInfoResolverWrapper) (*CRConverterFactory, error) {
converterFactory := &CRConverterFactory{} converterFactory := &CRConverterFactory{}
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
webhookConverterFactory, err := newWebhookConverterFactory(serviceResolver, authResolverWrapper)
if err != nil {
return nil, err
}
converterFactory.webhookConverterFactory = webhookConverterFactory
}
return converterFactory, nil return converterFactory, nil
} }
...@@ -65,15 +53,8 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin ...@@ -65,15 +53,8 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensions.CustomResourceDefin
} }
return &safeConverterWrapper{unsafe}, unsafe, nil return &safeConverterWrapper{unsafe}, unsafe, nil
case apiextensions.WebhookConverter: case apiextensions.WebhookConverter:
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
return nil, nil, fmt.Errorf("webhook conversion is disabled on this cluster") return nil, nil, fmt.Errorf("webhook conversion is disabled on this cluster")
} }
unsafe, err := m.webhookConverterFactory.NewWebhookConverter(validVersions, crd)
if err != nil {
return nil, nil, err
}
return &safeConverterWrapper{unsafe}, unsafe, nil
}
return nil, nil, fmt.Errorf("unknown conversion strategy %q for CRD %s", crd.Spec.Conversion.Strategy, crd.Name) return nil, nil, fmt.Errorf("unknown conversion strategy %q for CRD %s", crd.Spec.Conversion.Strategy, crd.Name)
} }
......
...@@ -40,12 +40,6 @@ const ( ...@@ -40,12 +40,6 @@ const (
// //
// CustomResourceSubresources defines the subresources for CustomResources // CustomResourceSubresources defines the subresources for CustomResources
CustomResourceSubresources utilfeature.Feature = "CustomResourceSubresources" CustomResourceSubresources utilfeature.Feature = "CustomResourceSubresources"
// owner: @mbohlool, @roycaihw
// alpha: v1.13
//
// CustomResourceWebhookConversion defines the webhook conversion for Custom Resources.
CustomResourceWebhookConversion utilfeature.Feature = "CustomResourceWebhookConversion"
) )
func init() { func init() {
...@@ -58,5 +52,4 @@ func init() { ...@@ -58,5 +52,4 @@ func init() {
var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{
CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta}, CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta},
CustomResourceWebhookConversion: {Default: false, PreRelease: utilfeature.Alpha},
} }
...@@ -67,17 +67,12 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { ...@@ -67,17 +67,12 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
crd.Spec.Versions[i].Subresources = nil 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 { for i := range crd.Spec.Versions {
crd.Spec.Versions[i].Schema = nil crd.Spec.Versions[i].Schema = nil
crd.Spec.Versions[i].Subresources = nil crd.Spec.Versions[i].Subresources = nil
crd.Spec.Versions[i].AdditionalPrinterColumns = nil crd.Spec.Versions[i].AdditionalPrinterColumns = nil
} }
} if crd.Spec.Conversion != nil {
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && crd.Spec.Conversion != nil {
crd.Spec.Conversion.WebhookClientConfig = nil crd.Spec.Conversion.WebhookClientConfig = nil
} }
...@@ -130,20 +125,14 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { ...@@ -130,20 +125,14 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
} }
} }
// On UPDATE, if the CustomResourceWebhookConversion feature gate is off, we auto-clear if !hasPerVersionField(oldCRD.Spec.Versions) {
// 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 { for i := range newCRD.Spec.Versions {
newCRD.Spec.Versions[i].Schema = nil newCRD.Spec.Versions[i].Schema = nil
newCRD.Spec.Versions[i].Subresources = nil newCRD.Spec.Versions[i].Subresources = nil
newCRD.Spec.Versions[i].AdditionalPrinterColumns = nil newCRD.Spec.Versions[i].AdditionalPrinterColumns = nil
} }
} }
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && newCRD.Spec.Conversion != nil { if newCRD.Spec.Conversion != nil {
if oldCRD.Spec.Conversion == nil || newCRD.Spec.Conversion.WebhookClientConfig == nil { if oldCRD.Spec.Conversion == nil || newCRD.Spec.Conversion.WebhookClientConfig == nil {
newCRD.Spec.Conversion.WebhookClientConfig = nil newCRD.Spec.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