From d5ab2c568ca17d1d5615b7fdc01aa91b2ac99b18 Mon Sep 17 00:00:00 2001 From: Somtochi Onyekwere Date: Wed, 19 Jan 2022 11:08:22 +0100 Subject: [PATCH] replace manager in ssa apply Signed-off-by: Somtochi Onyekwere --- ssa/manager_apply.go | 2 +- ssa/manager_apply_test.go | 2 +- ssa/patch.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ssa/manager_apply.go b/ssa/manager_apply.go index 830be5ea..9095a63e 100644 --- a/ssa/manager_apply.go +++ b/ssa/manager_apply.go @@ -248,7 +248,7 @@ func (m *ResourceManager) cleanupMetadata(ctx context.Context, object *unstructu } if len(opts.FieldManagers) > 0 { - patches = append(patches, patchRemoveFieldsManagers(existingObject, opts.FieldManagers)...) + patches = append(patches, patchReplaceFieldsManagers(existingObject, opts.FieldManagers, m.owner.Field)...) } // no patching is needed exit early diff --git a/ssa/manager_apply_test.go b/ssa/manager_apply_test.go index 0df8e169..ae3803be 100644 --- a/ssa/manager_apply_test.go +++ b/ssa/manager_apply_test.go @@ -499,7 +499,7 @@ func TestApply_Cleanup(t *testing.T) { } }) - t.Run("removes kubectl server-side-apply manager", func(t *testing.T) { + t.Run("replaces kubectl server-side-apply manager", func(t *testing.T) { for _, object := range objects { obj := object.DeepCopy() if err := manager.client.Patch(ctx, obj, client.Apply, client.FieldOwner("kubectl")); err != nil { diff --git a/ssa/patch.go b/ssa/patch.go index 42c083c6..0c67dd4d 100644 --- a/ssa/patch.go +++ b/ssa/patch.go @@ -91,6 +91,34 @@ func patchRemoveFieldsManagers(object *unstructured.Unstructured, managers []Fil return append(patches, newPatchReplace("/metadata/managedFields", entries)) } +// patchReplaceFieldsManagers returns a jsonPatch array for replacing the managers with matching prefix and operation type +// with the specified manager name and an apply operation. +func patchReplaceFieldsManagers(object *unstructured.Unstructured, managers []FiledManager, name string) []jsonPatch { + objEntries := object.GetManagedFields() + + var patches []jsonPatch + entries := make([]metav1.ManagedFieldsEntry, 0, len(objEntries)) + renamed := false + for _, entry := range objEntries { + for _, manager := range managers { + if strings.HasPrefix(entry.Manager, manager.Name) && + entry.Operation == manager.OperationType && + entry.Subresource == "" { + entry.Manager = name + entry.Operation = metav1.ManagedFieldsOperationApply + renamed = true + } + } + entries = append(entries, entry) + } + + if !renamed { + return nil + } + + return append(patches, newPatchReplace("/metadata/managedFields", entries)) +} + // patchRemoveAnnotations returns a jsonPatch array for removing annotations with matching keys. func patchRemoveAnnotations(object *unstructured.Unstructured, keys []string) []jsonPatch { var patches []jsonPatch