Lock ServerSideApply feature to true

This commit is contained in:
Wojciech Tyczyński 2022-09-27 11:13:00 +02:00
parent 27b7d3cd41
commit 57c95fbfa1
21 changed files with 32 additions and 347 deletions

View File

@ -62,7 +62,7 @@ function run_kube_apiserver() {
AUTHORIZATION_MODE="RBAC,AlwaysAllow"
# Enable features
ENABLE_FEATURE_GATES="ServerSideApply=true"
ENABLE_FEATURE_GATES=""
"${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \
--bind-address="127.0.0.1" \

View File

@ -22,7 +22,6 @@ import (
"sort"
"time"
"k8s.io/apiserver/pkg/features"
rbacv1ac "k8s.io/client-go/applyconfigurations/rbac/v1"
"k8s.io/klog/v2"
@ -33,7 +32,6 @@ import (
"k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
rbacinformers "k8s.io/client-go/informers/rbac/v1"
rbacclient "k8s.io/client-go/kubernetes/typed/rbac/v1"
rbaclisters "k8s.io/client-go/listers/rbac/v1"
@ -125,16 +123,12 @@ func (c *ClusterRoleAggregationController) syncClusterRole(ctx context.Context,
return nil
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
err = c.applyClusterRoles(ctx, sharedClusterRole.Name, newPolicyRules)
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
// 1.21 since api-server can be 1.20 during the upgrade/downgrade.
// Since Server Side Apply is enabled by default in Beta, this fallback only kicks in
// if the feature has been disabled using its feature flag.
err = c.updateClusterRoles(ctx, sharedClusterRole, newPolicyRules)
}
} else {
err = c.applyClusterRoles(ctx, sharedClusterRole.Name, newPolicyRules)
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
// 1.21 since api-server can be 1.20 during the upgrade/downgrade.
// Since Server Side Apply is enabled by default in Beta, this fallback only kicks in
// if the feature has been disabled using its feature flag.
err = c.updateClusterRoles(ctx, sharedClusterRole, newPolicyRules)
}
return err

View File

@ -1034,7 +1034,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
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},

View File

@ -69,12 +69,10 @@ import (
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/apiserver/pkg/endpoints/metrics"
apirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
genericfilters "k8s.io/apiserver/pkg/server/filters"
"k8s.io/apiserver/pkg/storage/storagebackend"
utilfeature "k8s.io/apiserver/pkg/util/feature"
flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request"
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
"k8s.io/apiserver/pkg/util/webhook"
@ -330,9 +328,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
supportedTypes := []string{
string(types.JSONPatchType),
string(types.MergePatchType),
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
supportedTypes = append(supportedTypes, string(types.ApplyPatchType))
string(types.ApplyPatchType),
}
var handlerFunc http.HandlerFunc
@ -849,7 +845,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
standardSerializers = append(standardSerializers, s)
}
requestScopes[v.Name] = &handlers.RequestScope{
reqScope := handlers.RequestScope{
Namer: handlers.ContextBasedNaming{
Namer: meta.NewAccessor(),
ClusterScoped: clusterScoped,
@ -880,20 +876,18 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
MaxRequestBodyBytes: r.maxRequestBodyBytes,
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
resetFields := storages[v.Name].CustomResource.GetResetFields()
reqScope := *requestScopes[v.Name]
reqScope, err = scopeWithFieldManager(
typeConverter,
reqScope,
resetFields,
"",
)
if err != nil {
return nil, err
}
requestScopes[v.Name] = &reqScope
resetFields := storages[v.Name].CustomResource.GetResetFields()
reqScope, err = scopeWithFieldManager(
typeConverter,
reqScope,
resetFields,
"",
)
if err != nil {
return nil, err
}
requestScopes[v.Name] = &reqScope
scaleColumns, err := getScaleColumnsForVersion(crd, v.Name)
if err != nil {
@ -914,7 +908,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
}
scaleScope.TableConvertor = scaleTable
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Scale != nil {
if subresources != nil && subresources.Scale != nil {
scaleScope, err = scopeWithFieldManager(
typeConverter,
scaleScope,
@ -937,7 +931,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
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()
statusScope, err = scopeWithFieldManager(
typeConverter,
@ -1400,11 +1394,8 @@ func hasServedCRDVersion(spec *apiextensionsv1.CustomResourceDefinitionSpec, ver
// 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.
// 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) {
if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
return nil, nil
}
if staticOpenAPISpec == nil {
return nil, nil
}

View File

@ -340,11 +340,8 @@ func (b *builder) buildRoute(root, path, httpMethod, actionVerb, operationVerb s
supportedTypes := []string{
string(types.JSONPatchType),
string(types.MergePatchType),
string(types.ApplyPatchType),
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
supportedTypes = append(supportedTypes, string(types.ApplyPatchType))
}
route.Consumes(supportedTypes...)
} else {
route.Consumes(runtime.ContentTypeJSON, runtime.ContentTypeYAML)

View File

@ -31,8 +31,6 @@ import (
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/endpoints"
"k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kube-openapi/pkg/validation/spec"
utilpointer "k8s.io/utils/pointer"
)
@ -540,10 +538,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
actions.Insert(action)
}
if action == "patch" {
expected := []string{"application/json-patch+json", "application/merge-patch+json"}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
expected = append(expected, "application/apply-patch+yaml")
}
expected := []string{"application/json-patch+json", "application/merge-patch+json", "application/apply-patch+yaml"}
assert.Equal(t, operation.Consumes, expected)
} else {
assert.Equal(t, operation.Consumes, []string{"application/json", "application/yaml"})

View File

@ -26,15 +26,10 @@ import (
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
)
func TestApplyBasic(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
tearDown, config, _, err := fixtures.StartDefaultServer(t)
if err != nil {
t.Fatal(err)

View File

@ -32,10 +32,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
@ -387,8 +384,6 @@ func TestScaleSubresource(t *testing.T) {
}
func TestApplyScaleSubresource(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
tearDown, config, _, err := fixtures.StartDefaultServer(t)
if err != nil {
t.Fatal(err)

View File

@ -260,7 +260,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
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 {
resetFields = resetFieldsStrategy.GetResetFields()
}
@ -599,7 +599,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if a.group.MetaGroupVersion != nil {
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(
a.group.TypeConverter,
a.group.UnsafeConvertor,
@ -785,9 +785,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
string(types.JSONPatchType),
string(types.MergePatchType),
string(types.StrategicMergePatchType),
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
supportedTypes = append(supportedTypes, string(types.ApplyPatchType))
string(types.ApplyPatchType),
}
handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, deprecated, removedRelease, restfulPatchResource(patcher, reqScope, admit, supportedTypes))
handler = utilwarning.AddWarningsHandler(handler, warnings)

View File

@ -605,7 +605,7 @@ func CleanVerb(verb string, request *http.Request) string {
if verb == "WATCHLIST" {
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"
}
return reportedVerb

View File

@ -231,7 +231,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
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},

View File

@ -30,9 +30,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/storage/names"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/warning"
)
@ -121,11 +119,6 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx context.Context, obj runtime.
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 {
return errors.NewInvalid(kind.GroupKind(), objectMeta.GetName(), errs)
}

View File

@ -29,8 +29,6 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/warning"
)
@ -128,12 +126,6 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx context.Context, obj, old run
}
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)
// Use the existing UID if none is provided

View File

@ -666,7 +666,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A
}
apiGroupVersion.OpenAPIModels = openAPIModels
if openAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) {
if openAPIModels != nil {
typeConverter, err := fieldmanager.NewTypeConverter(openAPIModels, false)
if err != nil {
return err

View File

@ -29,10 +29,7 @@ import (
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"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
// when there is no validation field provided.
func TestApplyCRDNoSchema(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd())
if err != nil {
t.Fatal(err)

View File

@ -41,10 +41,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"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,
// it will be used to construct the CR schema used by apply.
func TestApplyCRDStructuralSchema(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd())
if err != nil {
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,
// apply falls back to non-schema behavior
func TestApplyCRDUnhandledSchema(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
storageConfig := framework.SharedEtcd()
tlsInfo := transport.TLSInfo{
CertFile: storageConfig.Transport.CertFile,
@ -608,8 +601,6 @@ func getManagedFields(rawResponse []byte) ([]metav1.ManagedFieldsEntry, error) {
}
func TestDefaultMissingKeyCRD(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd())
if err != nil {
t.Fatal(err)

View File

@ -23,7 +23,6 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"testing"
"time"
@ -39,11 +38,8 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
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"
restclient "k8s.io/client-go/rest"
featuregatetesting "k8s.io/component-base/featuregate/testing"
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"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
// 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) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -150,8 +144,6 @@ func TestApplyAlsoCreates(t *testing.T) {
// TestNoOpUpdateSameResourceVersion makes sure that PUT requests which change nothing
// will not change the resource version (no write to etcd is done)
func TestNoOpUpdateSameResourceVersion(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -264,8 +256,6 @@ func getRV(obj runtime.Object) (string, error) {
// - Applying an atomic struct that removes a default
// - Changing Quantity or other fields that are normalized
func TestNoSemanticUpdateApplySameResourceVersion(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -350,8 +340,6 @@ func TestNoSemanticUpdateApplySameResourceVersion(t *testing.T) {
// - Applying an atomic struct that removes a default
// - Changing Quantity or other fields that are normalized
func TestNoSemanticUpdatePutSameResourceVersion(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -431,8 +419,6 @@ func TestNoSemanticUpdatePutSameResourceVersion(t *testing.T) {
// 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
func TestCreateOnApplyFailsWithUID(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -463,8 +449,6 @@ func TestCreateOnApplyFailsWithUID(t *testing.T) {
}
func TestApplyUpdateApplyConflictForced(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -553,8 +537,6 @@ func TestApplyUpdateApplyConflictForced(t *testing.T) {
// TestApplyGroupsManySeparateUpdates tests that when many different managers update the same object,
// the number of managedFields entries will only grow to a certain size.
func TestApplyGroupsManySeparateUpdates(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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
func TestCreateVeryLargeObject(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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
func TestUpdateVeryLargeObject(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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
func TestPatchVeryLargeObject(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -788,8 +764,6 @@ func TestPatchVeryLargeObject(t *testing.T) {
// TestApplyManagedFields makes sure that managedFields api does not change
func TestApplyManagedFields(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -915,8 +889,6 @@ func TestApplyManagedFields(t *testing.T) {
// TestApplyRemovesEmptyManagedFields there are no empty managers in managedFields
func TestApplyRemovesEmptyManagedFields(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -967,8 +939,6 @@ func TestApplyRemovesEmptyManagedFields(t *testing.T) {
}
func TestApplyRequiresFieldManager(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1007,8 +977,6 @@ func TestApplyRequiresFieldManager(t *testing.T) {
// TestApplyRemoveContainerPort removes a container port from a deployment
func TestApplyRemoveContainerPort(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1111,8 +1079,6 @@ func TestApplyRemoveContainerPort(t *testing.T) {
// TestApplyFailsWithVersionMismatch ensures that a version mismatch between the
// patch object and the live object will error
func TestApplyFailsWithVersionMismatch(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1208,8 +1174,6 @@ func TestApplyFailsWithVersionMismatch(t *testing.T) {
// TestApplyConvertsManagedFieldsVersion checks that the apply
// converts the API group-version in the field manager
func TestApplyConvertsManagedFieldsVersion(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1351,8 +1315,6 @@ func TestApplyConvertsManagedFieldsVersion(t *testing.T) {
// TestClearManagedFieldsWithMergePatch verifies it's possible to clear the managedFields
func TestClearManagedFieldsWithMergePatch(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1407,8 +1369,6 @@ func TestClearManagedFieldsWithMergePatch(t *testing.T) {
// TestClearManagedFieldsWithStrategicMergePatch verifies it's possible to clear the managedFields
func TestClearManagedFieldsWithStrategicMergePatch(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1467,8 +1427,6 @@ func TestClearManagedFieldsWithStrategicMergePatch(t *testing.T) {
// TestClearManagedFieldsWithJSONPatch verifies it's possible to clear the managedFields
func TestClearManagedFieldsWithJSONPatch(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1523,8 +1481,6 @@ func TestClearManagedFieldsWithJSONPatch(t *testing.T) {
// TestClearManagedFieldsWithUpdate verifies it's possible to clear the managedFields
func TestClearManagedFieldsWithUpdate(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1597,8 +1553,6 @@ func TestClearManagedFieldsWithUpdate(t *testing.T) {
// TestErrorsDontFail
func TestErrorsDontFail(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1637,8 +1591,6 @@ func TestErrorsDontFail(t *testing.T) {
}
func TestErrorsDontFailUpdate(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1701,8 +1653,6 @@ func TestErrorsDontFailUpdate(t *testing.T) {
}
func TestErrorsDontFailPatch(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1751,8 +1701,6 @@ func TestErrorsDontFailPatch(t *testing.T) {
}
func TestApplyDoesNotChangeManagedFieldsViaSubresources(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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.
func TestClearManagedFieldsWithUpdateEmptyList(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -1939,8 +1885,6 @@ func TestClearManagedFieldsWithUpdateEmptyList(t *testing.T) {
// TestApplyUnsetExclusivelyOwnedFields verifies that when owned fields are omitted from an applied
// configuration, and no other managers own the field, it is removed.
func TestApplyUnsetExclusivelyOwnedFields(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -2048,8 +1992,6 @@ func TestApplyUnsetExclusivelyOwnedFields(t *testing.T) {
// TestApplyUnsetSharedFields verifies that when owned fields are omitted from an applied
// configuration, but other managers also own the field, is it not removed.
func TestApplyUnsetSharedFields(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -2160,8 +2102,6 @@ func TestApplyUnsetSharedFields(t *testing.T) {
// object, a controller takes ownership of a field, and the applier
// then omits the field from its applied configuration, that the field value persists.
func TestApplyCanTransferFieldOwnershipToController(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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
// then omits the item from its applied configuration, that the item is removed.
func TestApplyCanRemoveMapItemsContributedToByControllers(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -2399,8 +2337,6 @@ func TestApplyCanRemoveMapItemsContributedToByControllers(t *testing.T) {
// TestDefaultMissingKeys makes sure that the missing keys default is used when merging.
func TestDefaultMissingKeys(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -2647,23 +2583,7 @@ func encodePod(pod v1.Pod) []byte {
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 {
defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(b)
defer closeFn()
flag.Lookup("v").Value.Set("0")
@ -2682,48 +2602,9 @@ func getPodBytesWhenEnabled(b *testing.B, pod v1.Pod, format string) []byte {
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) {
podBytesWhenEnabled := getPodBytesWhenEnabled(b, decodePod(podBytes), "application/yaml")
defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(b)
defer closeFn()
flag.Lookup("v").Value.Set("0")
@ -2858,8 +2739,6 @@ func benchRepeatedUpdate(client clientset.Interface, podName string) func(*testi
}
func TestUpgradeClientSideToServerSideApply(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -3179,8 +2957,6 @@ func TestRenamingAppliedFieldManagers(t *testing.T) {
}
func TestRenamingUpdatedFieldManagers(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -3281,8 +3057,6 @@ func TestRenamingUpdatedFieldManagers(t *testing.T) {
}
func TestDroppingSubresourceField(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -3394,8 +3168,6 @@ func TestDroppingSubresourceField(t *testing.T) {
}
func TestDroppingSubresourceFromSpecField(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -3508,8 +3280,6 @@ func TestDroppingSubresourceFromSpecField(t *testing.T) {
}
func TestSubresourceField(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
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
// the fields' management again as granular.
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
// ownership changed when XX popualted the UID after the user specified the
// GVKN.

View File

@ -30,7 +30,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"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/kubernetes"
@ -38,7 +37,6 @@ import (
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
k8sfeatures "k8s.io/kubernetes/pkg/features"
//k8sfeatures "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/test/integration/etcd"
"k8s.io/kubernetes/test/integration/framework"
"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.
// We then attempt to apply obj2 to the spec endpoint which fails with an expected conflict.
func TestApplyResetFields(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, 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())

View File

@ -30,11 +30,8 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"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"
"k8s.io/client-go/kubernetes/scheme"
featuregatetesting "k8s.io/component-base/featuregate/testing"
deploymentstorage "k8s.io/kubernetes/pkg/registry/apps/deployment/storage"
replicasetstorage "k8s.io/kubernetes/pkg/registry/apps/replicaset/storage"
statefulsetstorage "k8s.io/kubernetes/pkg/registry/apps/statefulset/storage"
@ -49,8 +46,6 @@ type scaleTest struct {
}
func TestScaleAllResources(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()
@ -239,8 +234,6 @@ func TestScaleAllResources(t *testing.T) {
}
func TestScaleUpdateOnlyStatus(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
client, closeFn := setup(t)
defer closeFn()

View File

@ -28,11 +28,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"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/kubernetes"
featuregatetesting "k8s.io/component-base/featuregate/testing"
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"k8s.io/kubernetes/test/integration/etcd"
"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.
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())
if err != nil {
t.Fatal(err)

View File

@ -40,14 +40,11 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
unionauthz "k8s.io/apiserver/pkg/authorization/union"
genericfeatures "k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/registry/generic"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
watchtools "k8s.io/client-go/tools/watch"
"k8s.io/client-go/transport"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/klog/v2"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1"
@ -302,8 +299,6 @@ var (
)
func TestRBAC(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
superUser := "admin/system:masters"
tests := []struct {