Reuse SSA type converter for resources in the same API Group
This commit is contained in:
		| @@ -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 { | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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"], | ||||
|   | ||||
| @@ -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()) | ||||
|   | ||||
| @@ -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)) | ||||
| 	} | ||||
|   | ||||
| @@ -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", | ||||
|     ], | ||||
| ) | ||||
|   | ||||
| @@ -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} | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
| @@ -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) | ||||
| 	} | ||||
| @@ -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" | ||||
| @@ -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") | ||||
| } | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jefftree
					Jefftree