mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Lock ServerSideApply feature to true
This commit is contained in:
		| @@ -62,7 +62,7 @@ function run_kube_apiserver() { | |||||||
|   AUTHORIZATION_MODE="RBAC,AlwaysAllow" |   AUTHORIZATION_MODE="RBAC,AlwaysAllow" | ||||||
|  |  | ||||||
|   # Enable features |   # Enable features | ||||||
|   ENABLE_FEATURE_GATES="ServerSideApply=true" |   ENABLE_FEATURE_GATES="" | ||||||
|  |  | ||||||
|   "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \ |   "${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \ | ||||||
|     --bind-address="127.0.0.1" \ |     --bind-address="127.0.0.1" \ | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ import ( | |||||||
| 	"sort" | 	"sort" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"k8s.io/apiserver/pkg/features" |  | ||||||
| 	rbacv1ac "k8s.io/client-go/applyconfigurations/rbac/v1" | 	rbacv1ac "k8s.io/client-go/applyconfigurations/rbac/v1" | ||||||
| 	"k8s.io/klog/v2" | 	"k8s.io/klog/v2" | ||||||
|  |  | ||||||
| @@ -33,7 +32,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/labels" | 	"k8s.io/apimachinery/pkg/labels" | ||||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	rbacinformers "k8s.io/client-go/informers/rbac/v1" | 	rbacinformers "k8s.io/client-go/informers/rbac/v1" | ||||||
| 	rbacclient "k8s.io/client-go/kubernetes/typed/rbac/v1" | 	rbacclient "k8s.io/client-go/kubernetes/typed/rbac/v1" | ||||||
| 	rbaclisters "k8s.io/client-go/listers/rbac/v1" | 	rbaclisters "k8s.io/client-go/listers/rbac/v1" | ||||||
| @@ -125,7 +123,6 @@ func (c *ClusterRoleAggregationController) syncClusterRole(ctx context.Context, | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 	err = c.applyClusterRoles(ctx, sharedClusterRole.Name, newPolicyRules) | 	err = c.applyClusterRoles(ctx, sharedClusterRole.Name, newPolicyRules) | ||||||
| 	if errors.IsUnsupportedMediaType(err) { // TODO: Remove this fallback at least one release after ServerSideApply GA | 	if errors.IsUnsupportedMediaType(err) { // TODO: Remove this fallback at least one release after ServerSideApply GA | ||||||
| 		// When Server Side Apply is not enabled, fallback to Update. This is required when running | 		// When Server Side Apply is not enabled, fallback to Update. This is required when running | ||||||
| @@ -134,9 +131,6 @@ func (c *ClusterRoleAggregationController) syncClusterRole(ctx context.Context, | |||||||
| 		// if the feature has been disabled using its feature flag. | 		// if the feature has been disabled using its feature flag. | ||||||
| 		err = c.updateClusterRoles(ctx, sharedClusterRole, newPolicyRules) | 		err = c.updateClusterRoles(ctx, sharedClusterRole, newPolicyRules) | ||||||
| 	} | 	} | ||||||
| 	} else { |  | ||||||
| 		err = c.updateClusterRoles(ctx, sharedClusterRole, newPolicyRules) |  | ||||||
| 	} |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1034,7 +1034,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS | |||||||
|  |  | ||||||
| 	genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.Beta}, | 	genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.Beta}, | ||||||
|  |  | ||||||
| 	genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA}, | 	genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 | ||||||
|  |  | ||||||
| 	genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, | 	genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -69,12 +69,10 @@ import ( | |||||||
| 	"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" | 	"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" | ||||||
| 	"k8s.io/apiserver/pkg/endpoints/metrics" | 	"k8s.io/apiserver/pkg/endpoints/metrics" | ||||||
| 	apirequest "k8s.io/apiserver/pkg/endpoints/request" | 	apirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||||
| 	"k8s.io/apiserver/pkg/features" |  | ||||||
| 	"k8s.io/apiserver/pkg/registry/generic" | 	"k8s.io/apiserver/pkg/registry/generic" | ||||||
| 	genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" | 	genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" | ||||||
| 	genericfilters "k8s.io/apiserver/pkg/server/filters" | 	genericfilters "k8s.io/apiserver/pkg/server/filters" | ||||||
| 	"k8s.io/apiserver/pkg/storage/storagebackend" | 	"k8s.io/apiserver/pkg/storage/storagebackend" | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" | 	flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" | ||||||
| 	utilopenapi "k8s.io/apiserver/pkg/util/openapi" | 	utilopenapi "k8s.io/apiserver/pkg/util/openapi" | ||||||
| 	"k8s.io/apiserver/pkg/util/webhook" | 	"k8s.io/apiserver/pkg/util/webhook" | ||||||
| @@ -330,9 +328,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | |||||||
| 	supportedTypes := []string{ | 	supportedTypes := []string{ | ||||||
| 		string(types.JSONPatchType), | 		string(types.JSONPatchType), | ||||||
| 		string(types.MergePatchType), | 		string(types.MergePatchType), | ||||||
| 	} | 		string(types.ApplyPatchType), | ||||||
| 	if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 		supportedTypes = append(supportedTypes, string(types.ApplyPatchType)) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var handlerFunc http.HandlerFunc | 	var handlerFunc http.HandlerFunc | ||||||
| @@ -849,7 +845,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd | |||||||
| 			standardSerializers = append(standardSerializers, s) | 			standardSerializers = append(standardSerializers, s) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		requestScopes[v.Name] = &handlers.RequestScope{ | 		reqScope := handlers.RequestScope{ | ||||||
| 			Namer: handlers.ContextBasedNaming{ | 			Namer: handlers.ContextBasedNaming{ | ||||||
| 				Namer:         meta.NewAccessor(), | 				Namer:         meta.NewAccessor(), | ||||||
| 				ClusterScoped: clusterScoped, | 				ClusterScoped: clusterScoped, | ||||||
| @@ -880,9 +876,8 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd | |||||||
|  |  | ||||||
| 			MaxRequestBodyBytes: r.maxRequestBodyBytes, | 			MaxRequestBodyBytes: r.maxRequestBodyBytes, | ||||||
| 		} | 		} | ||||||
| 		if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 		resetFields := storages[v.Name].CustomResource.GetResetFields() | 		resetFields := storages[v.Name].CustomResource.GetResetFields() | ||||||
| 			reqScope := *requestScopes[v.Name] |  | ||||||
| 		reqScope, err = scopeWithFieldManager( | 		reqScope, err = scopeWithFieldManager( | ||||||
| 			typeConverter, | 			typeConverter, | ||||||
| 			reqScope, | 			reqScope, | ||||||
| @@ -893,7 +888,6 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd | |||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		requestScopes[v.Name] = &reqScope | 		requestScopes[v.Name] = &reqScope | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		scaleColumns, err := getScaleColumnsForVersion(crd, v.Name) | 		scaleColumns, err := getScaleColumnsForVersion(crd, v.Name) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -914,7 +908,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd | |||||||
| 		} | 		} | ||||||
| 		scaleScope.TableConvertor = scaleTable | 		scaleScope.TableConvertor = scaleTable | ||||||
|  |  | ||||||
| 		if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Scale != nil { | 		if subresources != nil && subresources.Scale != nil { | ||||||
| 			scaleScope, err = scopeWithFieldManager( | 			scaleScope, err = scopeWithFieldManager( | ||||||
| 				typeConverter, | 				typeConverter, | ||||||
| 				scaleScope, | 				scaleScope, | ||||||
| @@ -937,7 +931,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd | |||||||
| 			ClusterScoped: clusterScoped, | 			ClusterScoped: clusterScoped, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Status != nil { | 		if subresources != nil && subresources.Status != nil { | ||||||
| 			resetFields := storages[v.Name].Status.GetResetFields() | 			resetFields := storages[v.Name].Status.GetResetFields() | ||||||
| 			statusScope, err = scopeWithFieldManager( | 			statusScope, err = scopeWithFieldManager( | ||||||
| 				typeConverter, | 				typeConverter, | ||||||
| @@ -1400,11 +1394,8 @@ func hasServedCRDVersion(spec *apiextensionsv1.CustomResourceDefinitionSpec, ver | |||||||
|  |  | ||||||
| // buildOpenAPIModelsForApply constructs openapi models from any validation schemas specified in the custom resource, | // buildOpenAPIModelsForApply constructs openapi models from any validation schemas specified in the custom resource, | ||||||
| // and merges it with the models defined in the static OpenAPI spec. | // and merges it with the models defined in the static OpenAPI spec. | ||||||
| // Returns nil models if the ServerSideApply feature is disabled, or the static spec is nil, or an error is encountered. | // Returns nil models ifthe static spec is nil, or an error is encountered. | ||||||
| func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensionsv1.CustomResourceDefinition) (proto.Models, error) { | func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensionsv1.CustomResourceDefinition) (proto.Models, error) { | ||||||
| 	if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 	if staticOpenAPISpec == nil { | 	if staticOpenAPISpec == nil { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -340,11 +340,8 @@ func (b *builder) buildRoute(root, path, httpMethod, actionVerb, operationVerb s | |||||||
| 		supportedTypes := []string{ | 		supportedTypes := []string{ | ||||||
| 			string(types.JSONPatchType), | 			string(types.JSONPatchType), | ||||||
| 			string(types.MergePatchType), | 			string(types.MergePatchType), | ||||||
|  | 			string(types.ApplyPatchType), | ||||||
| 		} | 		} | ||||||
| 		if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 			supportedTypes = append(supportedTypes, string(types.ApplyPatchType)) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		route.Consumes(supportedTypes...) | 		route.Consumes(supportedTypes...) | ||||||
| 	} else { | 	} else { | ||||||
| 		route.Consumes(runtime.ContentTypeJSON, runtime.ContentTypeYAML) | 		route.Consumes(runtime.ContentTypeJSON, runtime.ContentTypeYAML) | ||||||
|   | |||||||
| @@ -31,8 +31,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/json" | 	"k8s.io/apimachinery/pkg/util/json" | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
| 	"k8s.io/apiserver/pkg/endpoints" | 	"k8s.io/apiserver/pkg/endpoints" | ||||||
| 	"k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/kube-openapi/pkg/validation/spec" | 	"k8s.io/kube-openapi/pkg/validation/spec" | ||||||
| 	utilpointer "k8s.io/utils/pointer" | 	utilpointer "k8s.io/utils/pointer" | ||||||
| ) | ) | ||||||
| @@ -540,10 +538,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) { | |||||||
| 							actions.Insert(action) | 							actions.Insert(action) | ||||||
| 						} | 						} | ||||||
| 						if action == "patch" { | 						if action == "patch" { | ||||||
| 							expected := []string{"application/json-patch+json", "application/merge-patch+json"} | 							expected := []string{"application/json-patch+json", "application/merge-patch+json", "application/apply-patch+yaml"} | ||||||
| 							if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 								expected = append(expected, "application/apply-patch+yaml") |  | ||||||
| 							} |  | ||||||
| 							assert.Equal(t, operation.Consumes, expected) | 							assert.Equal(t, operation.Consumes, expected) | ||||||
| 						} else { | 						} else { | ||||||
| 							assert.Equal(t, operation.Consumes, []string{"application/json", "application/yaml"}) | 							assert.Equal(t, operation.Consumes, []string{"application/json", "application/yaml"}) | ||||||
|   | |||||||
| @@ -26,15 +26,10 @@ import ( | |||||||
| 	"k8s.io/apiextensions-apiserver/test/integration/fixtures" | 	"k8s.io/apiextensions-apiserver/test/integration/fixtures" | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestApplyBasic(t *testing.T) { | func TestApplyBasic(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	tearDown, config, _, err := fixtures.StartDefaultServer(t) | 	tearDown, config, _, err := fixtures.StartDefaultServer(t) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|   | |||||||
| @@ -32,10 +32,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
|  |  | ||||||
| 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" | 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" | ||||||
| 	"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" | 	"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" | ||||||
| @@ -387,8 +384,6 @@ func TestScaleSubresource(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestApplyScaleSubresource(t *testing.T) { | func TestApplyScaleSubresource(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	tearDown, config, _, err := fixtures.StartDefaultServer(t) | 	tearDown, config, _, err := fixtures.StartDefaultServer(t) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|   | |||||||
| @@ -260,7 +260,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var resetFields map[fieldpath.APIVersion]*fieldpath.Set | 	var resetFields map[fieldpath.APIVersion]*fieldpath.Set | ||||||
| 	if a.group.OpenAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { | 	if a.group.OpenAPIModels != nil { | ||||||
| 		if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy { | 		if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy { | ||||||
| 			resetFields = resetFieldsStrategy.GetResetFields() | 			resetFields = resetFieldsStrategy.GetResetFields() | ||||||
| 		} | 		} | ||||||
| @@ -599,7 +599,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag | |||||||
| 	if a.group.MetaGroupVersion != nil { | 	if a.group.MetaGroupVersion != nil { | ||||||
| 		reqScope.MetaGroupVersion = *a.group.MetaGroupVersion | 		reqScope.MetaGroupVersion = *a.group.MetaGroupVersion | ||||||
| 	} | 	} | ||||||
| 	if a.group.OpenAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { | 	if a.group.OpenAPIModels != nil { | ||||||
| 		reqScope.FieldManager, err = fieldmanager.NewDefaultFieldManager( | 		reqScope.FieldManager, err = fieldmanager.NewDefaultFieldManager( | ||||||
| 			a.group.TypeConverter, | 			a.group.TypeConverter, | ||||||
| 			a.group.UnsafeConvertor, | 			a.group.UnsafeConvertor, | ||||||
| @@ -785,9 +785,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag | |||||||
| 				string(types.JSONPatchType), | 				string(types.JSONPatchType), | ||||||
| 				string(types.MergePatchType), | 				string(types.MergePatchType), | ||||||
| 				string(types.StrategicMergePatchType), | 				string(types.StrategicMergePatchType), | ||||||
| 			} | 				string(types.ApplyPatchType), | ||||||
| 			if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 				supportedTypes = append(supportedTypes, string(types.ApplyPatchType)) |  | ||||||
| 			} | 			} | ||||||
| 			handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, deprecated, removedRelease, restfulPatchResource(patcher, reqScope, admit, supportedTypes)) | 			handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, deprecated, removedRelease, restfulPatchResource(patcher, reqScope, admit, supportedTypes)) | ||||||
| 			handler = utilwarning.AddWarningsHandler(handler, warnings) | 			handler = utilwarning.AddWarningsHandler(handler, warnings) | ||||||
|   | |||||||
| @@ -605,7 +605,7 @@ func CleanVerb(verb string, request *http.Request) string { | |||||||
| 	if verb == "WATCHLIST" { | 	if verb == "WATCHLIST" { | ||||||
| 		reportedVerb = "WATCH" | 		reportedVerb = "WATCH" | ||||||
| 	} | 	} | ||||||
| 	if verb == "PATCH" && request.Header.Get("Content-Type") == string(types.ApplyPatchType) && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { | 	if verb == "PATCH" && request.Header.Get("Content-Type") == string(types.ApplyPatchType) { | ||||||
| 		reportedVerb = "APPLY" | 		reportedVerb = "APPLY" | ||||||
| 	} | 	} | ||||||
| 	return reportedVerb | 	return reportedVerb | ||||||
|   | |||||||
| @@ -231,7 +231,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS | |||||||
|  |  | ||||||
| 	RemoveSelfLink: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, | 	RemoveSelfLink: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, | ||||||
|  |  | ||||||
| 	ServerSideApply: {Default: true, PreRelease: featuregate.GA}, | 	ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 | ||||||
|  |  | ||||||
| 	ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, | 	ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,9 +30,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||||
| 	"k8s.io/apiserver/pkg/features" |  | ||||||
| 	"k8s.io/apiserver/pkg/storage/names" | 	"k8s.io/apiserver/pkg/storage/names" | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/apiserver/pkg/warning" | 	"k8s.io/apiserver/pkg/warning" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -121,11 +119,6 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx context.Context, obj runtime. | |||||||
|  |  | ||||||
| 	strategy.PrepareForCreate(ctx, obj) | 	strategy.PrepareForCreate(ctx, obj) | ||||||
|  |  | ||||||
| 	// Ensure managedFields is not set unless the feature is enabled |  | ||||||
| 	if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 		objectMeta.SetManagedFields(nil) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if errs := strategy.Validate(ctx, obj); len(errs) > 0 { | 	if errs := strategy.Validate(ctx, obj); len(errs) > 0 { | ||||||
| 		return errors.NewInvalid(kind.GroupKind(), objectMeta.GetName(), errs) | 		return errors.NewInvalid(kind.GroupKind(), objectMeta.GetName(), errs) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -29,8 +29,6 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||||
| 	"k8s.io/apiserver/pkg/admission" | 	"k8s.io/apiserver/pkg/admission" | ||||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||||
| 	"k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/apiserver/pkg/warning" | 	"k8s.io/apiserver/pkg/warning" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -128,12 +126,6 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx context.Context, obj, old run | |||||||
| 	} | 	} | ||||||
| 	objectMeta.SetGeneration(oldMeta.GetGeneration()) | 	objectMeta.SetGeneration(oldMeta.GetGeneration()) | ||||||
|  |  | ||||||
| 	// Ensure managedFields state is removed unless ServerSideApply is enabled |  | ||||||
| 	if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { |  | ||||||
| 		oldMeta.SetManagedFields(nil) |  | ||||||
| 		objectMeta.SetManagedFields(nil) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	strategy.PrepareForUpdate(ctx, obj, old) | 	strategy.PrepareForUpdate(ctx, obj, old) | ||||||
|  |  | ||||||
| 	// Use the existing UID if none is provided | 	// Use the existing UID if none is provided | ||||||
|   | |||||||
| @@ -666,7 +666,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A | |||||||
| 		} | 		} | ||||||
| 		apiGroupVersion.OpenAPIModels = openAPIModels | 		apiGroupVersion.OpenAPIModels = openAPIModels | ||||||
|  |  | ||||||
| 		if openAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { | 		if openAPIModels != nil { | ||||||
| 			typeConverter, err := fieldmanager.NewTypeConverter(openAPIModels, false) | 			typeConverter, err := fieldmanager.NewTypeConverter(openAPIModels, false) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
|   | |||||||
| @@ -29,10 +29,7 @@ import ( | |||||||
| 	"k8s.io/apiextensions-apiserver/test/integration/fixtures" | 	"k8s.io/apiextensions-apiserver/test/integration/fixtures" | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| ) | ) | ||||||
| @@ -40,8 +37,6 @@ import ( | |||||||
| // TestApplyCRDNoSchema tests that CRDs and CRs can both be applied to with a PATCH request with the apply content type | // TestApplyCRDNoSchema tests that CRDs and CRs can both be applied to with a PATCH request with the apply content type | ||||||
| // when there is no validation field provided. | // when there is no validation field provided. | ||||||
| func TestApplyCRDNoSchema(t *testing.T) { | func TestApplyCRDNoSchema(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|   | |||||||
| @@ -41,10 +41,7 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| ) | ) | ||||||
| @@ -52,8 +49,6 @@ import ( | |||||||
| // TestApplyCRDStructuralSchema tests that when a CRD has a structural schema in its validation field, | // TestApplyCRDStructuralSchema tests that when a CRD has a structural schema in its validation field, | ||||||
| // it will be used to construct the CR schema used by apply. | // it will be used to construct the CR schema used by apply. | ||||||
| func TestApplyCRDStructuralSchema(t *testing.T) { | func TestApplyCRDStructuralSchema(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| @@ -418,8 +413,6 @@ func findCRDCondition(crd *apiextensionsv1.CustomResourceDefinition, conditionTy | |||||||
| // TestApplyCRDUnhandledSchema tests that when a CRD has a schema that kube-openapi ToProtoModels cannot handle correctly, | // TestApplyCRDUnhandledSchema tests that when a CRD has a schema that kube-openapi ToProtoModels cannot handle correctly, | ||||||
| // apply falls back to non-schema behavior | // apply falls back to non-schema behavior | ||||||
| func TestApplyCRDUnhandledSchema(t *testing.T) { | func TestApplyCRDUnhandledSchema(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	storageConfig := framework.SharedEtcd() | 	storageConfig := framework.SharedEtcd() | ||||||
| 	tlsInfo := transport.TLSInfo{ | 	tlsInfo := transport.TLSInfo{ | ||||||
| 		CertFile:      storageConfig.Transport.CertFile, | 		CertFile:      storageConfig.Transport.CertFile, | ||||||
| @@ -608,8 +601,6 @@ func getManagedFields(rawResponse []byte) ([]metav1.ManagedFieldsEntry, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestDefaultMissingKeyCRD(t *testing.T) { | func TestDefaultMissingKeyCRD(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|   | |||||||
| @@ -23,7 +23,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" |  | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -39,11 +38,8 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	yamlutil "k8s.io/apimachinery/pkg/util/yaml" | 	yamlutil "k8s.io/apimachinery/pkg/util/yaml" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| ) | ) | ||||||
| @@ -67,8 +63,6 @@ func setup(t testing.TB) (clientset.Interface, kubeapiservertesting.TearDownFunc | |||||||
| // will create the object if it doesn't already exist | // will create the object if it doesn't already exist | ||||||
| // TODO: make a set of test cases in an easy-to-consume place (separate package?) so it's easy to test in both integration and e2e. | // TODO: make a set of test cases in an easy-to-consume place (separate package?) so it's easy to test in both integration and e2e. | ||||||
| func TestApplyAlsoCreates(t *testing.T) { | func TestApplyAlsoCreates(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -150,8 +144,6 @@ func TestApplyAlsoCreates(t *testing.T) { | |||||||
| // TestNoOpUpdateSameResourceVersion makes sure that PUT requests which change nothing | // TestNoOpUpdateSameResourceVersion makes sure that PUT requests which change nothing | ||||||
| // will not change the resource version (no write to etcd is done) | // will not change the resource version (no write to etcd is done) | ||||||
| func TestNoOpUpdateSameResourceVersion(t *testing.T) { | func TestNoOpUpdateSameResourceVersion(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -264,8 +256,6 @@ func getRV(obj runtime.Object) (string, error) { | |||||||
| // - Applying an atomic struct that removes a default | // - Applying an atomic struct that removes a default | ||||||
| // - Changing Quantity or other fields that are normalized | // - Changing Quantity or other fields that are normalized | ||||||
| func TestNoSemanticUpdateApplySameResourceVersion(t *testing.T) { | func TestNoSemanticUpdateApplySameResourceVersion(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -350,8 +340,6 @@ func TestNoSemanticUpdateApplySameResourceVersion(t *testing.T) { | |||||||
| // - Applying an atomic struct that removes a default | // - Applying an atomic struct that removes a default | ||||||
| // - Changing Quantity or other fields that are normalized | // - Changing Quantity or other fields that are normalized | ||||||
| func TestNoSemanticUpdatePutSameResourceVersion(t *testing.T) { | func TestNoSemanticUpdatePutSameResourceVersion(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -431,8 +419,6 @@ func TestNoSemanticUpdatePutSameResourceVersion(t *testing.T) { | |||||||
| // TestCreateOnApplyFailsWithUID makes sure that PATCH requests with the apply content type | // TestCreateOnApplyFailsWithUID makes sure that PATCH requests with the apply content type | ||||||
| // will not create the object if it doesn't already exist and it specifies a UID | // will not create the object if it doesn't already exist and it specifies a UID | ||||||
| func TestCreateOnApplyFailsWithUID(t *testing.T) { | func TestCreateOnApplyFailsWithUID(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -463,8 +449,6 @@ func TestCreateOnApplyFailsWithUID(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestApplyUpdateApplyConflictForced(t *testing.T) { | func TestApplyUpdateApplyConflictForced(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -553,8 +537,6 @@ func TestApplyUpdateApplyConflictForced(t *testing.T) { | |||||||
| // TestApplyGroupsManySeparateUpdates tests that when many different managers update the same object, | // TestApplyGroupsManySeparateUpdates tests that when many different managers update the same object, | ||||||
| // the number of managedFields entries will only grow to a certain size. | // the number of managedFields entries will only grow to a certain size. | ||||||
| func TestApplyGroupsManySeparateUpdates(t *testing.T) { | func TestApplyGroupsManySeparateUpdates(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -617,8 +599,6 @@ func TestApplyGroupsManySeparateUpdates(t *testing.T) { | |||||||
|  |  | ||||||
| // TestCreateVeryLargeObject tests that a very large object can be created without exceeding the size limit due to managedFields | // TestCreateVeryLargeObject tests that a very large object can be created without exceeding the size limit due to managedFields | ||||||
| func TestCreateVeryLargeObject(t *testing.T) { | func TestCreateVeryLargeObject(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -663,8 +643,6 @@ func TestCreateVeryLargeObject(t *testing.T) { | |||||||
|  |  | ||||||
| // TestUpdateVeryLargeObject tests that a small object can be updated to be very large without exceeding the size limit due to managedFields | // TestUpdateVeryLargeObject tests that a small object can be updated to be very large without exceeding the size limit due to managedFields | ||||||
| func TestUpdateVeryLargeObject(t *testing.T) { | func TestUpdateVeryLargeObject(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -729,8 +707,6 @@ func TestUpdateVeryLargeObject(t *testing.T) { | |||||||
|  |  | ||||||
| // TestPatchVeryLargeObject tests that a small object can be patched to be very large without exceeding the size limit due to managedFields | // TestPatchVeryLargeObject tests that a small object can be patched to be very large without exceeding the size limit due to managedFields | ||||||
| func TestPatchVeryLargeObject(t *testing.T) { | func TestPatchVeryLargeObject(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -788,8 +764,6 @@ func TestPatchVeryLargeObject(t *testing.T) { | |||||||
|  |  | ||||||
| // TestApplyManagedFields makes sure that managedFields api does not change | // TestApplyManagedFields makes sure that managedFields api does not change | ||||||
| func TestApplyManagedFields(t *testing.T) { | func TestApplyManagedFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -915,8 +889,6 @@ func TestApplyManagedFields(t *testing.T) { | |||||||
|  |  | ||||||
| // TestApplyRemovesEmptyManagedFields there are no empty managers in managedFields | // TestApplyRemovesEmptyManagedFields there are no empty managers in managedFields | ||||||
| func TestApplyRemovesEmptyManagedFields(t *testing.T) { | func TestApplyRemovesEmptyManagedFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -967,8 +939,6 @@ func TestApplyRemovesEmptyManagedFields(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestApplyRequiresFieldManager(t *testing.T) { | func TestApplyRequiresFieldManager(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1007,8 +977,6 @@ func TestApplyRequiresFieldManager(t *testing.T) { | |||||||
|  |  | ||||||
| // TestApplyRemoveContainerPort removes a container port from a deployment | // TestApplyRemoveContainerPort removes a container port from a deployment | ||||||
| func TestApplyRemoveContainerPort(t *testing.T) { | func TestApplyRemoveContainerPort(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1111,8 +1079,6 @@ func TestApplyRemoveContainerPort(t *testing.T) { | |||||||
| // TestApplyFailsWithVersionMismatch ensures that a version mismatch between the | // TestApplyFailsWithVersionMismatch ensures that a version mismatch between the | ||||||
| // patch object and the live object will error | // patch object and the live object will error | ||||||
| func TestApplyFailsWithVersionMismatch(t *testing.T) { | func TestApplyFailsWithVersionMismatch(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1208,8 +1174,6 @@ func TestApplyFailsWithVersionMismatch(t *testing.T) { | |||||||
| // TestApplyConvertsManagedFieldsVersion checks that the apply | // TestApplyConvertsManagedFieldsVersion checks that the apply | ||||||
| // converts the API group-version in the field manager | // converts the API group-version in the field manager | ||||||
| func TestApplyConvertsManagedFieldsVersion(t *testing.T) { | func TestApplyConvertsManagedFieldsVersion(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1351,8 +1315,6 @@ func TestApplyConvertsManagedFieldsVersion(t *testing.T) { | |||||||
|  |  | ||||||
| // TestClearManagedFieldsWithMergePatch verifies it's possible to clear the managedFields | // TestClearManagedFieldsWithMergePatch verifies it's possible to clear the managedFields | ||||||
| func TestClearManagedFieldsWithMergePatch(t *testing.T) { | func TestClearManagedFieldsWithMergePatch(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1407,8 +1369,6 @@ func TestClearManagedFieldsWithMergePatch(t *testing.T) { | |||||||
|  |  | ||||||
| // TestClearManagedFieldsWithStrategicMergePatch verifies it's possible to clear the managedFields | // TestClearManagedFieldsWithStrategicMergePatch verifies it's possible to clear the managedFields | ||||||
| func TestClearManagedFieldsWithStrategicMergePatch(t *testing.T) { | func TestClearManagedFieldsWithStrategicMergePatch(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1467,8 +1427,6 @@ func TestClearManagedFieldsWithStrategicMergePatch(t *testing.T) { | |||||||
|  |  | ||||||
| // TestClearManagedFieldsWithJSONPatch verifies it's possible to clear the managedFields | // TestClearManagedFieldsWithJSONPatch verifies it's possible to clear the managedFields | ||||||
| func TestClearManagedFieldsWithJSONPatch(t *testing.T) { | func TestClearManagedFieldsWithJSONPatch(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1523,8 +1481,6 @@ func TestClearManagedFieldsWithJSONPatch(t *testing.T) { | |||||||
|  |  | ||||||
| // TestClearManagedFieldsWithUpdate verifies it's possible to clear the managedFields | // TestClearManagedFieldsWithUpdate verifies it's possible to clear the managedFields | ||||||
| func TestClearManagedFieldsWithUpdate(t *testing.T) { | func TestClearManagedFieldsWithUpdate(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1597,8 +1553,6 @@ func TestClearManagedFieldsWithUpdate(t *testing.T) { | |||||||
|  |  | ||||||
| // TestErrorsDontFail | // TestErrorsDontFail | ||||||
| func TestErrorsDontFail(t *testing.T) { | func TestErrorsDontFail(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1637,8 +1591,6 @@ func TestErrorsDontFail(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestErrorsDontFailUpdate(t *testing.T) { | func TestErrorsDontFailUpdate(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1701,8 +1653,6 @@ func TestErrorsDontFailUpdate(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestErrorsDontFailPatch(t *testing.T) { | func TestErrorsDontFailPatch(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1751,8 +1701,6 @@ func TestErrorsDontFailPatch(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestApplyDoesNotChangeManagedFieldsViaSubresources(t *testing.T) { | func TestApplyDoesNotChangeManagedFieldsViaSubresources(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1854,8 +1802,6 @@ func TestApplyDoesNotChangeManagedFieldsViaSubresources(t *testing.T) { | |||||||
|  |  | ||||||
| // TestClearManagedFieldsWithUpdateEmptyList verifies it's possible to clear the managedFields by sending an empty list. | // TestClearManagedFieldsWithUpdateEmptyList verifies it's possible to clear the managedFields by sending an empty list. | ||||||
| func TestClearManagedFieldsWithUpdateEmptyList(t *testing.T) { | func TestClearManagedFieldsWithUpdateEmptyList(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -1939,8 +1885,6 @@ func TestClearManagedFieldsWithUpdateEmptyList(t *testing.T) { | |||||||
| // TestApplyUnsetExclusivelyOwnedFields verifies that when owned fields are omitted from an applied | // TestApplyUnsetExclusivelyOwnedFields verifies that when owned fields are omitted from an applied | ||||||
| // configuration, and no other managers own the field, it is removed. | // configuration, and no other managers own the field, it is removed. | ||||||
| func TestApplyUnsetExclusivelyOwnedFields(t *testing.T) { | func TestApplyUnsetExclusivelyOwnedFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2048,8 +1992,6 @@ func TestApplyUnsetExclusivelyOwnedFields(t *testing.T) { | |||||||
| // TestApplyUnsetSharedFields verifies that when owned fields are omitted from an applied | // TestApplyUnsetSharedFields verifies that when owned fields are omitted from an applied | ||||||
| // configuration, but other managers also own the field, is it not removed. | // configuration, but other managers also own the field, is it not removed. | ||||||
| func TestApplyUnsetSharedFields(t *testing.T) { | func TestApplyUnsetSharedFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2160,8 +2102,6 @@ func TestApplyUnsetSharedFields(t *testing.T) { | |||||||
| // object, a controller takes ownership of a field, and the applier | // object, a controller takes ownership of a field, and the applier | ||||||
| // then omits the field from its applied configuration, that the field value persists. | // then omits the field from its applied configuration, that the field value persists. | ||||||
| func TestApplyCanTransferFieldOwnershipToController(t *testing.T) { | func TestApplyCanTransferFieldOwnershipToController(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2279,8 +2219,6 @@ func TestApplyCanTransferFieldOwnershipToController(t *testing.T) { | |||||||
| // object, a controller modifies the contents of the map item via update, and the applier | // object, a controller modifies the contents of the map item via update, and the applier | ||||||
| // then omits the item from its applied configuration, that the item is removed. | // then omits the item from its applied configuration, that the item is removed. | ||||||
| func TestApplyCanRemoveMapItemsContributedToByControllers(t *testing.T) { | func TestApplyCanRemoveMapItemsContributedToByControllers(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2399,8 +2337,6 @@ func TestApplyCanRemoveMapItemsContributedToByControllers(t *testing.T) { | |||||||
|  |  | ||||||
| // TestDefaultMissingKeys makes sure that the missing keys default is used when merging. | // TestDefaultMissingKeys makes sure that the missing keys default is used when merging. | ||||||
| func TestDefaultMissingKeys(t *testing.T) { | func TestDefaultMissingKeys(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2647,23 +2583,7 @@ func encodePod(pod v1.Pod) []byte { | |||||||
| 	return podBytes | 	return podBytes | ||||||
| } | } | ||||||
|  |  | ||||||
| func BenchmarkNoServerSideApply(b *testing.B) { |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, false)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(b) |  | ||||||
| 	defer closeFn() |  | ||||||
| 	flag.Lookup("v").Value.Set("0") |  | ||||||
|  |  | ||||||
| 	benchAll(b, client, decodePod(podBytes)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func getPodSizeWhenEnabled(b *testing.B, pod v1.Pod) int { |  | ||||||
| 	return len(getPodBytesWhenEnabled(b, pod, "application/vnd.kubernetes.protobuf")) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func getPodBytesWhenEnabled(b *testing.B, pod v1.Pod, format string) []byte { | func getPodBytesWhenEnabled(b *testing.B, pod v1.Pod, format string) []byte { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(b) | 	client, closeFn := setup(b) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
| 	flag.Lookup("v").Value.Set("0") | 	flag.Lookup("v").Value.Set("0") | ||||||
| @@ -2682,48 +2602,9 @@ func getPodBytesWhenEnabled(b *testing.B, pod v1.Pod, format string) []byte { | |||||||
| 	return podB | 	return podB | ||||||
| } | } | ||||||
|  |  | ||||||
| func BenchmarkNoServerSideApplyButSameSize(b *testing.B) { |  | ||||||
| 	pod := decodePod(podBytes) |  | ||||||
|  |  | ||||||
| 	ssaPodSize := getPodSizeWhenEnabled(b, pod) |  | ||||||
|  |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, false)() |  | ||||||
| 	client, closeFn := setup(b) |  | ||||||
| 	defer closeFn() |  | ||||||
| 	flag.Lookup("v").Value.Set("0") |  | ||||||
|  |  | ||||||
| 	pod.Name = "size-pod" |  | ||||||
| 	noSSAPod, err := client.CoreV1().RESTClient().Post(). |  | ||||||
| 		Namespace("default"). |  | ||||||
| 		Resource("pods"). |  | ||||||
| 		SetHeader("Content-Type", "application/yaml"). |  | ||||||
| 		SetHeader("Accept", "application/vnd.kubernetes.protobuf"). |  | ||||||
| 		Body(encodePod(pod)).DoRaw(context.TODO()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		b.Fatalf("Failed to create object: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ssaDiff := ssaPodSize - len(noSSAPod) |  | ||||||
| 	fmt.Printf("Without SSA: %v bytes, With SSA: %v bytes, Difference: %v bytes\n", len(noSSAPod), ssaPodSize, ssaDiff) |  | ||||||
| 	annotations := pod.GetAnnotations() |  | ||||||
| 	builder := strings.Builder{} |  | ||||||
| 	for i := 0; i < ssaDiff; i++ { |  | ||||||
| 		builder.WriteByte('0') |  | ||||||
| 	} |  | ||||||
| 	if annotations == nil { |  | ||||||
| 		annotations = map[string]string{} |  | ||||||
| 	} |  | ||||||
| 	annotations["x-ssa-difference"] = builder.String() |  | ||||||
| 	pod.SetAnnotations(annotations) |  | ||||||
|  |  | ||||||
| 	benchAll(b, client, pod) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func BenchmarkServerSideApply(b *testing.B) { | func BenchmarkServerSideApply(b *testing.B) { | ||||||
| 	podBytesWhenEnabled := getPodBytesWhenEnabled(b, decodePod(podBytes), "application/yaml") | 	podBytesWhenEnabled := getPodBytesWhenEnabled(b, decodePod(podBytes), "application/yaml") | ||||||
|  |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(b) | 	client, closeFn := setup(b) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
| 	flag.Lookup("v").Value.Set("0") | 	flag.Lookup("v").Value.Set("0") | ||||||
| @@ -2858,8 +2739,6 @@ func benchRepeatedUpdate(client clientset.Interface, podName string) func(*testi | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestUpgradeClientSideToServerSideApply(t *testing.T) { | func TestUpgradeClientSideToServerSideApply(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -2987,108 +2866,7 @@ spec: | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestStopTrackingManagedFieldsOnFeatureDisabled(t *testing.T) { |  | ||||||
| 	sharedEtcd := framework.SharedEtcd() |  | ||||||
|  |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	// Disable ServiceAccount admission plugin as we don't have serviceaccount controller running. |  | ||||||
| 	server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, sharedEtcd) |  | ||||||
| 	client, err := clientset.NewForConfig(server.ClientConfig) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Error in create clientset: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	obj := []byte(` |  | ||||||
| apiVersion: apps/v1 |  | ||||||
| kind: Deployment |  | ||||||
| metadata: |  | ||||||
|   name: my-deployment |  | ||||||
| spec: |  | ||||||
|   selector: |  | ||||||
|     matchLabels: |  | ||||||
|       app: my-app |  | ||||||
|   template: |  | ||||||
|     metadata: |  | ||||||
|       labels: |  | ||||||
|         app: my-app |  | ||||||
|     spec: |  | ||||||
|       containers: |  | ||||||
|       - name: my-c |  | ||||||
|         image: my-image |  | ||||||
| `) |  | ||||||
|  |  | ||||||
| 	deployment, err := yamlutil.ToJSON(obj) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Failed marshal yaml: %v", err) |  | ||||||
| 	} |  | ||||||
| 	_, err = client.CoreV1().RESTClient().Patch(types.ApplyPatchType). |  | ||||||
| 		AbsPath("/apis/apps/v1"). |  | ||||||
| 		Namespace("default"). |  | ||||||
| 		Resource("deployments"). |  | ||||||
| 		Name("my-deployment"). |  | ||||||
| 		Param("fieldManager", "kubectl"). |  | ||||||
| 		Body(deployment). |  | ||||||
| 		Do(context.TODO()). |  | ||||||
| 		Get() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Failed to apply object: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	deploymentObj, err := client.AppsV1().Deployments("default").Get(context.TODO(), "my-deployment", metav1.GetOptions{}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Failed to get object: %v", err) |  | ||||||
| 	} |  | ||||||
| 	if managed := deploymentObj.GetManagedFields(); managed == nil { |  | ||||||
| 		t.Errorf("object doesn't have managedFields") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Restart server with server-side apply disabled |  | ||||||
| 	server.TearDownFn() |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, false)() |  | ||||||
|  |  | ||||||
| 	server = kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--disable-admission-plugins=ServiceAccount"}, sharedEtcd) |  | ||||||
| 	defer server.TearDownFn() |  | ||||||
| 	client, err = clientset.NewForConfig(server.ClientConfig) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Error in create clientset: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	_, err = client.CoreV1().RESTClient().Patch(types.ApplyPatchType). |  | ||||||
| 		AbsPath("/apis/apps/v1"). |  | ||||||
| 		Namespace("default"). |  | ||||||
| 		Resource("deployments"). |  | ||||||
| 		Name("my-deployment"). |  | ||||||
| 		Param("fieldManager", "kubectl"). |  | ||||||
| 		Body(deployment). |  | ||||||
| 		Do(context.TODO()). |  | ||||||
| 		Get() |  | ||||||
| 	if err == nil { |  | ||||||
| 		t.Errorf("expected to fail to apply object, but succeeded") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	_, err = client.CoreV1().RESTClient().Patch(types.MergePatchType). |  | ||||||
| 		AbsPath("/apis/apps/v1"). |  | ||||||
| 		Namespace("default"). |  | ||||||
| 		Resource("deployments"). |  | ||||||
| 		Name("my-deployment"). |  | ||||||
| 		Body([]byte(`{"metadata":{"labels": { "app": "v1" }}}`)).Do(context.TODO()).Get() |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Errorf("failed to update object: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	deploymentObj, err = client.AppsV1().Deployments("default").Get(context.TODO(), "my-deployment", metav1.GetOptions{}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Failed to get object: %v", err) |  | ||||||
| 	} |  | ||||||
| 	if managed := deploymentObj.GetManagedFields(); managed != nil { |  | ||||||
| 		t.Errorf("object has unexpected managedFields: %v", managed) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRenamingAppliedFieldManagers(t *testing.T) { | func TestRenamingAppliedFieldManagers(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -3179,8 +2957,6 @@ func TestRenamingAppliedFieldManagers(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestRenamingUpdatedFieldManagers(t *testing.T) { | func TestRenamingUpdatedFieldManagers(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -3281,8 +3057,6 @@ func TestRenamingUpdatedFieldManagers(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestDroppingSubresourceField(t *testing.T) { | func TestDroppingSubresourceField(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -3394,8 +3168,6 @@ func TestDroppingSubresourceField(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestDroppingSubresourceFromSpecField(t *testing.T) { | func TestDroppingSubresourceFromSpecField(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -3508,8 +3280,6 @@ func TestDroppingSubresourceFromSpecField(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestSubresourceField(t *testing.T) { | func TestSubresourceField(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -3599,8 +3369,6 @@ func TestSubresourceField(t *testing.T) { | |||||||
| // do not experience any friction when updating to a version of k8s which marks | // do not experience any friction when updating to a version of k8s which marks | ||||||
| // the fields' management again as granular. | // the fields' management again as granular. | ||||||
| func TestApplyFormerlyAtomicFields(t *testing.T) { | func TestApplyFormerlyAtomicFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	// Start server with our populated ObjectReference. Since it is atomic its | 	// Start server with our populated ObjectReference. Since it is atomic its | ||||||
| 	// ownership changed when XX popualted the UID after the user specified the | 	// ownership changed when XX popualted the UID after the user specified the | ||||||
| 	// GVKN. | 	// GVKN. | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
| @@ -38,7 +37,6 @@ import ( | |||||||
| 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	k8sfeatures "k8s.io/kubernetes/pkg/features" | 	k8sfeatures "k8s.io/kubernetes/pkg/features" | ||||||
|  |  | ||||||
| 	//k8sfeatures "k8s.io/kubernetes/pkg/features" |  | ||||||
| 	"k8s.io/kubernetes/test/integration/etcd" | 	"k8s.io/kubernetes/test/integration/etcd" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| 	"k8s.io/kubernetes/test/utils/image" | 	"k8s.io/kubernetes/test/utils/image" | ||||||
| @@ -153,7 +151,6 @@ var resetFieldsSpecData = map[schema.GroupVersionResource]string{ | |||||||
| // confirms that the fieldmanager1 is wiped of the status and fieldmanager2 is wiped of the spec. | // confirms that the fieldmanager1 is wiped of the status and fieldmanager2 is wiped of the spec. | ||||||
| // We then attempt to apply obj2 to the spec endpoint which fails with an expected conflict. | // We then attempt to apply obj2 to the spec endpoint which fails with an expected conflict. | ||||||
| func TestApplyResetFields(t *testing.T) { | func TestApplyResetFields(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, k8sfeatures.NetworkPolicyStatus, true)() | 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, k8sfeatures.NetworkPolicyStatus, true)() | ||||||
|  |  | ||||||
| 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), []string{"--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition"}, framework.SharedEtcd()) | 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), []string{"--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition"}, framework.SharedEtcd()) | ||||||
|   | |||||||
| @@ -30,11 +30,8 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" | 	"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
| 	"k8s.io/client-go/kubernetes/scheme" | 	"k8s.io/client-go/kubernetes/scheme" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	deploymentstorage "k8s.io/kubernetes/pkg/registry/apps/deployment/storage" | 	deploymentstorage "k8s.io/kubernetes/pkg/registry/apps/deployment/storage" | ||||||
| 	replicasetstorage "k8s.io/kubernetes/pkg/registry/apps/replicaset/storage" | 	replicasetstorage "k8s.io/kubernetes/pkg/registry/apps/replicaset/storage" | ||||||
| 	statefulsetstorage "k8s.io/kubernetes/pkg/registry/apps/statefulset/storage" | 	statefulsetstorage "k8s.io/kubernetes/pkg/registry/apps/statefulset/storage" | ||||||
| @@ -49,8 +46,6 @@ type scaleTest struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestScaleAllResources(t *testing.T) { | func TestScaleAllResources(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
| @@ -239,8 +234,6 @@ func TestScaleAllResources(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestScaleUpdateOnlyStatus(t *testing.T) { | func TestScaleUpdateOnlyStatus(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	client, closeFn := setup(t) | 	client, closeFn := setup(t) | ||||||
| 	defer closeFn() | 	defer closeFn() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,11 +28,8 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	"k8s.io/client-go/dynamic" | 	"k8s.io/client-go/dynamic" | ||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	"k8s.io/kubernetes/test/integration/etcd" | 	"k8s.io/kubernetes/test/integration/etcd" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| @@ -92,7 +89,6 @@ func createMapping(groupVersion string, resource metav1.APIResource) (*meta.REST | |||||||
|  |  | ||||||
| // TestApplyStatus makes sure that applying the status works for all known types. | // TestApplyStatus makes sure that applying the status works for all known types. | ||||||
| func TestApplyStatus(t *testing.T) { | func TestApplyStatus(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
| 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), []string{"--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition"}, framework.SharedEtcd()) | 	server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), []string{"--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition"}, framework.SharedEtcd()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|   | |||||||
| @@ -40,14 +40,11 @@ import ( | |||||||
| 	"k8s.io/apiserver/pkg/authentication/user" | 	"k8s.io/apiserver/pkg/authentication/user" | ||||||
| 	"k8s.io/apiserver/pkg/authorization/authorizer" | 	"k8s.io/apiserver/pkg/authorization/authorizer" | ||||||
| 	unionauthz "k8s.io/apiserver/pkg/authorization/union" | 	unionauthz "k8s.io/apiserver/pkg/authorization/union" | ||||||
| 	genericfeatures "k8s.io/apiserver/pkg/features" |  | ||||||
| 	"k8s.io/apiserver/pkg/registry/generic" | 	"k8s.io/apiserver/pkg/registry/generic" | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" |  | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
| 	watchtools "k8s.io/client-go/tools/watch" | 	watchtools "k8s.io/client-go/tools/watch" | ||||||
| 	"k8s.io/client-go/transport" | 	"k8s.io/client-go/transport" | ||||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" |  | ||||||
| 	"k8s.io/klog/v2" | 	"k8s.io/klog/v2" | ||||||
| 	"k8s.io/kubernetes/cmd/kube-apiserver/app/options" | 	"k8s.io/kubernetes/cmd/kube-apiserver/app/options" | ||||||
| 	rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1" | 	rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1" | ||||||
| @@ -302,8 +299,6 @@ var ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestRBAC(t *testing.T) { | func TestRBAC(t *testing.T) { | ||||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)() |  | ||||||
|  |  | ||||||
| 	superUser := "admin/system:masters" | 	superUser := "admin/system:masters" | ||||||
|  |  | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Wojciech Tyczyński
					Wojciech Tyczyński