mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Remove use of CustomResourceSubresources feature gate, CRD field clearing
This commit is contained in:
		@@ -15,7 +15,6 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
 | 
			
		||||
@@ -25,7 +24,6 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/rest:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -21,11 +21,9 @@ import (
 | 
			
		||||
 | 
			
		||||
	autoscalingv1 "k8s.io/api/autoscaling/v1"
 | 
			
		||||
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 | 
			
		||||
	apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
			
		||||
	"k8s.io/apiserver/pkg/util/webhook"
 | 
			
		||||
	typedscheme "k8s.io/client-go/kubernetes/scheme"
 | 
			
		||||
)
 | 
			
		||||
@@ -78,13 +76,11 @@ func (m *CRConverterFactory) NewConverter(crd *apiextensionsv1.CustomResourceDef
 | 
			
		||||
 | 
			
		||||
	// Determine whether we should expect to be asked to "convert" autoscaling/v1 Scale types
 | 
			
		||||
	convertScale := false
 | 
			
		||||
	if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
 | 
			
		||||
	for _, version := range crd.Spec.Versions {
 | 
			
		||||
		if version.Subresources != nil && version.Subresources.Scale != nil {
 | 
			
		||||
			convertScale = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsafe = &crConverter{
 | 
			
		||||
		convertScale:  convertScale,
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,6 @@ import (
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/crdserverscheme"
 | 
			
		||||
	apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/registry/customresource"
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor"
 | 
			
		||||
 | 
			
		||||
@@ -701,7 +700,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
 | 
			
		||||
			utilruntime.HandleError(err)
 | 
			
		||||
			return nil, fmt.Errorf("the server could not properly serve the CR subresources")
 | 
			
		||||
		}
 | 
			
		||||
		if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Status != nil {
 | 
			
		||||
		if subresources != nil && subresources.Status != nil {
 | 
			
		||||
			equivalentResourceRegistry.RegisterKindFor(resource, "status", kind)
 | 
			
		||||
			statusSpec = &apiextensionsinternal.CustomResourceSubresourceStatus{}
 | 
			
		||||
			if err := apiextensionsv1.Convert_v1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus(subresources.Status, statusSpec, nil); err != nil {
 | 
			
		||||
@@ -720,7 +719,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var scaleSpec *apiextensionsinternal.CustomResourceSubresourceScale
 | 
			
		||||
		if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && subresources != nil && subresources.Scale != nil {
 | 
			
		||||
		if subresources != nil && subresources.Scale != nil {
 | 
			
		||||
			equivalentResourceRegistry.RegisterKindFor(resource, "scale", autoscalingv1.SchemeGroupVersion.WithKind("Scale"))
 | 
			
		||||
			scaleSpec = &apiextensionsinternal.CustomResourceSubresourceScale{}
 | 
			
		||||
			if err := apiextensionsv1.Convert_v1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale(subresources.Scale, scaleSpec, nil); err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
 | 
			
		||||
@@ -40,7 +39,6 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
			
		||||
        "//vendor/github.com/go-openapi/validate:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -32,12 +32,10 @@ import (
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/validation/field"
 | 
			
		||||
	apiserverstorage "k8s.io/apiserver/pkg/storage"
 | 
			
		||||
	"k8s.io/apiserver/pkg/storage/names"
 | 
			
		||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
 | 
			
		||||
	structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
 | 
			
		||||
	schemaobjectmeta "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta"
 | 
			
		||||
	apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// customResourceStrategy implements behavior for CustomResources.
 | 
			
		||||
@@ -75,7 +73,7 @@ func (a customResourceStrategy) NamespaceScoped() bool {
 | 
			
		||||
 | 
			
		||||
// PrepareForCreate clears the status of a CustomResource before creation.
 | 
			
		||||
func (a customResourceStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
 | 
			
		||||
	if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil {
 | 
			
		||||
	if a.status != nil {
 | 
			
		||||
		customResourceObject := obj.(*unstructured.Unstructured)
 | 
			
		||||
		customResource := customResourceObject.UnstructuredContent()
 | 
			
		||||
 | 
			
		||||
@@ -98,7 +96,7 @@ func (a customResourceStrategy) PrepareForUpdate(ctx context.Context, obj, old r
 | 
			
		||||
	oldCustomResource := oldCustomResourceObject.UnstructuredContent()
 | 
			
		||||
 | 
			
		||||
	// If the /status subresource endpoint is installed, update is not allowed to set status.
 | 
			
		||||
	if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil {
 | 
			
		||||
	if a.status != nil {
 | 
			
		||||
		_, ok1 := newCustomResource["status"]
 | 
			
		||||
		_, ok2 := oldCustomResource["status"]
 | 
			
		||||
		switch {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ go_library(
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
			
		||||
@@ -30,7 +29,6 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/storage/errors:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/util/dryrun:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +55,6 @@ go_test(
 | 
			
		||||
        "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/utils/pointer:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ import (
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
 | 
			
		||||
	apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
 | 
			
		||||
	apiequality "k8s.io/apimachinery/pkg/api/equality"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/fields"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/labels"
 | 
			
		||||
@@ -33,7 +32,6 @@ import (
 | 
			
		||||
	"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.
 | 
			
		||||
@@ -56,8 +54,6 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
 | 
			
		||||
	crd.Status = apiextensions.CustomResourceDefinitionStatus{}
 | 
			
		||||
	crd.Generation = 1
 | 
			
		||||
 | 
			
		||||
	dropDisabledFields(&crd.Spec, nil)
 | 
			
		||||
 | 
			
		||||
	for _, v := range crd.Spec.Versions {
 | 
			
		||||
		if v.Storage {
 | 
			
		||||
			if !apiextensions.IsStoredVersion(crd, v.Name) {
 | 
			
		||||
@@ -86,8 +82,6 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
 | 
			
		||||
		newCRD.Generation = oldCRD.Generation + 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dropDisabledFields(&newCRD.Spec, &oldCRD.Spec)
 | 
			
		||||
 | 
			
		||||
	for _, v := range newCRD.Spec.Versions {
 | 
			
		||||
		if v.Storage {
 | 
			
		||||
			if !apiextensions.IsStoredVersion(newCRD, v.Name) {
 | 
			
		||||
@@ -198,102 +192,3 @@ 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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,6 @@ limitations under the License.
 | 
			
		||||
package customresourcedefinition
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
 | 
			
		||||
@@ -26,333 +24,10 @@ import (
 | 
			
		||||
	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/diff"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/validation/field"
 | 
			
		||||
	"k8s.io/utils/pointer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestDropDisableFieldsCustomResourceDefinition(t *testing.T) {
 | 
			
		||||
	t.Log("testing unversioned validation..")
 | 
			
		||||
	crdWithUnversionedValidation := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with non-versioned validation
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Validation: &apiextensions.CustomResourceValidation{
 | 
			
		||||
					OpenAPIV3Schema: &apiextensions.JSONSchemaProps{},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdWithoutUnversionedValidation := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with non-versioned validation
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdInfos := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		crd  func() *apiextensions.CustomResourceDefinition
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "has unversioned validation",
 | 
			
		||||
			crd:  crdWithUnversionedValidation,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "doesn't have unversioned validation",
 | 
			
		||||
			crd:  crdWithoutUnversionedValidation,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nil",
 | 
			
		||||
			crd:  func() *apiextensions.CustomResourceDefinition { return nil },
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, oldCRDInfo := range crdInfos {
 | 
			
		||||
		for _, newCRDInfo := range crdInfos {
 | 
			
		||||
			oldCRD := oldCRDInfo.crd()
 | 
			
		||||
			newCRD := newCRDInfo.crd()
 | 
			
		||||
			if newCRD == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			t.Run(fmt.Sprintf("old CRD %v, new CRD %v", oldCRDInfo.name, newCRDInfo.name),
 | 
			
		||||
				func(t *testing.T) {
 | 
			
		||||
					var oldCRDSpec *apiextensions.CustomResourceDefinitionSpec
 | 
			
		||||
					if oldCRD != nil {
 | 
			
		||||
						oldCRDSpec = &oldCRD.Spec
 | 
			
		||||
					}
 | 
			
		||||
					dropDisabledFields(&newCRD.Spec, oldCRDSpec)
 | 
			
		||||
					// old CRD should never be changed
 | 
			
		||||
					if !reflect.DeepEqual(oldCRD, oldCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("old crd changed: %v", diff.ObjectReflectDiff(oldCRD, oldCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
					if !reflect.DeepEqual(newCRD, newCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("new crd changed: %v", diff.ObjectReflectDiff(newCRD, newCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t.Log("testing unversioned subresources...")
 | 
			
		||||
	crdWithUnversionedSubresources := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with unversioned subresources
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Subresources: &apiextensions.CustomResourceSubresources{},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdWithoutUnversionedSubresources := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd without unversioned subresources
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdInfos = []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		crd  func() *apiextensions.CustomResourceDefinition
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "has unversioned subresources",
 | 
			
		||||
			crd:  crdWithUnversionedSubresources,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "doesn't have unversioned subresources",
 | 
			
		||||
			crd:  crdWithoutUnversionedSubresources,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nil",
 | 
			
		||||
			crd:  func() *apiextensions.CustomResourceDefinition { return nil },
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, oldCRDInfo := range crdInfos {
 | 
			
		||||
		for _, newCRDInfo := range crdInfos {
 | 
			
		||||
			oldCRD := oldCRDInfo.crd()
 | 
			
		||||
			newCRD := newCRDInfo.crd()
 | 
			
		||||
			if newCRD == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			t.Run(fmt.Sprintf("old CRD %v, new CRD %v", oldCRDInfo.name, newCRDInfo.name),
 | 
			
		||||
				func(t *testing.T) {
 | 
			
		||||
					var oldCRDSpec *apiextensions.CustomResourceDefinitionSpec
 | 
			
		||||
					if oldCRD != nil {
 | 
			
		||||
						oldCRDSpec = &oldCRD.Spec
 | 
			
		||||
					}
 | 
			
		||||
					dropDisabledFields(&newCRD.Spec, oldCRDSpec)
 | 
			
		||||
					// old CRD should never be changed
 | 
			
		||||
					if !reflect.DeepEqual(oldCRD, oldCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("old crd changed: %v", diff.ObjectReflectDiff(oldCRD, oldCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
					if !reflect.DeepEqual(newCRD, newCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("new crd changed: %v", diff.ObjectReflectDiff(newCRD, newCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t.Log("testing versioned validation..")
 | 
			
		||||
	crdWithVersionedValidation := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with versioned validation
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Versions: []apiextensions.CustomResourceDefinitionVersion{
 | 
			
		||||
					{
 | 
			
		||||
						Name: "v1",
 | 
			
		||||
						Schema: &apiextensions.CustomResourceValidation{
 | 
			
		||||
							OpenAPIV3Schema: &apiextensions.JSONSchemaProps{},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdWithoutVersionedValidation := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with versioned validation
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Versions: []apiextensions.CustomResourceDefinitionVersion{
 | 
			
		||||
					{
 | 
			
		||||
						Name: "v1",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdInfos = []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		crd  func() *apiextensions.CustomResourceDefinition
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "has versioned validation",
 | 
			
		||||
			crd:  crdWithVersionedValidation,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "doesn't have versioned validation",
 | 
			
		||||
			crd:  crdWithoutVersionedValidation,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nil",
 | 
			
		||||
			crd:  func() *apiextensions.CustomResourceDefinition { return nil },
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, oldCRDInfo := range crdInfos {
 | 
			
		||||
		for _, newCRDInfo := range crdInfos {
 | 
			
		||||
			oldCRD := oldCRDInfo.crd()
 | 
			
		||||
			newCRD := newCRDInfo.crd()
 | 
			
		||||
			if newCRD == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			t.Run(fmt.Sprintf("old CRD %v, new CRD %v", oldCRDInfo.name, newCRDInfo.name),
 | 
			
		||||
				func(t *testing.T) {
 | 
			
		||||
					var oldCRDSpec *apiextensions.CustomResourceDefinitionSpec
 | 
			
		||||
					if oldCRD != nil {
 | 
			
		||||
						oldCRDSpec = &oldCRD.Spec
 | 
			
		||||
					}
 | 
			
		||||
					dropDisabledFields(&newCRD.Spec, oldCRDSpec)
 | 
			
		||||
					// old CRD should never be changed
 | 
			
		||||
					if !reflect.DeepEqual(oldCRD, oldCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("old crd changed: %v", diff.ObjectReflectDiff(oldCRD, oldCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
					if !reflect.DeepEqual(newCRD, newCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("new crd changed: %v", diff.ObjectReflectDiff(newCRD, newCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t.Log("testing versioned subresources w/ conversion enabled..")
 | 
			
		||||
	crdWithVersionedSubresources := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with versioned subresources
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Versions: []apiextensions.CustomResourceDefinitionVersion{
 | 
			
		||||
					{
 | 
			
		||||
						Name:         "v1",
 | 
			
		||||
						Subresources: &apiextensions.CustomResourceSubresources{},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdWithoutVersionedSubresources := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd without versioned subresources
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Versions: []apiextensions.CustomResourceDefinitionVersion{
 | 
			
		||||
					{
 | 
			
		||||
						Name: "v1",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdInfos = []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		crd  func() *apiextensions.CustomResourceDefinition
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "has versioned subresources",
 | 
			
		||||
			crd:  crdWithVersionedSubresources,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "doesn't have versioned subresources",
 | 
			
		||||
			crd:  crdWithoutVersionedSubresources,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nil",
 | 
			
		||||
			crd:  func() *apiextensions.CustomResourceDefinition { return nil },
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, oldCRDInfo := range crdInfos {
 | 
			
		||||
		for _, newCRDInfo := range crdInfos {
 | 
			
		||||
			oldCRD := oldCRDInfo.crd()
 | 
			
		||||
			newCRD := newCRDInfo.crd()
 | 
			
		||||
			if newCRD == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			t.Run(fmt.Sprintf("old CRD %v, new CRD %v", oldCRDInfo.name, newCRDInfo.name),
 | 
			
		||||
				func(t *testing.T) {
 | 
			
		||||
					var oldCRDSpec *apiextensions.CustomResourceDefinitionSpec
 | 
			
		||||
					if oldCRD != nil {
 | 
			
		||||
						oldCRDSpec = &oldCRD.Spec
 | 
			
		||||
					}
 | 
			
		||||
					dropDisabledFields(&newCRD.Spec, oldCRDSpec)
 | 
			
		||||
					// old CRD should never be changed
 | 
			
		||||
					if !reflect.DeepEqual(oldCRD, oldCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("old crd changed: %v", diff.ObjectReflectDiff(oldCRD, oldCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
					if !reflect.DeepEqual(newCRD, newCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("new crd changed: %v", diff.ObjectReflectDiff(newCRD, newCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t.Log("testing conversion webhook..")
 | 
			
		||||
	crdWithUnversionedConversionWebhook := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with conversion webhook
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Conversion: &apiextensions.CustomResourceConversion{
 | 
			
		||||
					WebhookClientConfig: &apiextensions.WebhookClientConfig{},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdWithoutUnversionedConversionWebhook := func() *apiextensions.CustomResourceDefinition {
 | 
			
		||||
		// crd with conversion webhook
 | 
			
		||||
		return &apiextensions.CustomResourceDefinition{
 | 
			
		||||
			Spec: apiextensions.CustomResourceDefinitionSpec{
 | 
			
		||||
				Conversion: &apiextensions.CustomResourceConversion{},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	crdInfos = []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		crd  func() *apiextensions.CustomResourceDefinition
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "has conversion webhook",
 | 
			
		||||
			crd:  crdWithUnversionedConversionWebhook,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "doesn't have conversion webhook",
 | 
			
		||||
			crd:  crdWithoutUnversionedConversionWebhook,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nil",
 | 
			
		||||
			crd:  func() *apiextensions.CustomResourceDefinition { return nil },
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, oldCRDInfo := range crdInfos {
 | 
			
		||||
		for _, newCRDInfo := range crdInfos {
 | 
			
		||||
			oldCRD := oldCRDInfo.crd()
 | 
			
		||||
			newCRD := newCRDInfo.crd()
 | 
			
		||||
			if newCRD == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			t.Run(fmt.Sprintf("old CRD %v, new CRD %v", oldCRDInfo.name, newCRDInfo.name),
 | 
			
		||||
				func(t *testing.T) {
 | 
			
		||||
					var oldCRDSpec *apiextensions.CustomResourceDefinitionSpec
 | 
			
		||||
					if oldCRD != nil {
 | 
			
		||||
						oldCRDSpec = &oldCRD.Spec
 | 
			
		||||
					}
 | 
			
		||||
					dropDisabledFields(&newCRD.Spec, oldCRDSpec)
 | 
			
		||||
					// old CRD should never be changed
 | 
			
		||||
					if !reflect.DeepEqual(oldCRD, oldCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("old crd changed: %v", diff.ObjectReflectDiff(oldCRD, oldCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
					if !reflect.DeepEqual(newCRD, newCRDInfo.crd()) {
 | 
			
		||||
						t.Errorf("new crd changed: %v", diff.ObjectReflectDiff(newCRD, newCRDInfo.crd()))
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func strPtr(in string) *string {
 | 
			
		||||
	return &in
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -1182,7 +1182,6 @@ k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/controller/status
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/crdserverscheme
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/features
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/generated/openapi
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/registry/customresource
 | 
			
		||||
k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user