diff --git a/cmd/apply.go b/cmd/apply.go index e5cbbca0..f7349f44 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -66,6 +66,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&applyOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) f.BoolVar(&applyOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.StringVar(&applyOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) + f.StringArrayVar(&applyOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringVar(&applyOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background") return cmd diff --git a/cmd/diff.go b/cmd/diff.go index d6efab94..86ec65b2 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -53,6 +53,7 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&diffOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm diff upgrade --install --reuse-values"`) f.BoolVar(&diffOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm diff upgrade --install --reset-values"`) f.StringVar(&diffOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) + f.StringArrayVar(&diffOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) return cmd } diff --git a/cmd/sync.go b/cmd/sync.go index 42d200e8..a0db717e 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -45,6 +45,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&syncOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) f.BoolVar(&syncOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.StringVar(&syncOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) + f.StringArrayVar(&syncOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringVar(&syncOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background") return cmd diff --git a/cmd/template.go b/cmd/template.go index c5a1f64d..52cd5bff 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -45,6 +45,7 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&templateOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`) f.BoolVar(&templateOptions.SkipCleanup, "skip-cleanup", false, "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security") f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) + f.StringArrayVar(&templateOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringVar(&templateOptions.KubeVersion, "kube-version", "", `pass --kube-version to "helm template". Overrides kubeVersion in helmfile.yaml`) return cmd diff --git a/docs/index.md b/docs/index.md index 008ec399..60282155 100644 --- a/docs/index.md +++ b/docs/index.md @@ -211,6 +211,12 @@ helmDefaults: reuseValues: false # propagate `--post-renderer` to helmv3 template and helm install postRenderer: "path/to/postRenderer" + # propagate `--post-renderer-args` to helmv3 template and helm install. This allows using Powershell + # scripts on Windows as a post renderer + postRendererArgs: + - PowerShell + - "-Command" + - "theScript.ps1" # cascade `--cascade` to helmv3 delete, available values: background, foreground, or orphan, default: background cascade: "background" # insecureSkipTLSVerify is true if the TLS verification should be skipped when fetching remote chart @@ -314,6 +320,12 @@ releases: skipDeps: false # propagate `--post-renderer` to helmv3 template and helm install postRenderer: "path/to/postRenderer" + # propagate `--post-renderer-args` to helmv3 template and helm install. This allows using Powershell + # scripts on Windows as a post renderer + postRendererArgs: + - PowerShell + - "-Command" + - "theScript.ps1" # cascade `--cascade` to helmv3 delete, available values: background, foreground, or orphan, default: background cascade: "background" # insecureSkipTLSVerify is true if the TLS verification should be skipped when fetching remote chart diff --git a/pkg/app/app.go b/pkg/app/app.go index 70c397bf..e265826e 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1370,6 +1370,7 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) { ResetValues: c.ResetValues(), DiffArgs: c.DiffArgs(), PostRenderer: c.PostRenderer(), + PostRendererArgs: c.PostRendererArgs(), } infoMsg, releasesToBeUpdated, releasesToBeDeleted, errs := r.diff(false, detailedExitCode, c, diffOpts) @@ -1472,14 +1473,15 @@ Do you really want to apply? subst.Releases = rs syncOpts := &state.SyncOpts{ - Set: c.Set(), - SkipCleanup: c.RetainValuesFiles() || c.SkipCleanup(), - SkipCRDs: c.SkipCRDs(), - Wait: c.Wait(), - WaitForJobs: c.WaitForJobs(), - ReuseValues: c.ReuseValues(), - ResetValues: c.ResetValues(), - PostRenderer: c.PostRenderer(), + Set: c.Set(), + SkipCleanup: c.RetainValuesFiles() || c.SkipCleanup(), + SkipCRDs: c.SkipCRDs(), + Wait: c.Wait(), + WaitForJobs: c.WaitForJobs(), + ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), + PostRenderer: c.PostRenderer(), + PostRendererArgs: c.PostRendererArgs(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) })) @@ -1604,6 +1606,7 @@ func (a *App) diff(r *Run, c DiffConfigProvider) (*string, bool, bool, []error) ReuseValues: c.ReuseValues(), ResetValues: c.ResetValues(), PostRenderer: c.PostRenderer(), + PostRendererArgs: c.PostRendererArgs(), } filtered := &Run{ @@ -1863,13 +1866,14 @@ Do you really want to sync? subst.Releases = rs opts := &state.SyncOpts{ - Set: c.Set(), - SkipCRDs: c.SkipCRDs(), - Wait: c.Wait(), - WaitForJobs: c.WaitForJobs(), - ReuseValues: c.ReuseValues(), - ResetValues: c.ResetValues(), - PostRenderer: c.PostRenderer(), + Set: c.Set(), + SkipCRDs: c.SkipCRDs(), + Wait: c.Wait(), + WaitForJobs: c.WaitForJobs(), + ReuseValues: c.ReuseValues(), + ResetValues: c.ResetValues(), + PostRenderer: c.PostRenderer(), + PostRendererArgs: c.PostRendererArgs(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) })) @@ -1903,6 +1907,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) { SkipCleanup: c.SkipCleanup(), SkipTests: c.SkipTests(), PostRenderer: c.PostRenderer(), + PostRendererArgs: c.PostRendererArgs(), KubeVersion: c.KubeVersion(), } return st.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), c.Validate(), opts) diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 99f200e2..812c7946 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2181,6 +2181,10 @@ func (c configImpl) PostRenderer() string { return "" } +func (c configImpl) PostRendererArgs() []string { + return nil +} + func (c configImpl) KubeVersion() string { return c.kubeVersion } @@ -2222,6 +2226,7 @@ type applyConfig struct { waitForJobs bool reuseValues bool postRenderer string + postRendererArgs []string kubeVersion string // template-only options @@ -2383,6 +2388,10 @@ func (a applyConfig) PostRenderer() string { return a.postRenderer } +func (a applyConfig) PostRendererArgs() []string { + return a.postRendererArgs +} + func (a applyConfig) KubeVersion() string { return a.kubeVersion } diff --git a/pkg/app/config.go b/pkg/app/config.go index 14cd840c..5d3a1764 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -48,6 +48,7 @@ type ReposConfigProvider interface { type ApplyConfigProvider interface { Args() string PostRenderer() string + PostRendererArgs() []string Cascade() string Values() []string @@ -93,6 +94,7 @@ type ApplyConfigProvider interface { type SyncConfigProvider interface { Args() string PostRenderer() string + PostRendererArgs() []string Cascade() string Values() []string @@ -118,6 +120,7 @@ type SyncConfigProvider interface { type DiffConfigProvider interface { Args() string PostRenderer() string + PostRendererArgs() []string Values() []string Set() []string @@ -209,6 +212,7 @@ type FetchConfigProvider interface { type TemplateConfigProvider interface { Args() string PostRenderer() string + PostRendererArgs() []string Values() []string Set() []string diff --git a/pkg/app/diff_test.go b/pkg/app/diff_test.go index 11d7a766..c8ba1270 100644 --- a/pkg/app/diff_test.go +++ b/pkg/app/diff_test.go @@ -164,6 +164,10 @@ func (a diffConfig) PostRenderer() string { return "" } +func (a diffConfig) PostRendererArgs() []string { + return nil +} + func TestDiff(t *testing.T) { type flags struct { skipNeeds bool diff --git a/pkg/config/apply.go b/pkg/config/apply.go index f4dcabf3..568e0893 100644 --- a/pkg/config/apply.go +++ b/pkg/config/apply.go @@ -58,6 +58,8 @@ type ApplyOptions struct { ResetValues bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string // Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background Cascade string } @@ -222,6 +224,11 @@ func (a *ApplyImpl) PostRenderer() string { return a.ApplyOptions.PostRenderer } +// PostRendererArgs returns the PostRendererArgs. +func (a *ApplyImpl) PostRendererArgs() []string { + return a.ApplyOptions.PostRendererArgs +} + // Cascade returns cascade flag func (a *ApplyImpl) Cascade() string { return a.ApplyOptions.Cascade diff --git a/pkg/config/diff.go b/pkg/config/diff.go index 5212c8a9..be1d24cc 100644 --- a/pkg/config/diff.go +++ b/pkg/config/diff.go @@ -42,6 +42,8 @@ type DiffOptions struct { ResetValues bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string // DiffArgs is the list of arguments to pass to helm-diff. DiffArgs string } @@ -185,3 +187,8 @@ func (t *DiffImpl) ResetValues() bool { func (t *DiffImpl) PostRenderer() string { return t.DiffOptions.PostRenderer } + +// PostRendererArgs returns the PostRendererArgs. +func (t *DiffImpl) PostRendererArgs() []string { + return t.DiffOptions.PostRendererArgs +} diff --git a/pkg/config/sync.go b/pkg/config/sync.go index d8858fab..7bb71f59 100644 --- a/pkg/config/sync.go +++ b/pkg/config/sync.go @@ -28,6 +28,8 @@ type SyncOptions struct { ResetValues bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string // Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background Cascade string } @@ -121,6 +123,11 @@ func (t *SyncImpl) PostRenderer() string { return t.SyncOptions.PostRenderer } +// PostRendererArgs returns the PostRendererArgs. +func (t *SyncImpl) PostRendererArgs() []string { + return t.SyncOptions.PostRendererArgs +} + // Cascade returns cascade flag func (t *SyncImpl) Cascade() string { return t.SyncOptions.Cascade diff --git a/pkg/config/template.go b/pkg/config/template.go index 00b6e455..eca71c49 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -34,6 +34,8 @@ type TemplateOptions struct { SkipCleanup bool // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer string + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string // KubeVersion is the kube-version flag KubeVersion string } @@ -126,6 +128,11 @@ func (t *TemplateImpl) PostRenderer() string { return t.TemplateOptions.PostRenderer } +// PostRendererArgs returns the PostRendererArgs. +func (t *TemplateImpl) PostRendererArgs() []string { + return t.TemplateOptions.PostRendererArgs +} + // KubeVersion returns the the KubeVersion. func (t *TemplateImpl) KubeVersion() string { return t.TemplateOptions.KubeVersion diff --git a/pkg/state/helmx.go b/pkg/state/helmx.go index 1f04a88a..86447f7e 100644 --- a/pkg/state/helmx.go +++ b/pkg/state/helmx.go @@ -39,6 +39,31 @@ func (st *HelmState) appendPostRenderFlags(flags []string, release *ReleaseSpec, return flags } +// append post-renderer-args flags to helm flags +func (st *HelmState) appendPostRenderArgsFlags(flags []string, release *ReleaseSpec, postRendererArgs []string) []string { + switch { + case len(release.PostRendererArgs) != 0: + for _, arg := range release.PostRendererArgs { + if arg != "" { + flags = append(flags, "--post-renderer-args", arg) + } + } + case len(postRendererArgs) != 0: + for _, arg := range postRendererArgs { + if arg != "" { + flags = append(flags, "--post-renderer-args", arg) + } + } + case len(st.HelmDefaults.PostRendererArgs) != 0: + for _, arg := range st.HelmDefaults.PostRendererArgs { + if arg != "" { + flags = append(flags, "--post-renderer-args", arg) + } + } + } + return flags +} + func (st *HelmState) appendWaitForJobsFlags(flags []string, release *ReleaseSpec, ops *SyncOpts) []string { switch { case release.WaitForJobs != nil && *release.WaitForJobs: diff --git a/pkg/state/state.go b/pkg/state/state.go index 8c3a196a..870f8848 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -183,6 +183,8 @@ type HelmSpec struct { ReuseValues bool `yaml:"reuseValues"` // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer *string `yaml:"postRenderer,omitempty"` + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string `yaml:"postRendererArgs,omitempty"` // Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background Cascade *string `yaml:"cascade,omitempty"` @@ -357,6 +359,9 @@ type ReleaseSpec struct { // Propagate '--post-renderer' to helmv3 template and helm install PostRenderer *string `yaml:"postRenderer,omitempty"` + // Propagate '--post-renderer-args' to helmv3 template and helm install + PostRendererArgs []string `yaml:"postRendererArgs,omitempty"` + // Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background Cascade *string `yaml:"cascade,omitempty"` @@ -711,14 +716,15 @@ func (st *HelmState) DetectReleasesToBeDeleted(helm helmexec.Interface, releases } type SyncOpts struct { - Set []string - SkipCleanup bool - SkipCRDs bool - Wait bool - WaitForJobs bool - ReuseValues bool - ResetValues bool - PostRenderer string + Set []string + SkipCleanup bool + SkipCRDs bool + Wait bool + WaitForJobs bool + ReuseValues bool + ResetValues bool + PostRenderer string + PostRendererArgs []string } type SyncOpt interface{ Apply(*SyncOpts) } @@ -1393,6 +1399,7 @@ type TemplateOpts struct { IncludeCRDs bool SkipTests bool PostRenderer string + PostRendererArgs []string KubeVersion string } @@ -1914,6 +1921,7 @@ type DiffOpts struct { ReuseValues bool ResetValues bool PostRenderer string + PostRendererArgs []string } func (o *DiffOpts) Apply(opts *DiffOpts) { @@ -2567,6 +2575,12 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp } flags = st.appendPostRenderFlags(flags, release, postRenderer) + var postRendererArgs []string + if opt != nil { + postRendererArgs = opt.PostRendererArgs + } + flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) + common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex) if err != nil { return nil, clean, err @@ -2582,12 +2596,15 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS flags = st.appendHelmXFlags(flags, release) postRenderer := "" + var postRendererArgs []string kubeVersion := "" if opt != nil { postRenderer = opt.PostRenderer + postRendererArgs = opt.PostRendererArgs kubeVersion = opt.KubeVersion } flags = st.appendPostRenderFlags(flags, release, postRenderer) + flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) flags = st.appendApiVersionsFlags(flags, release, kubeVersion) flags = st.appendChartDownloadTLSFlags(flags, release) @@ -2653,6 +2670,12 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec, } flags = st.appendPostRenderFlags(flags, release, postRenderer) + var postRendererArgs []string + if opt != nil { + postRendererArgs = opt.PostRendererArgs + } + flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) + common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex) if err != nil { return nil, files, err diff --git a/pkg/state/temp_test.go b/pkg/state/temp_test.go index 654c00bd..427955f5 100644 --- a/pkg/state/temp_test.go +++ b/pkg/state/temp_test.go @@ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) { run(testcase{ subject: "baseline", release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, - want: "foo-values-6749dfb776", + want: "foo-values-c7464bdc5", }) run(testcase{ subject: "different bytes content", release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, data: []byte(`{"k":"v"}`), - want: "foo-values-84f9645959", + want: "foo-values-79f8658596", }) run(testcase{ subject: "different map content", release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, data: map[string]any{"k": "v"}, - want: "foo-values-7774fccb4f", + want: "foo-values-7996cc88d6", }) run(testcase{ subject: "different chart", release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"}, - want: "foo-values-5cdf68c495", + want: "foo-values-7cdb6bd8b6", }) run(testcase{ subject: "different name", release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"}, - want: "bar-values-758d78db87", + want: "bar-values-59cd6576c4", }) run(testcase{ subject: "specific ns", release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"}, - want: "myns-foo-values-6888c4f5bf", + want: "myns-foo-values-5d5d46c98d", }) for id, n := range ids { diff --git a/test/integration/test-cases/postrender.sh b/test/integration/test-cases/postrender.sh index d34d0867..5a1a2aee 100644 --- a/test/integration/test-cases/postrender.sh +++ b/test/integration/test-cases/postrender.sh @@ -27,7 +27,7 @@ test_start "postrender diff" info "Comparing postrender diff output ${postrender_diff_reverse} with ${postrender_case_output_dir}/result.yaml" for i in $(seq 10); do info "Comparing build/postrender-diff #$i" - ${helmfile} -f ${postrender_case_input_dir}/${config_file} diff --concurrency 1 --post-renderer ./add-cm1.bash &> ${postrender_diff_reverse} || fail "\"helmfile diff\" shouldn't fail" + ${helmfile} -f ${postrender_case_input_dir}/${config_file} diff --concurrency 1 --post-renderer ./add-cm.bash --post-renderer-args cm1 &> ${postrender_diff_reverse} || fail "\"helmfile diff\" shouldn't fail" diff -u ${postrender_diff_out_file} ${postrender_diff_reverse} || fail "\"helmfile diff\" should be consistent" echo code=$? done @@ -37,7 +37,7 @@ test_start "postrender template" info "Comparing postrender template output ${postrender_template_reverse} with ${postrender_case_output_dir}/result.yaml" for i in $(seq 10); do info "Comparing build/postrender-diff #$i" - ${helmfile} -f ${postrender_case_input_dir}/${config_file} template --concurrency 1 --post-renderer ./add-cm1.bash &> ${postrender_template_reverse} || fail "\"helmfile template\" shouldn't fail" + ${helmfile} -f ${postrender_case_input_dir}/${config_file} template --concurrency 1 --post-renderer ./add-cm.bash --post-renderer-args cm1 &> ${postrender_template_reverse} || fail "\"helmfile template\" shouldn't fail" diff -u ${postrender_template_out_file} ${postrender_template_reverse} || fail "\"helmfile template\" should be consistent" echo code=$? done diff --git a/test/integration/test-cases/postrender/input/add-cm1.bash b/test/integration/test-cases/postrender/input/add-cm.bash similarity index 55% rename from test/integration/test-cases/postrender/input/add-cm1.bash rename to test/integration/test-cases/postrender/input/add-cm.bash index 0304b012..3ea642e4 100755 --- a/test/integration/test-cases/postrender/input/add-cm1.bash +++ b/test/integration/test-cases/postrender/input/add-cm.bash @@ -1,13 +1,13 @@ #!/usr/bin/env bash - -cat $1 +configmap_name=$1 +cat echo "---" cat <