Repository: roboll/helmfile
Pull request #2077 (2022-02-02 18:44:20)

feat: Add --suppress option for diff and apply commands
We need to suppress the output of certain Kubernetes API objects in the diff/apply output.

As the helm-diff plugin supports `--suppress` to allow suppression of the values (kubernetes objects) listed in the diff output, with this MR, helmfile also supports using this flag now.


Patch:
diff --git a/main.go b/main.go
index 09aacdf..1084e4f 100644
--- a/main.go
+++ b/main.go
@@ -211,6 +211,10 @@ func main() {
 					Name:  "skip-diff-on-install",
 					Usage: "Skips running helm-diff on releases being newly installed on this apply. Useful when the release manifests are too huge to be reviewed, or it's too time-consuming to diff at all",
 				},
+				cli.StringSliceFlag{
+					Name:  "suppress",
+					Usage: "suppress specified Kubernetes objects in the output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret",
+				},
 				cli.BoolFlag{
 					Name:  "suppress-secrets",
 					Usage: "suppress secrets in the output. highly recommended to specify on CI/CD use-cases",
@@ -517,6 +521,10 @@ func main() {
 					Name:  "include-tests",
 					Usage: "enable the diffing of the helm test hooks",
 				},
+				cli.StringSliceFlag{
+					Name:  "suppress",
+					Usage: "suppress specified Kubernetes objects in the diff output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret",
+				},
 				cli.BoolFlag{
 					Name:  "suppress-secrets",
 					Usage: "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases",
@@ -823,6 +831,10 @@ func (c configImpl) IncludeTests() bool {
 	return c.c.Bool("include-tests")
 }
 
+func (c configImpl) Suppress() []string {
+	return c.c.StringSlice("suppress")
+}
+
 func (c configImpl) SuppressSecrets() bool {
 	return c.c.Bool("suppress-secrets")
 }
diff --git a/pkg/app/config.go b/pkg/app/config.go
index c37f2c8..e39281f 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -49,6 +49,7 @@ type ApplyConfigProvider interface {
 
 	IncludeTests() bool
 
+	Suppress() []string
 	SuppressSecrets() bool
 	ShowSecrets() bool
 	SuppressDiff() bool
@@ -102,6 +103,7 @@ type DiffConfigProvider interface {
 
 	IncludeTests() bool
 
+	Suppress() []string
 	SuppressSecrets() bool
 	ShowSecrets() bool
 	SuppressDiff() bool
diff --git a/pkg/app/run.go b/pkg/app/run.go
index 02ba342..e412e86 100644
--- a/pkg/app/run.go
+++ b/pkg/app/run.go
@@ -127,7 +127,7 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig
 
 	// TODO Better way to detect diff on only filtered releases
 	{
-		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.IncludeTests(), c.SuppressSecrets(), c.ShowSecrets(), c.SuppressDiff(), triggerCleanupEvent, diffOpts)
+		changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.IncludeTests(), c.Suppress(), c.SuppressSecrets(), c.ShowSecrets(), c.SuppressDiff(), triggerCleanupEvent, diffOpts)
 
 		var err error
 		deletingReleases, err = st.DetectReleasesToBeDeletedForSync(helm, st.Releases)
diff --git a/pkg/state/state.go b/pkg/state/state.go
index d54df95..85f8501 100644
--- a/pkg/state/state.go
+++ b/pkg/state/state.go
@@ -1598,7 +1598,7 @@ type diffPrepareResult struct {
 	upgradeDueToSkippedDiff bool
 }
 
-func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode, includeTests, suppressSecrets bool, showSecrets bool, opt ...DiffOpt) ([]diffPrepareResult, []error) {
+func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValues []string, concurrency int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets bool, showSecrets bool, opt ...DiffOpt) ([]diffPrepareResult, []error) {
 	opts := &DiffOpts{}
 	for _, o := range opt {
 		o.Apply(opts)
@@ -1699,6 +1699,12 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu
 					flags = append(flags, "--include-tests")
 				}
 
+				if suppress != nil {
+					for _, s := range suppress {
+						flags = append(flags, "--suppress", s)
+					}
+				}
+
 				if suppressSecrets {
 					flags = append(flags, "--suppress-secrets")
 				}
@@ -1815,13 +1821,13 @@ type DiffOpt interface{ Apply(*DiffOpts) }
 // For example, terraform-provider-helmfile runs a helmfile-diff on `terraform plan` and another on `terraform apply`.
 // `terraform`, by design, fails when helmfile-diff outputs were not equivalent.
 // Stabilized helmfile-diff output rescues that.
-func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode, includeTests, suppressSecrets, showSecrets, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
+func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets, showSecrets, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
 	opts := &DiffOpts{}
 	for _, o := range opt {
 		o.Apply(opts)
 	}
 
-	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppressSecrets, showSecrets, opts)
+	preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppress, suppressSecrets, showSecrets, opts)
 
 	if !opts.SkipCleanup {
 		defer func() {


Test patch:
diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go
index 4ba6059..3f3e268 100644
--- a/pkg/app/app_test.go
+++ b/pkg/app/app_test.go
@@ -2360,6 +2360,7 @@ type applyConfig struct {
 	includeNeeds           bool
 	includeTransitiveNeeds bool
 	includeTests           bool
+	suppress               []string
 	suppressSecrets        bool
 	showSecrets            bool
 	suppressDiff           bool
@@ -2427,6 +2428,10 @@ func (a applyConfig) IncludeTests() bool {
 	return a.includeTests
 }
 
+func (a applyConfig) Suppress() []string {
+	return a.suppress
+}
+
 func (a applyConfig) SuppressSecrets() bool {
 	return a.suppressSecrets
 }
diff --git a/pkg/app/diff_test.go b/pkg/app/diff_test.go
index 2ceedc9..af801a9 100644
--- a/pkg/app/diff_test.go
+++ b/pkg/app/diff_test.go
@@ -27,6 +27,7 @@ type diffConfig struct {
 	includeTests      bool
 	includeNeeds      bool
 	skipNeeds         bool
+	suppress          []string
 	suppressSecrets   bool
 	showSecrets       bool
 	suppressDiff      bool
@@ -76,6 +77,10 @@ func (a diffConfig) SkipNeeds() bool {
 	return a.skipNeeds
 }
 
+func (a diffConfig) Suppress() []string {
+	return a.suppress
+}
+
 func (a diffConfig) SuppressSecrets() bool {
 	return a.suppressSecrets
 }
diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go
index 5e8b7c1..698890f 100644
--- a/pkg/state/state_test.go
+++ b/pkg/state/state_test.go
@@ -1612,7 +1612,7 @@ func TestHelmState_DiffReleases(t *testing.T) {
 				valsRuntime:    valsRuntime,
 				RenderedValues: map[string]interface{}{},
 			}
-			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false, false, false)
+			_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false)
 			if errs != nil && len(errs) > 0 {
 				t.Errorf("unexpected error: %v", errs)
 			}
@@ -1783,7 +1783,7 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) {
 `,
 			})
 			state = injectFs(state, testfs)
-			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false, false, false); errs != nil && len(errs) > 0 {
+			if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false); errs != nil && len(errs) > 0 {
 				t.Errorf("unexpected errors: %v", errs)
 			}