From 0a953731b0f4879eb53c9281155d58f55abb8f03 Mon Sep 17 00:00:00 2001 From: guofutan Date: Mon, 12 Dec 2022 17:44:18 +0800 Subject: [PATCH] fix(#507): support assign --post-renderer within helmfile flags and helmdefault or release config 1. only implement post-renderer flags this patch 2. As mumoshu advise, add helmfile flags `--post-render` and add the postRenderer config in helmDefaults and release. the priority is helmfile flags > release > helmDefaults. 3. fix the test case in state_test.go and some other tests. Signed-off-by: guofutan Signed-off-by: yxxhero --- cmd/apply.go | 1 + cmd/sync.go | 1 + cmd/template.go | 1 + pkg/app/app.go | 2 + pkg/app/app_test.go | 14 +++ pkg/app/config.go | 3 + pkg/app/mocks_test.go | 6 ++ pkg/argparser/args.go | 7 -- pkg/argparser/args_test.go | 40 -------- pkg/config/apply.go | 7 ++ pkg/config/sync.go | 7 ++ pkg/config/template.go | 7 ++ pkg/exectest/helm.go | 10 +- pkg/helmexec/exec.go | 37 +++---- pkg/helmexec/exec_test.go | 47 ++++----- pkg/helmexec/helmexec.go | 2 + pkg/state/state.go | 33 +++++-- pkg/state/state_test.go | 197 ++++++++++++++++++++++++++++++++++++- 18 files changed, 320 insertions(+), 102 deletions(-) diff --git a/cmd/apply.go b/cmd/apply.go index 4d45bf63..617cb439 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -60,6 +60,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&applyOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&applyOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) f.BoolVar(&applyOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) + f.StringVar(&applyOptions.PostRenderer, "post-renderer", "", `pass post-renderer to "helm template" or "helm upgrade --install"`) return cmd } diff --git a/cmd/sync.go b/cmd/sync.go index 33ab4cff..10a912b1 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -44,6 +44,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&syncOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&syncOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) f.BoolVar(&syncOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) + f.StringVar(&syncOptions.PostRenderer, "post-renderer", "", `pass post-renderer to "helm template" or "helm upgrade --install"`) return cmd } diff --git a/cmd/template.go b/cmd/template.go index 35193f94..8766c79b 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.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) 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"`) return cmd } diff --git a/pkg/app/app.go b/pkg/app/app.go index de06601c..82ce75de 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1392,6 +1392,7 @@ Do you really want to apply? } r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...) + r.helm.SetPostRenderer(c.PostRenderer()) // We deleted releases by traversing the DAG in reverse order if len(releasesToBeDeleted) > 0 { @@ -1774,6 +1775,7 @@ Do you really want to sync? var errs []error r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...) + r.helm.SetPostRenderer(c.PostRenderer()) // Traverse DAG of all the releases so that we don't suffer from false-positive missing dependencies st.Releases = selectedAndNeededReleases diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index f561ad15..76d4c441 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2304,6 +2304,10 @@ func (c configImpl) SkipCharts() bool { return c.skipCharts } +func (c configImpl) PostRenderer() string { + return "" +} + type applyConfig struct { args string values []string @@ -2334,6 +2338,7 @@ type applyConfig struct { wait bool waitForJobs bool reuseValues bool + postRenderer string // template-only options includeCRDs, skipTests bool @@ -2473,6 +2478,10 @@ func (a applyConfig) ReuseValues() bool { return a.reuseValues } +func (a applyConfig) PostRenderer() string { + return a.postRenderer +} + type depsConfig struct { skipRepos bool includeTransitiveNeeds bool @@ -2555,6 +2564,11 @@ func (helm *mockHelmExec) SetHelmBinary(bin string) { } func (helm *mockHelmExec) SetEnableLiveOutput(enableLiveOutput bool) { } +func (helm *mockHelmExec) SetPostRenderer(postRenderer string) { +} +func (helm *mockHelmExec) GetPostRenderer() string { + return "" +} func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.repos = append(helm.repos, mockRepo{Name: name}) return nil diff --git a/pkg/app/config.go b/pkg/app/config.go index 2690a372..4bf17d72 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -42,6 +42,7 @@ type ReposConfigProvider interface { type ApplyConfigProvider interface { Args() string + PostRenderer() string Values() []string Set() []string @@ -80,6 +81,7 @@ type ApplyConfigProvider interface { type SyncConfigProvider interface { Args() string + PostRenderer() string Values() []string Set() []string @@ -186,6 +188,7 @@ type FetchConfigProvider interface { type TemplateConfigProvider interface { Args() string + PostRenderer() string Values() []string Set() []string diff --git a/pkg/app/mocks_test.go b/pkg/app/mocks_test.go index a6c28a57..b24e686a 100644 --- a/pkg/app/mocks_test.go +++ b/pkg/app/mocks_test.go @@ -53,6 +53,12 @@ func (helm *noCallHelmExec) SetHelmBinary(bin string) { func (helm *noCallHelmExec) SetEnableLiveOutput(enableLiveOutput bool) { helm.doPanic() } +func (helm *noCallHelmExec) SetPostRenderer(postRenderer string) { +} +func (helm *noCallHelmExec) GetPostRenderer() string { + return "" +} + func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.doPanic() return nil diff --git a/pkg/argparser/args.go b/pkg/argparser/args.go index 1b3fc8ef..f2fc36e6 100644 --- a/pkg/argparser/args.go +++ b/pkg/argparser/args.go @@ -112,13 +112,6 @@ func GetArgs(args string, state *state.HelmState) []string { } } - if len(state.HelmDefaults.PostRenderer) > 0 { - argArr = append(argArr, fmt.Sprintf("--post-renderer=\"%s\"", state.HelmDefaults.PostRenderer)) - } - for _, arg := range state.HelmDefaults.PostRendererArgs { - argArr = append(argArr, fmt.Sprintf("--post-renderer-args=\"%s\"", arg)) - } - state.HelmDefaults.Args = argArr return state.HelmDefaults.Args diff --git a/pkg/argparser/args_test.go b/pkg/argparser/args_test.go index 01e1987e..ed7b7482 100644 --- a/pkg/argparser/args_test.go +++ b/pkg/argparser/args_test.go @@ -35,14 +35,6 @@ func TestGetArgs(t *testing.T) { defaultArgs: []string{"--recreate-pods", "--force"}, expected: "--timeout=3600 --set app1.bootstrap=true --set app2.bootstrap=false,app3.bootstrap=true --tiller-namespace ns --recreate-pods --force", }, - { - args: "--post-renderer=aaa --post-renderer-args=bbb", - expected: "--post-renderer=aaa --post-renderer-args=bbb", - }, - { - args: "--post-renderer aaa --post-renderer-args bbb", - expected: "--post-renderer aaa --post-renderer-args bbb", - }, } for _, test := range tests { Helmdefaults := state.HelmSpec{KubeContext: "test", TillerNamespace: "test-namespace", Args: test.defaultArgs} @@ -57,38 +49,6 @@ func TestGetArgs(t *testing.T) { } } -func TestGetArgs_PostRenderer(t *testing.T) { - tests := []struct { - postRenderer string - PostRendererArgs []string - expected string - }{ - { - postRenderer: "sed", - PostRendererArgs: []string{"-i", "s/aaa/bb/g"}, - expected: "--post-renderer=\"sed\" --post-renderer-args=\"-i\" --post-renderer-args=\"s/aaa/bb/g\"", - }, - - { - postRenderer: "sed", - PostRendererArgs: []string{"-i", "s/aa a/b b/g"}, - expected: "--post-renderer=\"sed\" --post-renderer-args=\"-i\" --post-renderer-args=\"s/aa a/b b/g\"", - }, - } - - for _, test := range tests { - Helmdefaults := state.HelmSpec{KubeContext: "test", TillerNamespace: "test-namespace", PostRenderer: test.postRenderer, PostRendererArgs: test.PostRendererArgs} - testState := &state.HelmState{ - ReleaseSetSpec: state.ReleaseSetSpec{ - HelmDefaults: Helmdefaults, - }, - } - receivedArgs := GetArgs("", testState) - - require.Equalf(t, test.expected, strings.Join(receivedArgs, " "), "expected args %s, received args %s", test.expected, strings.Join(receivedArgs, " ")) - } -} - // TestIsNewFlag tests the isNewFlag function func TestIsNewFlag(t *testing.T) { tests := []struct { diff --git a/pkg/config/apply.go b/pkg/config/apply.go index c3e0559f..393d4ad5 100644 --- a/pkg/config/apply.go +++ b/pkg/config/apply.go @@ -50,6 +50,8 @@ type ApplyOptions struct { WaitForJobs bool // ReuseValues is true if the helm command should reuse the values ReuseValues bool + // Propagate '--postRenderer' to helmv3 template and helm install + PostRenderer string } // NewApply creates a new Apply @@ -193,3 +195,8 @@ func (a *ApplyImpl) WaitForJobs() bool { func (a *ApplyImpl) ReuseValues() bool { return a.ApplyOptions.ReuseValues } + +// PostRenderer returns the PostRenderer. +func (a *ApplyImpl) PostRenderer() string { + return a.ApplyOptions.PostRenderer +} diff --git a/pkg/config/sync.go b/pkg/config/sync.go index 14a3f4f9..9073376c 100644 --- a/pkg/config/sync.go +++ b/pkg/config/sync.go @@ -26,6 +26,8 @@ type SyncOptions struct { WaitForJobs bool // ReuseValues is true if the helm command should reuse the values ReuseValues bool + // Propagate '--postRenderer' to helmv3 template and helm install + PostRenderer string } // NewSyncOptions creates a new Apply @@ -110,3 +112,8 @@ func (t *SyncImpl) WaitForJobs() bool { func (t *SyncImpl) ReuseValues() bool { return t.SyncOptions.ReuseValues } + +// PostRenderer returns the PostRenderer. +func (t *SyncImpl) PostRenderer() string { + return t.SyncOptions.PostRenderer +} diff --git a/pkg/config/template.go b/pkg/config/template.go index 1e61cdef..541034d2 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -34,6 +34,8 @@ type TemplateOptions struct { SkipDeps bool // SkipCleanup is the skip cleanup flag SkipCleanup bool + // Propagate '--postRenderer' to helmv3 template and helm install + PostRenderer string } // NewTemplateOptions creates a new Apply @@ -123,3 +125,8 @@ func (t *TemplateImpl) Validate() bool { func (t *TemplateImpl) Values() []string { return t.TemplateOptions.Values } + +// PostRenderer returns the PostRenderer. +func (t *TemplateImpl) PostRenderer() string { + return t.TemplateOptions.PostRenderer +} diff --git a/pkg/exectest/helm.go b/pkg/exectest/helm.go index 31741c12..8c71133e 100644 --- a/pkg/exectest/helm.go +++ b/pkg/exectest/helm.go @@ -92,6 +92,11 @@ func (helm *Helm) SetHelmBinary(bin string) { } func (helm *Helm) SetEnableLiveOutput(enableLiveOutput bool) { } +func (helm *Helm) SetPostRenderer(postRenderer string) { +} +func (helm *Helm) GetPostRenderer() string { + return "" +} func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials, skipTLSVerify} return nil @@ -200,7 +205,10 @@ func (helm *Helm) ChartExport(chart string, path string, flags ...string) error return nil } func (helm *Helm) IsHelm3() bool { - return helm.Helm3 + if helm.Version == nil { + return helm.Helm3 + } + return helm.Version.Major() == 3 } func (helm *Helm) GetVersion() helmexec.Version { diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 88feb15e..a35071fe 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -36,7 +36,7 @@ type execer struct { logger *zap.SugaredLogger kubeContext string extra []string - postRenderers []string + postRenderer string decryptedSecretMutex sync.Mutex decryptedSecrets map[string]*decryptedSecret writeTempFile func([]byte) (string, error) @@ -132,23 +132,7 @@ func New(helmBinary string, enableLiveOutput bool, logger *zap.SugaredLogger, ku } func (helm *execer) SetExtraArgs(args ...string) { - var extraArgs []string - var renderArgs []string - // reset the postRenderers and filter --post-renderer=xx or --post-renderer xxx from args and put into helm.postRenderers - for i := 0; i < len(args); i++ { - if strings.HasPrefix(args[i], "--post-renderer=") || strings.HasPrefix(args[i], "--post-renderer-args=") { - renderArgs = append(renderArgs, args[i]) - } else if (args[i] == "--post-renderer" || args[i] == "--post-renderer-args") && i < len(args)-1 { - renderArgs = append(renderArgs, args[i]) - renderArgs = append(renderArgs, args[i+1]) - i++ - } else { - extraArgs = append(extraArgs, args[i]) - } - } - - helm.extra = extraArgs - helm.postRenderers = renderArgs + helm.extra = args } func (helm *execer) SetHelmBinary(bin string) { @@ -159,6 +143,14 @@ func (helm *execer) SetEnableLiveOutput(enableLiveOutput bool) { helm.enableLiveOutput = enableLiveOutput } +func (helm *execer) SetPostRenderer(postRenderer string) { + helm.postRenderer = postRenderer +} + +func (helm *execer) GetPostRenderer() string { + return helm.postRenderer +} + func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { var args []string var out []byte @@ -268,8 +260,8 @@ func (helm *execer) SyncRelease(context HelmContext, name, chart string, flags . env["HELM_TILLER_HISTORY_MAX"] = strconv.Itoa(context.HistoryMax) } - if helm.IsHelm3() { - flags = append(flags, helm.postRenderers...) + if helm.IsHelm3() && helm.postRenderer != "" { + flags = append(flags, "--post-renderer", helm.postRenderer) } out, err := helm.exec(append(append(preArgs, "upgrade", "--install", name, chart), flags...), env, nil) @@ -411,10 +403,9 @@ func (helm *execer) TemplateRelease(name string, chart string, flags ...string) args = []string{"template", chart, "--name", name} } - if helm.IsHelm3() { - flags = append(flags, helm.postRenderers...) + if helm.IsHelm3() && helm.postRenderer != "" { + flags = append(flags, "--post-renderer", helm.postRenderer) } - out, err := helm.exec(append(args, flags...), map[string]string{}, nil) var outputToFile bool diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 27a765dd..d53182ab 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -69,29 +69,6 @@ func Test_SetExtraArgs(t *testing.T) { if !reflect.DeepEqual(helm.extra, []string{"alpha", "beta"}) { t.Error("helmexec.SetExtraArgs() - two extra arguments missing (overwriting the previous value)") } - - helm.SetExtraArgs("--post-renderer=aaa") - fmt.Println(helm.postRenderers) - if !reflect.DeepEqual(helm.postRenderers, []string{"--post-renderer=aaa"}) { - t.Error("helmexec.SetExtraArgs() - post-renderer assign arguments missing ") - } - - helm.SetExtraArgs("--post-renderer", "aaa") - fmt.Println(helm.postRenderers) - if !reflect.DeepEqual(helm.postRenderers, []string{"--post-renderer", "aaa"}) { - t.Error("helmexec.SetExtraArgs() - post-renderer blank arguments missing ") - } - - helm.SetExtraArgs("--post-renderer-args=bbb") - fmt.Println(helm.postRenderers) - if !reflect.DeepEqual(helm.postRenderers, []string{"--post-renderer-args=bbb"}) { - t.Error("helmexec.SetExtraArgs() - post-renderer-args assign arguments missing") - } - - helm.SetExtraArgs("--post-renderer", "aaa", "--post-renderer-args=bbb") - if !reflect.DeepEqual(helm.postRenderers, []string{"--post-renderer", "aaa", "--post-renderer-args=bbb"}) { - t.Error("helmexec.SetExtraArgs() - post-renderer arguments not be set correct") - } } func Test_SetHelmBinary(t *testing.T) { @@ -116,6 +93,30 @@ func Test_SetEnableLiveOutput(t *testing.T) { } } +func Test_SetPostRenderer(t *testing.T) { + helm := MockExecer(NewLogger(os.Stdout, "info"), "dev") + if helm.enableLiveOutput { + t.Error("helmexec.enableLiveOutput should not be enabled by default") + } + postRendererFoo := "/bin/rewrite-repo.sh" + helm.SetPostRenderer(postRendererFoo) + if helm.postRenderer != postRendererFoo { + t.Errorf("helmexec.SetPostRenderer() - actual = %s expect = %s", helm.postRenderer, postRendererFoo) + } +} + +func Test_GetPostRenderer(t *testing.T) { + helm := MockExecer(NewLogger(os.Stdout, "info"), "dev") + if helm.enableLiveOutput { + t.Error("helmexec.enableLiveOutput should not be enabled by default") + } + postRendererFoo := "/bin/rewrite-repo.sh" + helm.SetPostRenderer(postRendererFoo) + if helm.GetPostRenderer() != postRendererFoo { + t.Errorf("helmexec.GetPostRenderer() - actual = %s expect = %s", helm.GetPostRenderer(), postRendererFoo) + } +} + func Test_AddRepo_Helm_3_3_2(t *testing.T) { var buffer bytes.Buffer logger := NewLogger(&buffer, "debug") diff --git a/pkg/helmexec/helmexec.go b/pkg/helmexec/helmexec.go index 462adf29..45f95cdd 100644 --- a/pkg/helmexec/helmexec.go +++ b/pkg/helmexec/helmexec.go @@ -14,6 +14,8 @@ type Interface interface { SetExtraArgs(args ...string) SetHelmBinary(bin string) SetEnableLiveOutput(enableLiveOutput bool) + SetPostRenderer(postRenderer string) + GetPostRenderer() string AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error UpdateRepo() error diff --git a/pkg/state/state.go b/pkg/state/state.go index 5f13c8ee..16060246 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -121,13 +121,11 @@ type SubhelmfileEnvironmentSpec struct { // HelmSpec to defines helmDefault values type HelmSpec struct { - KubeContext string `yaml:"kubeContext,omitempty"` - TillerNamespace string `yaml:"tillerNamespace,omitempty"` - Tillerless bool `yaml:"tillerless"` - Args []string `yaml:"args,omitempty"` - PostRenderer string `yaml:"postRenderer,omitempty"` - PostRendererArgs []string `yaml:"postRendererArgs,omitempty"` - Verify bool `yaml:"verify"` + KubeContext string `yaml:"kubeContext,omitempty"` + TillerNamespace string `yaml:"tillerNamespace,omitempty"` + Tillerless bool `yaml:"tillerless"` + Args []string `yaml:"args,omitempty"` + Verify bool `yaml:"verify"` // Devel, when set to true, use development versions, too. Equivalent to version '>0.0.0-0' Devel bool `yaml:"devel"` // Wait, if set to true, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful @@ -154,6 +152,8 @@ type HelmSpec struct { SkipDeps bool `yaml:"skipDeps"` // on helm upgrade/diff, reuse values currently set in the release and merge them with the ones defined within helmfile ReuseValues bool `yaml:"reuseValues"` + // Propagate '--postRenderer' to helmv3 template and helm install + PostRenderer *string `yaml:"postRenderer,omitempty"` TLS bool `yaml:"tls"` TLSCACert string `yaml:"tlsCACert,omitempty"` @@ -317,6 +317,9 @@ type ReleaseSpec struct { // This is relevant only when your release uses a local chart or a directory containing K8s manifests or a Kustomization // as a Helm chart. SkipDeps *bool `yaml:"skipDeps,omitempty"` + + // Propagate '--postRenderer' to helmv3 template and helm install + PostRenderer *string `yaml:"postRenderer,omitempty"` } // ChartPathOrName returns ChartPath if it is non-empty, and returns Chart otherwise. @@ -2515,6 +2518,14 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp return nil, nil, err } + if helm.IsHelm3() && helm.GetPostRenderer() == "" { + if release.PostRenderer != nil && *release.PostRenderer != "" { + flags = append(flags, "--post-renderer", *release.PostRenderer) + } else if st.HelmDefaults.PostRenderer != nil && *st.HelmDefaults.PostRenderer != "" { + flags = append(flags, "--post-renderer", *st.HelmDefaults.PostRenderer) + } + } + common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex) if err != nil { return nil, clean, err @@ -2542,6 +2553,14 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS flags = st.appendApiVersionsFlags(flags, release) + if helm.IsHelm3() && helm.GetPostRenderer() == "" { + if release.PostRenderer != nil && *release.PostRenderer != "" { + flags = append(flags, "--post-renderer", *release.PostRenderer) + } else if st.HelmDefaults.PostRenderer != nil && *st.HelmDefaults.PostRenderer != "" { + flags = append(flags, "--post-renderer", *st.HelmDefaults.PostRenderer) + } + } + common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex) if err != nil { return nil, files, err diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 3e706205..76fe931b 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -161,7 +161,8 @@ func boolValue(v bool) *bool { func TestHelmState_flagsForUpgrade(t *testing.T) { enable := true disable := false - + postRendererDefault := "foo-default.sh" + postRendererRelease := "foo-release.sh" some := func(v int) *int { return &v } @@ -693,6 +694,73 @@ func TestHelmState_flagsForUpgrade(t *testing.T) { }, wantErr: "releases[].createNamespace requires Helm 3.2.0 or greater", }, + { + name: "post-renderer-flags-use-helmdefault", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + PostRenderer: &postRendererDefault, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererDefault, + "--namespace", "test-namespace", + }, + }, + { + name: "post-renderer-flags-use-release", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + PostRenderer: &postRendererRelease, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererRelease, + "--namespace", "test-namespace", + }, + }, + { + name: "post-renderer-flags-use-release-prior-helmdefault", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + PostRenderer: &postRendererDefault, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + PostRenderer: &postRendererRelease, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererRelease, + "--namespace", "test-namespace", + }, + }, } for i := range tests { tt := tests[i] @@ -724,6 +792,118 @@ func TestHelmState_flagsForUpgrade(t *testing.T) { } } +func TestHelmState_flagsForTemplate(t *testing.T) { + enable := true + disable := false + postRendererDefault := "foo-default.sh" + postRendererRelease := "foo-release.sh" + + tests := []struct { + name string + version *semver.Version + defaults HelmSpec + release *ReleaseSpec + want []string + wantErr string + }{ + { + name: "post-renderer-flags-use-helmdefault", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + PostRenderer: &postRendererDefault, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererDefault, + "--namespace", "test-namespace", + }, + }, + { + name: "post-renderer-flags-use-release", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + PostRenderer: &postRendererRelease, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererRelease, + "--namespace", "test-namespace", + }, + }, + { + name: "post-renderer-flags-use-release-prior-helmdefault", + defaults: HelmSpec{ + Verify: false, + CreateNamespace: &enable, + PostRenderer: &postRendererDefault, + }, + version: semver.MustParse("3.10.0"), + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Verify: &disable, + Name: "test-charts", + Namespace: "test-namespace", + CreateNamespace: &disable, + PostRenderer: &postRendererRelease, + }, + want: []string{ + "--version", "0.1", + "--post-renderer", postRendererRelease, + "--namespace", "test-namespace", + }, + }, + } + for i := range tests { + tt := tests[i] + t.Run(tt.name, func(t *testing.T) { + state := &HelmState{ + basePath: "./", + ReleaseSetSpec: ReleaseSetSpec{ + DeprecatedContext: "default", + Releases: []ReleaseSpec{*tt.release}, + HelmDefaults: tt.defaults, + }, + valsRuntime: valsRuntime, + } + helm := &exectest.Helm{ + Version: tt.version, + } + + args, _, err := state.flagsForTemplate(helm, tt.release, 0) + if err != nil && tt.wantErr == "" { + t.Errorf("unexpected error flagsForUpgrade: %v", err) + } + if tt.wantErr != "" && (err == nil || err.Error() != tt.wantErr) { + t.Errorf("expected error '%v'; got '%v'", err, tt.wantErr) + } + if !reflect.DeepEqual(args, tt.want) { + t.Errorf("flagsForUpgrade returned = %v, want %v", args, tt.want) + } + }) + } +} + func Test_isLocalChart(t *testing.T) { type args struct { chart string @@ -1054,6 +1234,7 @@ func TestHelmState_SyncRepos(t *testing.T) { } func TestHelmState_SyncReleases(t *testing.T) { + postRenderer := "foo.sh" tests := []struct { name string releases []ReleaseSpec @@ -1150,6 +1331,20 @@ func TestHelmState_SyncReleases(t *testing.T) { helm: &exectest.Helm{}, wantReleases: []exectest.Release{{Name: "releaseName", Flags: []string{"--set", "foo.bar[0]={A,B}", "--reset-values"}}}, }, + { + name: "post renderer", + releases: []ReleaseSpec{ + { + Name: "releaseName", + Chart: "foo", + PostRenderer: &postRenderer, + }, + }, + helm: &exectest.Helm{ + Helm3: true, + }, + wantReleases: []exectest.Release{{Name: "releaseName", Flags: []string{"--post-renderer", postRenderer, "--reset-values"}}}, + }, } for i := range tests { tt := tests[i]