From 1cd71cbb14ecfd0ec6c5e8a57db6be00ecb8a4d1 Mon Sep 17 00:00:00 2001 From: Alvaro Aleman Date: Sun, 2 Mar 2025 12:43:08 -0500 Subject: [PATCH] ManagedFieldsObjectTracker: Reload scheme In controller-runtime it is generally not expected to do any sort of scheme registration if unstructured.Unstructured is used. To make this work in the fakeclient, the fakeclient will register unstructured to scheme if the scheme doesn't recognize the GVK. This currently doesn't work with the `ManagedFieldsObjectTracker` as it never reloads the scheme. This change makes it reload the scheme in an inefficient but simple manner, which should be good enough for unit tests. --- .../src/k8s.io/client-go/testing/fixture.go | 17 ++++++++------ .../k8s.io/client-go/testing/fixture_test.go | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/staging/src/k8s.io/client-go/testing/fixture.go b/staging/src/k8s.io/client-go/testing/fixture.go index 3e749782135..2bec0ed6560 100644 --- a/staging/src/k8s.io/client-go/testing/fixture.go +++ b/staging/src/k8s.io/client-go/testing/fixture.go @@ -631,7 +631,7 @@ type managedFieldObjectTracker struct { ObjectTracker scheme ObjectScheme objectConverter runtime.ObjectConvertor - mapper meta.RESTMapper + mapper func() meta.RESTMapper typeConverter managedfields.TypeConverter } @@ -644,8 +644,10 @@ func NewFieldManagedObjectTracker(scheme *runtime.Scheme, decoder runtime.Decode ObjectTracker: NewObjectTracker(scheme, decoder), scheme: scheme, objectConverter: scheme, - mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme), - typeConverter: typeConverter, + mapper: func() meta.RESTMapper { + return testrestmapper.TestOnlyStaticRESTMapper(scheme) + }, + typeConverter: typeConverter, } } @@ -654,7 +656,7 @@ func (t *managedFieldObjectTracker) Create(gvr schema.GroupVersionResource, obj if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } @@ -698,8 +700,9 @@ func (t *managedFieldObjectTracker) Update(gvr schema.GroupVersionResource, obj if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { + println("kindfor") return err } mgr, err := t.fieldManagerFor(gvk) @@ -728,7 +731,7 @@ func (t *managedFieldObjectTracker) Patch(gvr schema.GroupVersionResource, patch if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } @@ -757,7 +760,7 @@ func (t *managedFieldObjectTracker) Apply(gvr schema.GroupVersionResource, apply if err != nil { return err } - gvk, err := t.mapper.KindFor(gvr) + gvk, err := t.mapper().KindFor(gvr) if err != nil { return err } diff --git a/staging/src/k8s.io/client-go/testing/fixture_test.go b/staging/src/k8s.io/client-go/testing/fixture_test.go index 2fa67cd6dcd..54c2502475c 100644 --- a/staging/src/k8s.io/client-go/testing/fixture_test.go +++ b/staging/src/k8s.io/client-go/testing/fixture_test.go @@ -661,3 +661,25 @@ var configMapTypedSchema = typed.YAMLObject(`types: namedType: __untyped_deduced_ elementRelationship: separable `) + +func TestManagedFieldsObjectTrackerReloadsScheme(t *testing.T) { + cmResource := schema.GroupVersionResource{Version: "v1", Resource: "configmaps"} + scheme := runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + + // Create tracker without registered ConfigMap type + tracker := NewFieldManagedObjectTracker(scheme, codecs.UniversalDecoder(), configMapTypeConverter(scheme)) + + cm := &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + }, + Data: map[string]string{"key": "value"}, + } + + // Register the type in scheme + scheme.AddKnownTypes(cmResource.GroupVersion(), &v1.ConfigMap{}) + + err := tracker.Create(cmResource, cm, "default", metav1.CreateOptions{FieldManager: "test-manager"}) + assert.NoError(t, err, "Create should succeed after registering type") +}