From 350fef76f535146ed4ae4adc2098c7ad8aa6a7e0 Mon Sep 17 00:00:00 2001 From: jennybuckley Date: Wed, 5 Jun 2019 14:09:08 -0700 Subject: [PATCH] Only update managedFields on update if it already exists Kubernetes-commit: 9a12e37a6dc28fd1d209eb84c210eb0723e6e38f --- .../handlers/fieldmanager/fieldmanager.go | 25 ++++++++++++++++++- .../fieldmanager/fieldmanager_test.go | 3 +++ pkg/endpoints/handlers/patch.go | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 66bdc7937..6a0bc579f 100644 --- a/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -104,6 +104,10 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r return nil, fmt.Errorf("failed to decode managed fields: %v", err) } } + // if managed field is still empty, skip updating managed fields altogether + if len(managed.Fields) == 0 { + return newObj, nil + } newObjVersioned, err := f.toVersioned(newObj) if err != nil { return nil, fmt.Errorf("failed to convert new object to proper version: %v", err) @@ -165,9 +169,11 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r // object and update the managed fields. func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager string, force bool) (runtime.Object, error) { // If the object doesn't have metadata, apply isn't allowed. - if _, err := meta.Accessor(liveObj); err != nil { + accessor, err := meta.Accessor(liveObj) + if err != nil { return nil, fmt.Errorf("couldn't get accessor: %v", err) } + missingManagedFields := (len(accessor.GetManagedFields()) == 0) managed, err := internal.DecodeObjectManagedFields(liveObj) if err != nil { @@ -207,6 +213,23 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager } apiVersion := fieldpath.APIVersion(f.groupVersion.String()) + // if managed field is missing, create a single entry for all the fields + if missingManagedFields { + unknownManager, err := internal.BuildManagerIdentifier(&metav1.ManagedFieldsEntry{ + Manager: "before-first-apply", + Operation: metav1.ManagedFieldsOperationUpdate, + APIVersion: f.groupVersion.String(), + }) + if err != nil { + return nil, fmt.Errorf("failed to create manager for existing fields: %v", err) + } + unknownFieldSet, err := liveObjTyped.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create fieldset for existing fields: %v", err) + } + managed.Fields[unknownManager] = fieldpath.NewVersionedSet(unknownFieldSet, apiVersion, false) + f.stripFields(managed.Fields, unknownManager) + } newObjTyped, managedFields, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed.Fields, manager, force) if err != nil { if conflicts, ok := err.(merge.Conflicts); ok { diff --git a/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go b/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go index bb347bee8..9ac1db11c 100644 --- a/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go +++ b/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go @@ -25,6 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -75,6 +76,7 @@ func TestApplyStripsFields(t *testing.T) { f := NewTestFieldManager() obj := &corev1.Pod{} + obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}} newObj, err := f.Apply(obj, []byte(`{ "apiVersion": "apps/v1", @@ -153,6 +155,7 @@ func TestApplyDoesNotStripLabels(t *testing.T) { f := NewTestFieldManager() obj := &corev1.Pod{} + obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}} newObj, err := f.Apply(obj, []byte(`{ "apiVersion": "apps/v1", diff --git a/pkg/endpoints/handlers/patch.go b/pkg/endpoints/handlers/patch.go index 80570f80a..10d5f032d 100644 --- a/pkg/endpoints/handlers/patch.go +++ b/pkg/endpoints/handlers/patch.go @@ -421,7 +421,7 @@ func (p *applyPatcher) applyPatchToCurrentObject(obj runtime.Object) (runtime.Ob func (p *applyPatcher) createNewObject() (runtime.Object, error) { obj, err := p.creater.New(p.kind) if err != nil { - return nil, fmt.Errorf("failed to create new object: %v", obj) + return nil, fmt.Errorf("failed to create new object: %v", err) } return p.applyPatchToCurrentObject(obj) }