From 3fcf57c9aa46dfd9742b8930bcf1736524ea9f2a Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Thu, 26 Jan 2023 16:39:51 +0200 Subject: [PATCH] ssa: Ignore objects even if they exist in cluster If an object was created but then marked as ignored in source, we should skip applying it even if the in-cluster object has no ignore annotation. Signed-off-by: Stefan Prodan --- ssa/manager_apply.go | 14 ++++++++------ ssa/manager_apply_test.go | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ssa/manager_apply.go b/ssa/manager_apply.go index 33925e88..2f7c19bc 100644 --- a/ssa/manager_apply.go +++ b/ssa/manager_apply.go @@ -82,7 +82,7 @@ func (m *ResourceManager) Apply(ctx context.Context, object *unstructured.Unstru existingObject := object.DeepCopy() _ = m.client.Get(ctx, client.ObjectKeyFromObject(object), existingObject) - if m.shouldSkipApply(existingObject, opts) { + if m.shouldSkipApply(object, existingObject, opts) { return m.changeSetEntry(object, UnchangedAction), nil } @@ -132,7 +132,7 @@ func (m *ResourceManager) ApplyAll(ctx context.Context, objects []*unstructured. existingObject := object.DeepCopy() _ = m.client.Get(ctx, client.ObjectKeyFromObject(object), existingObject) - if m.shouldSkipApply(existingObject, opts) { + if m.shouldSkipApply(object, existingObject, opts) { changeSet.Add(*m.changeSetEntry(existingObject, UnchangedAction)) continue } @@ -286,11 +286,11 @@ func (m *ResourceManager) cleanupMetadata(ctx context.Context, // An object is recreated if the apply error was due to immutable field changes and if the object // contains a label or annotation which matches the ApplyOptions.ForceSelector. func (m *ResourceManager) shouldForceApply(desiredObject *unstructured.Unstructured, - object *unstructured.Unstructured, opts ApplyOptions, err error) bool { + existingObject *unstructured.Unstructured, opts ApplyOptions, err error) bool { if IsImmutableError(err) { if opts.Force || AnyInMetadata(desiredObject, opts.ForceSelector) || - (object != nil && AnyInMetadata(object, opts.ForceSelector)) { + (existingObject != nil && AnyInMetadata(existingObject, opts.ForceSelector)) { return true } } @@ -300,6 +300,8 @@ func (m *ResourceManager) shouldForceApply(desiredObject *unstructured.Unstructu // shouldSkipApply determines based on the object metadata and ApplyOptions if the object should be skipped. // An object is not applied if it contains a label or annotation which matches the ApplyOptions.ExclusionSelector. -func (m *ResourceManager) shouldSkipApply(object *unstructured.Unstructured, opts ApplyOptions) bool { - return object != nil && AnyInMetadata(object, opts.ExclusionSelector) +func (m *ResourceManager) shouldSkipApply(desiredObject *unstructured.Unstructured, + existingObject *unstructured.Unstructured, opts ApplyOptions) bool { + return AnyInMetadata(desiredObject, opts.ExclusionSelector) || + (existingObject != nil && AnyInMetadata(existingObject, opts.ExclusionSelector)) } diff --git a/ssa/manager_apply_test.go b/ssa/manager_apply_test.go index 7313b65f..a1282cd3 100644 --- a/ssa/manager_apply_test.go +++ b/ssa/manager_apply_test.go @@ -416,6 +416,24 @@ func TestApply_Exclusions(t *testing.T) { } } }) + + t.Run("skips apply when desired state is annotated", func(t *testing.T) { + configMapClone := configMap.DeepCopy() + meta := map[string]string{ + "fluxcd.io/ignore": "true", + } + configMapClone.SetAnnotations(meta) + + // apply changes without exclusions + changeSet, err := manager.Apply(ctx, configMapClone, DefaultApplyOptions()) + if err != nil { + t.Fatal(err) + } + + if changeSet.Action != string(UnchangedAction) { + t.Errorf("Diff found for %s", changeSet.String()) + } + }) } func TestApply_Cleanup(t *testing.T) {