From 7182d84b109bb1c928bd5bf92d8c175432b9eeae Mon Sep 17 00:00:00 2001 From: Jefftree Date: Tue, 20 Oct 2020 11:16:51 -0700 Subject: [PATCH 1/2] Reuse SSA type converter for resources in the same API Group --- .../pkg/apiserver/customresource_handler.go | 14 ++++++++---- .../apiserver/pkg/endpoints/groupversion.go | 2 ++ .../pkg/endpoints/handlers/fieldmanager/BUILD | 7 ++++++ .../handlers/fieldmanager/fieldmanager.go | 21 ++++-------------- .../fieldmanager/fieldmanager_test.go | 7 +++--- .../handlers/fieldmanager/internal/BUILD | 11 ---------- .../fieldmanager/internal/gvkparser.go | 8 +++---- .../fieldmanager/lastappliedmanager.go | 5 ++--- .../handlers/fieldmanager/structuredmerge.go | 10 ++++----- .../{internal => }/testdata/swagger.json | 0 .../{internal => }/typeconverter.go | 7 +++--- .../{internal => }/typeconverter_test.go | 18 +++++++-------- .../{internal => }/versionconverter.go | 2 +- .../{internal => }/versionconverter_test.go | 22 +++++++++---------- .../apiserver/pkg/endpoints/installer.go | 2 +- staging/src/k8s.io/apiserver/pkg/server/BUILD | 1 + .../apiserver/pkg/server/genericapiserver.go | 12 ++++++++++ 17 files changed, 76 insertions(+), 73 deletions(-) rename staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/{internal => }/testdata/swagger.json (100%) rename staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/{internal => }/typeconverter.go (95%) rename staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/{internal => }/typeconverter_test.go (90%) rename staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/{internal => }/versionconverter.go (99%) rename staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/{internal => }/versionconverter_test.go (75%) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index d3c7457bf35..e43a96fd6a3 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -669,6 +669,14 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd openAPIModels = nil } + var typeConverter fieldmanager.TypeConverter = fieldmanager.DeducedTypeConverter{} + if openAPIModels != nil { + typeConverter, err = fieldmanager.NewTypeConverter(openAPIModels, crd.Spec.PreserveUnknownFields) + if err != nil { + typeConverter = nil + } + } + safeConverter, unsafeConverter, err := r.converterFactory.NewConverter(crd) if err != nil { return nil, err @@ -842,13 +850,12 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { reqScope := *requestScopes[v.Name] reqScope.FieldManager, err = fieldmanager.NewDefaultCRDFieldManager( - openAPIModels, + typeConverter, reqScope.Convertor, reqScope.Defaulter, reqScope.Creater, reqScope.Kind, reqScope.HubGroupVersion, - crd.Spec.PreserveUnknownFields, false, ) if err != nil { @@ -879,13 +886,12 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd statusScope := *requestScopes[v.Name] if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { statusScope.FieldManager, err = fieldmanager.NewDefaultCRDFieldManager( - openAPIModels, + typeConverter, statusScope.Convertor, statusScope.Defaulter, statusScope.Creater, statusScope.Kind, statusScope.HubGroupVersion, - crd.Spec.PreserveUnknownFields, true, ) if err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go index 920369977a9..e9c57f18e3a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go @@ -30,6 +30,7 @@ import ( "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/endpoints/discovery" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/registry/rest" openapiproto "k8s.io/kube-openapi/pkg/util/proto" ) @@ -71,6 +72,7 @@ type APIGroupVersion struct { Defaulter runtime.ObjectDefaulter Linker runtime.SelfLinker UnsafeConvertor runtime.ObjectConvertor + TypeConverter fieldmanager.TypeConverter EquivalentResourceRegistry runtime.EquivalentResourceRegistry diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD index 4ebd85e7f4f..a16e42c22ff 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD @@ -12,6 +12,8 @@ go_library( "skipnonapplied.go", "stripmeta.go", "structuredmerge.go", + "typeconverter.go", + "versionconverter.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager", importpath = "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager", @@ -29,6 +31,8 @@ go_library( "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/typed:go_default_library", + "//vendor/sigs.k8s.io/structured-merge-diff/v4/value:go_default_library", ], ) @@ -58,11 +62,14 @@ go_test( "lastappliedupdater_test.go", "managedfieldsupdater_test.go", "skipnonapplied_test.go", + "typeconverter_test.go", + "versionconverter_test.go", ], data = [ "endpoints.yaml", "node.yaml", "pod.yaml", + "testdata/swagger.json", "//api/openapi-spec", ], embed = [":go_default_library"], diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 5008260ec7c..7e81fcc8920 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/klog/v2" - openapiproto "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/merge" ) @@ -79,12 +78,7 @@ func NewFieldManager(f Manager, ignoreManagedFieldsFromRequestObject bool) *Fiel // NewDefaultFieldManager creates a new FieldManager that merges apply requests // and update managed fields for other types of requests. -func NewDefaultFieldManager(models openapiproto.Models, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, ignoreManagedFieldsFromRequestObject bool) (*FieldManager, error) { - typeConverter, err := internal.NewTypeConverter(models, false) - if err != nil { - return nil, err - } - +func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, ignoreManagedFieldsFromRequestObject bool) (*FieldManager, error) { f, err := NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub) if err != nil { return nil, fmt.Errorf("failed to create field manager: %v", err) @@ -95,15 +89,8 @@ func NewDefaultFieldManager(models openapiproto.Models, objectConverter runtime. // NewDefaultCRDFieldManager creates a new FieldManager specifically for // CRDs. This allows for the possibility of fields which are not defined // in models, as well as having no models defined at all. -func NewDefaultCRDFieldManager(models openapiproto.Models, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, preserveUnknownFields, ignoreManagedFieldsFromRequestObject bool) (_ *FieldManager, err error) { - var typeConverter internal.TypeConverter = internal.DeducedTypeConverter{} - if models != nil { - typeConverter, err = internal.NewTypeConverter(models, preserveUnknownFields) - if err != nil { - return nil, err - } - } - f, err := NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, preserveUnknownFields) +func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, ignoreManagedFieldsFromRequestObject bool) (_ *FieldManager, err error) { + f, err := NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub) if err != nil { return nil, fmt.Errorf("failed to create field manager: %v", err) } @@ -111,7 +98,7 @@ func NewDefaultCRDFieldManager(models openapiproto.Models, objectConverter runti } // newDefaultFieldManager is a helper function which wraps a Manager with certain default logic. -func newDefaultFieldManager(f Manager, typeConverter internal.TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, ignoreManagedFieldsFromRequestObject bool) *FieldManager { +func newDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, ignoreManagedFieldsFromRequestObject bool) *FieldManager { f = NewStripMetaManager(f) f = NewManagedFieldsUpdater(f) f = NewBuildManagerInfoManager(f, kind.GroupVersion()) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go index b95f2938d60..971dbe477f8 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go @@ -37,7 +37,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" yamlutil "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/kube-openapi/pkg/util/proto" prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" @@ -96,7 +95,7 @@ func NewSubresourceTestFieldManager(gvk schema.GroupVersionKind) TestFieldManage func NewTestFieldManager(gvk schema.GroupVersionKind, ignoreManagedFieldsFromRequestObject bool, chainFieldManager func(fieldmanager.Manager) fieldmanager.Manager) TestFieldManager { m := NewFakeOpenAPIModels() typeConverter := NewFakeTypeConverter(m) - converter := internal.NewVersionConverter(typeConverter, &fakeObjectConvertor{}, gvk.GroupVersion()) + converter := fieldmanager.NewVersionConverter(typeConverter, &fakeObjectConvertor{}, gvk.GroupVersion()) apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String()) objectConverter := &fakeObjectConvertor{converter, apiVersion} f, err := fieldmanager.NewStructuredMergeManager( @@ -128,8 +127,8 @@ func NewTestFieldManager(gvk schema.GroupVersionKind, ignoreManagedFieldsFromReq } } -func NewFakeTypeConverter(m proto.Models) internal.TypeConverter { - tc, err := internal.NewTypeConverter(m, false) +func NewFakeTypeConverter(m proto.Models) fieldmanager.TypeConverter { + tc, err := fieldmanager.NewTypeConverter(m, false) if err != nil { panic(fmt.Sprintf("Failed to build TypeConverter: %v", err)) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD index 05b80967138..a282e3e62e5 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/BUILD @@ -9,8 +9,6 @@ go_library( "gvkparser.go", "managedfields.go", "pathelement.go", - "typeconverter.go", - "versionconverter.go", ], importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal", importpath = "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal", @@ -19,7 +17,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/schemaconv:go_default_library", @@ -39,22 +36,14 @@ go_test( "fields_test.go", "managedfields_test.go", "pathelement_test.go", - "typeconverter_test.go", - "versionconverter_test.go", ], data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", - "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", - "//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library", "//vendor/sigs.k8s.io/structured-merge-diff/v4/fieldpath:go_default_library", "//vendor/sigs.k8s.io/structured-merge-diff/v4/merge:go_default_library", - "//vendor/sigs.k8s.io/structured-merge-diff/v4/typed:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go index 5e2f82c7506..765d722ba56 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go @@ -30,12 +30,12 @@ import ( // definition's "extensions" map. const groupVersionKindExtensionKey = "x-kubernetes-group-version-kind" -type gvkParser struct { +type GvkParser struct { gvks map[schema.GroupVersionKind]string parser typed.Parser } -func (p *gvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { +func (p *GvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { typeName, ok := p.gvks[gvk] if !ok { return nil @@ -44,12 +44,12 @@ func (p *gvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { return &t } -func newGVKParser(models proto.Models, preserveUnknownFields bool) (*gvkParser, error) { +func NewGVKParser(models proto.Models, preserveUnknownFields bool) (*GvkParser, error) { typeSchema, err := schemaconv.ToSchemaWithPreserveUnknownFields(models, preserveUnknownFields) if err != nil { return nil, fmt.Errorf("failed to convert models to schema: %v", err) } - parser := gvkParser{ + parser := GvkParser{ gvks: map[schema.GroupVersionKind]string{}, } parser.parser = typed.Parser{Schema: *typeSchema} diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go index 7c4079a6e6f..4b07d462a22 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go @@ -25,14 +25,13 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/merge" ) type lastAppliedManager struct { fieldManager Manager - typeConverter internal.TypeConverter + typeConverter TypeConverter objectConverter runtime.ObjectConvertor groupVersion schema.GroupVersion } @@ -41,7 +40,7 @@ var _ Manager = &lastAppliedManager{} // NewLastAppliedManager converts the client-side apply annotation to // server-side apply managed fields -func NewLastAppliedManager(fieldManager Manager, typeConverter internal.TypeConverter, objectConverter runtime.ObjectConvertor, groupVersion schema.GroupVersion) Manager { +func NewLastAppliedManager(fieldManager Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, groupVersion schema.GroupVersion) Manager { return &lastAppliedManager{ fieldManager: fieldManager, typeConverter: typeConverter, diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go index a4761d3acd4..18157370713 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go @@ -29,7 +29,7 @@ import ( ) type structuredMergeManager struct { - typeConverter internal.TypeConverter + typeConverter TypeConverter objectConverter runtime.ObjectConvertor objectDefaulter runtime.ObjectDefaulter groupVersion schema.GroupVersion @@ -41,7 +41,7 @@ var _ Manager = &structuredMergeManager{} // NewStructuredMergeManager creates a new Manager that merges apply requests // and update managed fields for other types of requests. -func NewStructuredMergeManager(typeConverter internal.TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion) (Manager, error) { +func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion) (Manager, error) { return &structuredMergeManager{ typeConverter: typeConverter, objectConverter: objectConverter, @@ -49,7 +49,7 @@ func NewStructuredMergeManager(typeConverter internal.TypeConverter, objectConve groupVersion: gv, hubVersion: hub, updater: merge.Updater{ - Converter: internal.NewVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s + Converter: NewVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s }, }, nil } @@ -57,7 +57,7 @@ func NewStructuredMergeManager(typeConverter internal.TypeConverter, objectConve // NewCRDStructuredMergeManager creates a new Manager specifically for // CRDs. This allows for the possibility of fields which are not defined // in models, as well as having no models defined at all. -func NewCRDStructuredMergeManager(typeConverter internal.TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, preserveUnknownFields bool) (_ Manager, err error) { +func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion) (_ Manager, err error) { return &structuredMergeManager{ typeConverter: typeConverter, objectConverter: objectConverter, @@ -65,7 +65,7 @@ func NewCRDStructuredMergeManager(typeConverter internal.TypeConverter, objectCo groupVersion: gv, hubVersion: hub, updater: merge.Updater{ - Converter: internal.NewCRDVersionConverter(typeConverter, objectConverter, hub), + Converter: NewCRDVersionConverter(typeConverter, objectConverter, hub), }, }, nil } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/testdata/swagger.json similarity index 100% rename from staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json rename to staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/testdata/swagger.json diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go similarity index 95% rename from staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go rename to staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go index 6669665dde9..8bb2f0c9eb9 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package internal +package fieldmanager import ( "fmt" @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/typed" "sigs.k8s.io/structured-merge-diff/v4/value" @@ -64,7 +65,7 @@ func (DeducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Obje } type typeConverter struct { - parser *gvkParser + parser *internal.GvkParser } var _ TypeConverter = &typeConverter{} @@ -73,7 +74,7 @@ var _ TypeConverter = &typeConverter{} // will automatically find the proper version of the object, and the // corresponding schema information. func NewTypeConverter(models proto.Models, preserveUnknownFields bool) (TypeConverter, error) { - parser, err := newGVKParser(models, preserveUnknownFields) + parser, err := internal.NewGVKParser(models, preserveUnknownFields) if err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go similarity index 90% rename from staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go rename to staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go index 5876760d58a..f212649a490 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package internal_test +package fieldmanager_test import ( "fmt" @@ -26,17 +26,17 @@ import ( "sigs.k8s.io/yaml" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/kube-openapi/pkg/util/proto" prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" ) -var fakeSchema = prototesting.Fake{ +var fakeSchema2 = prototesting.Fake{ Path: filepath.Join("testdata", "swagger.json"), } func TestTypeConverter(t *testing.T) { - d, err := fakeSchema.OpenAPISchema() + d, err := fakeSchema2.OpenAPISchema() if err != nil { t.Fatalf("Failed to parse OpenAPI schema: %v", err) } @@ -45,12 +45,12 @@ func TestTypeConverter(t *testing.T) { t.Fatalf("Failed to build OpenAPI models: %v", err) } - tc, err := internal.NewTypeConverter(m, false) + tc, err := fieldmanager.NewTypeConverter(m, false) if err != nil { t.Fatalf("Failed to build TypeConverter: %v", err) } - dtc := internal.DeducedTypeConverter{} + dtc := fieldmanager.DeducedTypeConverter{} testCases := []struct { name string @@ -127,7 +127,7 @@ spec: } } -func testObjectToTyped(t *testing.T, tc internal.TypeConverter, y string) { +func testObjectToTyped(t *testing.T, tc fieldmanager.TypeConverter, y string) { obj := &unstructured.Unstructured{Object: map[string]interface{}{}} if err := yaml.Unmarshal([]byte(y), &obj.Object); err != nil { t.Fatalf("Failed to parse yaml object: %v", err) @@ -177,7 +177,7 @@ spec: b.Fatalf("Failed to parse yaml object: %v", err) } - d, err := fakeSchema.OpenAPISchema() + d, err := fakeSchema2.OpenAPISchema() if err != nil { b.Fatalf("Failed to parse OpenAPI schema: %v", err) } @@ -186,7 +186,7 @@ spec: b.Fatalf("Failed to build OpenAPI models: %v", err) } - tc, err := internal.NewTypeConverter(m, false) + tc, err := fieldmanager.NewTypeConverter(m, false) if err != nil { b.Fatalf("Failed to build TypeConverter: %v", err) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go similarity index 99% rename from staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go rename to staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go index fc59f2f0ef0..73b86c6aa1c 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package internal +package fieldmanager import ( "k8s.io/apimachinery/pkg/runtime" diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go similarity index 75% rename from staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter_test.go rename to staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go index 3c6892085d2..4257a33f0db 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package internal_test +package fieldmanager_test import ( "fmt" @@ -24,14 +24,14 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) // TestVersionConverter tests the version converter func TestVersionConverter(t *testing.T) { - d, err := fakeSchema.OpenAPISchema() + d, err := fakeSchema2.OpenAPISchema() if err != nil { t.Fatalf("Failed to parse OpenAPI schema: %v", err) } @@ -39,15 +39,15 @@ func TestVersionConverter(t *testing.T) { if err != nil { t.Fatalf("Failed to build OpenAPI models: %v", err) } - tc, err := internal.NewTypeConverter(m, false) + tc, err := fieldmanager.NewTypeConverter(m, false) if err != nil { t.Fatalf("Failed to build TypeConverter: %v", err) } - oc := fakeObjectConvertor{ + oc := fakeObjectConvertorForTestSchema{ gvkForVersion("v1beta1"): objForGroupVersion("apps/v1beta1"), gvkForVersion("v1"): objForGroupVersion("apps/v1"), } - vc := internal.NewVersionConverter(tc, oc, schema.GroupVersion{Group: "apps", Version: runtime.APIVersionInternal}) + vc := fieldmanager.NewVersionConverter(tc, oc, schema.GroupVersion{Group: "apps", Version: runtime.APIVersionInternal}) input, err := tc.ObjectToTyped(objForGroupVersion("apps/v1beta1")) if err != nil { @@ -85,11 +85,11 @@ func objForGroupVersion(gv string) runtime.Object { } } -type fakeObjectConvertor map[schema.GroupVersionKind]runtime.Object +type fakeObjectConvertorForTestSchema map[schema.GroupVersionKind]runtime.Object -var _ runtime.ObjectConvertor = fakeObjectConvertor{} +var _ runtime.ObjectConvertor = fakeObjectConvertorForTestSchema{} -func (c fakeObjectConvertor) ConvertToVersion(_ runtime.Object, gv runtime.GroupVersioner) (runtime.Object, error) { +func (c fakeObjectConvertorForTestSchema) ConvertToVersion(_ runtime.Object, gv runtime.GroupVersioner) (runtime.Object, error) { allKinds := make([]schema.GroupVersionKind, 0) for kind := range c { allKinds = append(allKinds, kind) @@ -98,10 +98,10 @@ func (c fakeObjectConvertor) ConvertToVersion(_ runtime.Object, gv runtime.Group return c[gvk], nil } -func (fakeObjectConvertor) Convert(_, _, _ interface{}) error { +func (fakeObjectConvertorForTestSchema) Convert(_, _, _ interface{}) error { return fmt.Errorf("function not implemented") } -func (fakeObjectConvertor) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) { +func (fakeObjectConvertorForTestSchema) ConvertFieldLabel(_ schema.GroupVersionKind, _, _ string) (string, string, error) { return "", "", fmt.Errorf("function not implemented") } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 3257bf59f67..cabae0c464c 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -564,7 +564,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag } if a.group.OpenAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { reqScope.FieldManager, err = fieldmanager.NewDefaultFieldManager( - a.group.OpenAPIModels, + a.group.TypeConverter, a.group.UnsafeConvertor, a.group.Defaulter, a.group.Creater, diff --git a/staging/src/k8s.io/apiserver/pkg/server/BUILD b/staging/src/k8s.io/apiserver/pkg/server/BUILD index 329989c755f..ccbc721df2c 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/BUILD @@ -101,6 +101,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/endpoints:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/filters:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go index e0bbc31671c..0280730afea 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -40,9 +40,12 @@ import ( "k8s.io/apiserver/pkg/authorization/authorizer" genericapi "k8s.io/apiserver/pkg/endpoints" "k8s.io/apiserver/pkg/endpoints/discovery" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" + "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/routes" + utilfeature "k8s.io/apiserver/pkg/util/feature" utilopenapi "k8s.io/apiserver/pkg/util/openapi" restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" @@ -418,6 +421,15 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion } apiGroupVersion.OpenAPIModels = openAPIModels + + if openAPIModels != nil && utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) { + typeConverter, err := fieldmanager.NewTypeConverter(openAPIModels, false) + if err != nil { + return err + } + apiGroupVersion.TypeConverter = typeConverter + } + apiGroupVersion.MaxRequestBodyBytes = s.maxRequestBodyBytes if err := apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer); err != nil { From 1f986cc69d8ac5b579ccc2e6817fd0a07903692b Mon Sep 17 00:00:00 2001 From: Jefftree Date: Thu, 22 Oct 2020 13:21:38 -0700 Subject: [PATCH 2/2] Make versionconverter functions private --- .../pkg/apiserver/customresource_handler.go | 2 +- .../handlers/fieldmanager/capmanagers_test.go | 17 ++++--- .../fieldmanager/fieldmanager_test.go | 47 +++++++------------ .../fieldmanager/internal/gvkparser.go | 6 +++ .../fieldmanager/lastappliedmanager_test.go | 2 +- .../fieldmanager/lastappliedupdater_test.go | 7 ++- .../fieldmanager/managedfieldsupdater_test.go | 2 +- .../fieldmanager/skipnonapplied_test.go | 11 ++--- .../handlers/fieldmanager/structuredmerge.go | 4 +- .../fieldmanager/typeconverter_test.go | 6 +-- .../handlers/fieldmanager/versionconverter.go | 4 +- .../fieldmanager/versionconverter_test.go | 15 ++++-- 12 files changed, 58 insertions(+), 65 deletions(-) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index e43a96fd6a3..749ad7552f2 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -673,7 +673,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd if openAPIModels != nil { typeConverter, err = fieldmanager.NewTypeConverter(openAPIModels, crd.Spec.PreserveUnknownFields) if err != nil { - typeConverter = nil + return nil, err } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers_test.go index aaf2c96a067..3e79450551a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "bytes" @@ -29,19 +29,18 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) type fakeManager struct{} -var _ fieldmanager.Manager = &fakeManager{} +var _ Manager = &fakeManager{} -func (*fakeManager) Update(_, newObj runtime.Object, managed fieldmanager.Managed, _ string) (runtime.Object, fieldmanager.Managed, error) { +func (*fakeManager) Update(_, newObj runtime.Object, managed Managed, _ string) (runtime.Object, Managed, error) { return newObj, managed, nil } -func (*fakeManager) Apply(_, _ runtime.Object, _ fieldmanager.Managed, _ string, _ bool) (runtime.Object, fieldmanager.Managed, error) { +func (*fakeManager) Apply(_, _ runtime.Object, _ Managed, _ string, _ bool) (runtime.Object, Managed, error) { panic("not implemented") return nil, nil, nil } @@ -49,8 +48,8 @@ func (*fakeManager) Apply(_, _ runtime.Object, _ fieldmanager.Managed, _ string, func TestCapManagersManagerMergesEntries(t *testing.T) { f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, - func(m fieldmanager.Manager) fieldmanager.Manager { - return fieldmanager.NewCapManagersManager(m, 3) + func(m Manager) Manager { + return NewCapManagersManager(m, 3) }) podWithLabels := func(labels ...string) runtime.Object { @@ -115,8 +114,8 @@ func TestCapManagersManagerMergesEntries(t *testing.T) { func TestCapUpdateManagers(t *testing.T) { f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, - func(m fieldmanager.Manager) fieldmanager.Manager { - return fieldmanager.NewCapManagersManager(m, 3) + func(m Manager) Manager { + return NewCapManagersManager(m, 3) }) set := func(fields ...string) *metav1.FieldsV1 { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go index 971dbe477f8..7dc59285d33 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "errors" @@ -36,7 +36,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" yamlutil "k8s.io/apimachinery/pkg/util/yaml" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/kube-openapi/pkg/util/proto" prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" @@ -45,7 +44,7 @@ import ( "sigs.k8s.io/yaml" ) -var fakeSchema = prototesting.Fake{ +var kubernetesSwaggerSchema = prototesting.Fake{ Path: filepath.Join( strings.Repeat(".."+string(filepath.Separator), 8), "api", "openapi-spec", "swagger.json"), @@ -79,7 +78,7 @@ type fakeObjectDefaulter struct{} func (d *fakeObjectDefaulter) Default(in runtime.Object) {} type TestFieldManager struct { - fieldManager *fieldmanager.FieldManager + fieldManager *FieldManager emptyObj runtime.Object liveObj runtime.Object } @@ -92,13 +91,13 @@ func NewSubresourceTestFieldManager(gvk schema.GroupVersionKind) TestFieldManage return NewTestFieldManager(gvk, true, nil) } -func NewTestFieldManager(gvk schema.GroupVersionKind, ignoreManagedFieldsFromRequestObject bool, chainFieldManager func(fieldmanager.Manager) fieldmanager.Manager) TestFieldManager { +func NewTestFieldManager(gvk schema.GroupVersionKind, ignoreManagedFieldsFromRequestObject bool, chainFieldManager func(Manager) Manager) TestFieldManager { m := NewFakeOpenAPIModels() typeConverter := NewFakeTypeConverter(m) - converter := fieldmanager.NewVersionConverter(typeConverter, &fakeObjectConvertor{}, gvk.GroupVersion()) + converter := newVersionConverter(typeConverter, &fakeObjectConvertor{}, gvk.GroupVersion()) apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String()) objectConverter := &fakeObjectConvertor{converter, apiVersion} - f, err := fieldmanager.NewStructuredMergeManager( + f, err := NewStructuredMergeManager( typeConverter, objectConverter, &fakeObjectDefaulter{}, @@ -111,24 +110,24 @@ func NewTestFieldManager(gvk schema.GroupVersionKind, ignoreManagedFieldsFromReq live := &unstructured.Unstructured{} live.SetKind(gvk.Kind) live.SetAPIVersion(gvk.GroupVersion().String()) - f = fieldmanager.NewStripMetaManager(f) - f = fieldmanager.NewManagedFieldsUpdater(f) - f = fieldmanager.NewBuildManagerInfoManager(f, gvk.GroupVersion()) - f = fieldmanager.NewProbabilisticSkipNonAppliedManager(f, &fakeObjectCreater{gvk: gvk}, gvk, fieldmanager.DefaultTrackOnCreateProbability) - f = fieldmanager.NewLastAppliedManager(f, typeConverter, objectConverter, gvk.GroupVersion()) - f = fieldmanager.NewLastAppliedUpdater(f) + f = NewStripMetaManager(f) + f = NewManagedFieldsUpdater(f) + f = NewBuildManagerInfoManager(f, gvk.GroupVersion()) + f = NewProbabilisticSkipNonAppliedManager(f, &fakeObjectCreater{gvk: gvk}, gvk, DefaultTrackOnCreateProbability) + f = NewLastAppliedManager(f, typeConverter, objectConverter, gvk.GroupVersion()) + f = NewLastAppliedUpdater(f) if chainFieldManager != nil { f = chainFieldManager(f) } return TestFieldManager{ - fieldManager: fieldmanager.NewFieldManager(f, ignoreManagedFieldsFromRequestObject), + fieldManager: NewFieldManager(f, ignoreManagedFieldsFromRequestObject), emptyObj: live, liveObj: live.DeepCopyObject(), } } -func NewFakeTypeConverter(m proto.Models) fieldmanager.TypeConverter { - tc, err := fieldmanager.NewTypeConverter(m, false) +func NewFakeTypeConverter(m proto.Models) TypeConverter { + tc, err := NewTypeConverter(m, false) if err != nil { panic(fmt.Sprintf("Failed to build TypeConverter: %v", err)) } @@ -136,7 +135,7 @@ func NewFakeTypeConverter(m proto.Models) fieldmanager.TypeConverter { } func NewFakeOpenAPIModels() proto.Models { - d, err := fakeSchema.OpenAPISchema() + d, err := kubernetesSwaggerSchema.OpenAPISchema() if err != nil { panic(err) } @@ -1206,20 +1205,6 @@ func setLastAppliedFromEncoded(obj runtime.Object, lastApplied []byte) error { return setLastApplied(obj, lastAppliedJSON) } -func setLastApplied(obj runtime.Object, lastApplied string) error { - accessor := meta.NewAccessor() - annotations, err := accessor.Annotations(obj) - if err != nil { - return fmt.Errorf("failed to access annotations: %v", err) - } - if annotations == nil { - annotations = map[string]string{} - } - annotations[corev1.LastAppliedConfigAnnotation] = lastApplied - accessor.SetAnnotations(obj, annotations) - return nil -} - func getLastApplied(obj runtime.Object) (string, error) { accessor := meta.NewAccessor() annotations, err := accessor.Annotations(obj) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go index 765d722ba56..f8abcaf04ef 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go @@ -30,11 +30,14 @@ import ( // definition's "extensions" map. const groupVersionKindExtensionKey = "x-kubernetes-group-version-kind" +// GvkParser contains a Parser that allows introspecting the schema. type GvkParser struct { gvks map[schema.GroupVersionKind]string parser typed.Parser } +// Type returns a helper which can produce objects of the given type. Any +// errors are deferred until a further function is called. func (p *GvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { typeName, ok := p.gvks[gvk] if !ok { @@ -44,6 +47,9 @@ func (p *GvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { return &t } +// NewGVKParser builds a GVKParser from a proto.Models. This +// will automatically find the proper version of the object, and the +// corresponding schema information. func NewGVKParser(models proto.Models, preserveUnknownFields bool) (*GvkParser, error) { typeSchema, err := schemaconv.ToSchemaWithPreserveUnknownFields(models, preserveUnknownFields) if err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager_test.go index 63adce6831b..f6a2872d748 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "fmt" diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater_test.go index 7c3d2362ddf..14e9aa167da 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "strings" @@ -22,15 +22,14 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "sigs.k8s.io/yaml" ) func TestLastAppliedUpdater(t *testing.T) { f := NewTestFieldManager(schema.FromAPIVersionAndKind("apps/v1", "Deployment"), false, - func(m fieldmanager.Manager) fieldmanager.Manager { - return fieldmanager.NewLastAppliedUpdater(m) + func(m Manager) Manager { + return NewLastAppliedUpdater(m) }) originalLastApplied := `nonempty` diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater_test.go index f961989b6ab..2e1ad3d0b11 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "reflect" diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied_test.go index 8c7ac7019cd..c9e2dc02b13 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "strings" @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "sigs.k8s.io/yaml" ) @@ -43,8 +42,8 @@ func (f *fakeObjectCreater) New(_ schema.GroupVersionKind) (runtime.Object, erro } func TestNoUpdateBeforeFirstApply(t *testing.T) { - f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, func(m fieldmanager.Manager) fieldmanager.Manager { - return fieldmanager.NewSkipNonAppliedManager( + f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, func(m Manager) Manager { + return NewSkipNonAppliedManager( m, &fakeObjectCreater{gvk: schema.GroupVersionKind{Version: "v1", Kind: "Pod"}}, schema.GroupVersionKind{}, @@ -83,8 +82,8 @@ func TestNoUpdateBeforeFirstApply(t *testing.T) { } func TestUpdateBeforeFirstApply(t *testing.T) { - f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, func(m fieldmanager.Manager) fieldmanager.Manager { - return fieldmanager.NewSkipNonAppliedManager( + f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, func(m Manager) Manager { + return NewSkipNonAppliedManager( m, &fakeObjectCreater{gvk: schema.GroupVersionKind{Version: "v1", Kind: "Pod"}}, schema.GroupVersionKind{}, diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go index 18157370713..216a39cf7a5 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go @@ -49,7 +49,7 @@ func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runt groupVersion: gv, hubVersion: hub, updater: merge.Updater{ - Converter: NewVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s + Converter: newVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s }, }, nil } @@ -65,7 +65,7 @@ func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter r groupVersion: gv, hubVersion: hub, updater: merge.Updater{ - Converter: NewCRDVersionConverter(typeConverter, objectConverter, hub), + Converter: newCRDVersionConverter(typeConverter, objectConverter, hub), }, }, nil } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go index f212649a490..df7312b7306 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter_test.go @@ -31,12 +31,12 @@ import ( prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" ) -var fakeSchema2 = prototesting.Fake{ +var testSchema = prototesting.Fake{ Path: filepath.Join("testdata", "swagger.json"), } func TestTypeConverter(t *testing.T) { - d, err := fakeSchema2.OpenAPISchema() + d, err := testSchema.OpenAPISchema() if err != nil { t.Fatalf("Failed to parse OpenAPI schema: %v", err) } @@ -177,7 +177,7 @@ spec: b.Fatalf("Failed to parse yaml object: %v", err) } - d, err := fakeSchema2.OpenAPISchema() + d, err := testSchema.OpenAPISchema() if err != nil { b.Fatalf("Failed to parse OpenAPI schema: %v", err) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go index 73b86c6aa1c..477e92f796e 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go @@ -35,7 +35,7 @@ type versionConverter struct { var _ merge.Converter = &versionConverter{} // NewVersionConverter builds a VersionConverter from a TypeConverter and an ObjectConvertor. -func NewVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { +func newVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { return &versionConverter{ typeConverter: t, objectConvertor: o, @@ -49,7 +49,7 @@ func NewVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.Gr } // NewCRDVersionConverter builds a VersionConverter for CRDs from a TypeConverter and an ObjectConvertor. -func NewCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { +func newCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { return &versionConverter{ typeConverter: t, objectConvertor: o, diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go index 4257a33f0db..c6ca32007cf 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter_test.go @@ -14,24 +14,29 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager_test +package fieldmanager import ( "fmt" + "path/filepath" "reflect" "testing" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/kube-openapi/pkg/util/proto" + prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) +var testSchema = prototesting.Fake{ + Path: filepath.Join("testdata", "swagger.json"), +} + // TestVersionConverter tests the version converter func TestVersionConverter(t *testing.T) { - d, err := fakeSchema2.OpenAPISchema() + d, err := testSchema.OpenAPISchema() if err != nil { t.Fatalf("Failed to parse OpenAPI schema: %v", err) } @@ -39,7 +44,7 @@ func TestVersionConverter(t *testing.T) { if err != nil { t.Fatalf("Failed to build OpenAPI models: %v", err) } - tc, err := fieldmanager.NewTypeConverter(m, false) + tc, err := NewTypeConverter(m, false) if err != nil { t.Fatalf("Failed to build TypeConverter: %v", err) } @@ -47,7 +52,7 @@ func TestVersionConverter(t *testing.T) { gvkForVersion("v1beta1"): objForGroupVersion("apps/v1beta1"), gvkForVersion("v1"): objForGroupVersion("apps/v1"), } - vc := fieldmanager.NewVersionConverter(tc, oc, schema.GroupVersion{Group: "apps", Version: runtime.APIVersionInternal}) + vc := newVersionConverter(tc, oc, schema.GroupVersion{Group: "apps", Version: runtime.APIVersionInternal}) input, err := tc.ObjectToTyped(objForGroupVersion("apps/v1beta1")) if err != nil {