From 0652b98e0ffd04d0ebc076fdcde34db198357bd5 Mon Sep 17 00:00:00 2001 From: Paul <135009186+phooijenga@users.noreply.github.com> Date: Sat, 25 May 2024 04:22:48 +0200 Subject: [PATCH] feat: add support for resource-policy: keep (#246) (#582) The annotation `helm.sh/resource-policy: keep` instructs Helm to skip deleting this resource when a Helm operation would result in its deletion. As the resource is not actually deleted, exclude it from the generated diff. --- diff/diff.go | 4 +++- diff/diff_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ manifest/parse.go | 17 ++++++++++------- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/diff/diff.go b/diff/diff.go index b8ebea28..f78697f0 100644 --- a/diff/diff.go +++ b/diff/diff.go @@ -58,7 +58,9 @@ func Manifests(oldIndex, newIndex map[string]*manifest.MappingResult, options *O for _, key := range removed { oldContent := oldIndex[key] - doDiff(&report, key, oldContent, nil, options) + if oldContent.ResourcePolicy != "keep" { + doDiff(&report, key, oldContent, nil, options) + } } for _, key := range added { diff --git a/diff/diff_test.go b/diff/diff_test.go index 28711b74..764dd111 100644 --- a/diff/diff_test.go +++ b/diff/diff_test.go @@ -259,6 +259,22 @@ spec: `, }} + specReleaseKeep := map[string]*manifest.MappingResult{ + "default, nginx, Deployment (apps)": { + + Name: "default, nginx, Deployment (apps)", + Kind: "Deployment", + Content: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx +annotations: + helm.sh/resource-policy: keep +`, + ResourcePolicy: "keep", + }} + t.Run("OnChange", func(t *testing.T) { var buf1 bytes.Buffer diffOptions := Options{"diff", 10, false, true, []string{}, 0.0, []string{}} @@ -438,6 +454,35 @@ spec: require.Equal(t, ``, buf2.String()) }) + t.Run("OnChangeRemoved", func(t *testing.T) { + var buf1 bytes.Buffer + diffOptions := Options{"diff", 10, false, true, []string{}, 0.5, []string{}} + + if changesSeen := Manifests(specRelease, nil, &diffOptions, &buf1); !changesSeen { + t.Error("Unexpected return value from Manifests: Expected the return value to be `true` to indicate that it has seen any change(s), but was `false`") + } + + require.Equal(t, `default, nginx, Deployment (apps) has been removed: + +- apiVersion: apps/v1 +- kind: Deployment +- metadata: +- name: nginx +- `+` +`, buf1.String()) + }) + + t.Run("OnChangeRemovedWithResourcePolicyKeep", func(t *testing.T) { + var buf2 bytes.Buffer + diffOptions := Options{"diff", 10, false, true, []string{}, 0.0, []string{}} + + if changesSeen := Manifests(specReleaseKeep, nil, &diffOptions, &buf2); changesSeen { + t.Error("Unexpected return value from Manifests: Expected the return value to be `false` to indicate that it has NOT seen any change(s), but was `true`") + } + + require.Equal(t, ``, buf2.String()) + }) + t.Run("OnChangeSimple", func(t *testing.T) { var buf1 bytes.Buffer diffOptions := Options{"simple", 10, false, true, []string{}, 0.0, []string{}} diff --git a/manifest/parse.go b/manifest/parse.go index 821a6e1c..1a404998 100644 --- a/manifest/parse.go +++ b/manifest/parse.go @@ -11,16 +11,18 @@ import ( ) const ( - hookAnnotation = "helm.sh/hook" + hookAnnotation = "helm.sh/hook" + resourcePolicyAnnotation = "helm.sh/resource-policy" ) var yamlSeparator = []byte("\n---\n") // MappingResult to store result of diff type MappingResult struct { - Name string - Kind string - Content string + Name string + Kind string + Content string + ResourcePolicy string } type metadata struct { @@ -169,9 +171,10 @@ func parseContent(content string, defaultNamespace string, normalizeManifests bo name := parsedMetadata.String() return []*MappingResult{ { - Name: name, - Kind: parsedMetadata.Kind, - Content: content, + Name: name, + Kind: parsedMetadata.Kind, + Content: content, + ResourcePolicy: parsedMetadata.Metadata.Annotations[resourcePolicyAnnotation], }, }, nil }