diff --git a/cmd/template.go b/cmd/template.go index fb26ff3a..6cb81fea 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -40,11 +40,11 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&templateOptions.Validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the template of available API versions") f.BoolVar(&templateOptions.IncludeCRDs, "include-crds", false, "include CRDs in the templated output") f.BoolVar(&templateOptions.SkipTests, "skip-tests", false, "skip tests from templated output") - f.BoolVar(&templateOptions.SkipNeeds, "skip-needs", true, `do not automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided. Defaults to true when --include-needs or --include-transitive-needs is not provided`) f.BoolVar(&templateOptions.IncludeNeeds, "include-needs", false, `automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided`) 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.BoolVar(&templateOptions.NoHooks, "no-hooks", false, "do not template files made by hooks.") 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.BoolVar(&templateOptions.SkipSchemaValidation, "skip-schema-validation", false, `pass skip-schema-validation to "helm template" or "helm upgrade --install"`) diff --git a/pkg/app/app.go b/pkg/app/app.go index 7991c144..61b4dce1 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1976,6 +1976,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) { opts := &state.TemplateOpts{ Set: c.Set(), IncludeCRDs: c.IncludeCRDs(), + NoHooks: c.NoHooks(), OutputDirTemplate: c.OutputDirTemplate(), SkipCleanup: c.SkipCleanup(), SkipTests: c.SkipTests(), diff --git a/pkg/app/app_template_test.go b/pkg/app/app_template_test.go index 921bcb84..a29b1fea 100644 --- a/pkg/app/app_template_test.go +++ b/pkg/app/app_template_test.go @@ -24,6 +24,7 @@ func TestTemplate(t *testing.T) { skipNeeds bool includeNeeds bool includeTransitiveNeeds bool + noHooks bool showOnly []string } @@ -133,6 +134,7 @@ releases: includeNeeds: tc.fields.includeNeeds, includeTransitiveNeeds: tc.fields.includeTransitiveNeeds, showOnly: tc.fields.showOnly, + noHooks: tc.fields.noHooks, }) var gotErr string @@ -299,6 +301,20 @@ releases: }) }) + t.Run("no-hooks", func(t *testing.T) { + check(t, testcase{ + fields: fields{ + skipNeeds: true, + noHooks: true, + }, + selectors: []string{"app=test"}, + templated: []exectest.Release{ + {Name: "external-secrets", Flags: []string{"--namespace", "default", "--no-hooks"}}, + {Name: "my-release", Flags: []string{"--namespace", "default", "--no-hooks"}}, + }, + }) + }) + t.Run("bad selector", func(t *testing.T) { check(t, testcase{ selectors: []string{"app=test_non_existent"}, diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index b6198f38..df79ee51 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2088,6 +2088,7 @@ type configImpl struct { selectors []string set []string output string + noHooks bool includeCRDs bool skipCleanup bool skipCRDs bool @@ -2167,6 +2168,10 @@ func (c configImpl) IncludeCRDs() bool { return c.includeCRDs } +func (c configImpl) NoHooks() bool { + return c.noHooks +} + func (c configImpl) Concurrency() int { return 1 } @@ -2389,7 +2394,6 @@ func (a applyConfig) DiffArgs() string { } // helmfile-template-only flags - func (a applyConfig) IncludeCRDs() bool { return a.includeCRDs } diff --git a/pkg/app/config.go b/pkg/app/config.go index bb76811a..b6e3a064 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -248,6 +248,7 @@ type TemplateConfigProvider interface { SkipTests() bool OutputDir() string IncludeCRDs() bool + NoHooks() bool KubeVersion() string ShowOnly() []string diff --git a/pkg/app/testdata/app_template_test/no-hooks b/pkg/app/testdata/app_template_test/no-hooks new file mode 100644 index 00000000..67ee2936 --- /dev/null +++ b/pkg/app/testdata/app_template_test/no-hooks @@ -0,0 +1,115 @@ +processing file "helmfile.yaml" in directory "." +changing working directory to "/path/to" +first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode= +first-pass uses: &{default map[] map[]} +first-pass rendering output of "helmfile.yaml.part.0": + 0: + 1: releases: + 2: - name: logging + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + 6: - name: kubernetes-external-secrets + 7: chart: incubator/raw + 8: namespace: kube-system + 9: needs: +10: - kube-system/logging +11: +12: - name: external-secrets +13: chart: incubator/raw +14: namespace: default +15: labels: +16: app: test +17: needs: +18: - kube-system/kubernetes-external-secrets +19: +20: - name: my-release +21: chart: incubator/raw +22: namespace: default +23: labels: +24: app: test +25: needs: +26: - default/external-secrets +27: +28: +29: # Disabled releases are treated as missing +30: - name: disabled +31: chart: incubator/raw +32: namespace: kube-system +33: installed: false +34: +35: - name: test2 +36: chart: incubator/raw +37: needs: +38: - kube-system/disabled +39: +40: - name: test3 +41: chart: incubator/raw +42: needs: +43: - test2 +44: + +first-pass produced: &{default map[] map[]} +first-pass rendering result of "helmfile.yaml.part.0": {default map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile.yaml.part.0": + 0: + 1: releases: + 2: - name: logging + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + 6: - name: kubernetes-external-secrets + 7: chart: incubator/raw + 8: namespace: kube-system + 9: needs: +10: - kube-system/logging +11: +12: - name: external-secrets +13: chart: incubator/raw +14: namespace: default +15: labels: +16: app: test +17: needs: +18: - kube-system/kubernetes-external-secrets +19: +20: - name: my-release +21: chart: incubator/raw +22: namespace: default +23: labels: +24: app: test +25: needs: +26: - default/external-secrets +27: +28: +29: # Disabled releases are treated as missing +30: - name: disabled +31: chart: incubator/raw +32: namespace: kube-system +33: installed: false +34: +35: - name: test2 +36: chart: incubator/raw +37: needs: +38: - kube-system/disabled +39: +40: - name: test3 +41: chart: incubator/raw +42: needs: +43: - test2 +44: + +merged environment: &{default map[] map[]} +WARNING: release test2 needs disabled, but disabled is not installed due to installed: false. Either mark disabled as installed or remove disabled from test2's needs +2 release(s) matching app=test found in helmfile.yaml + +processing 2 groups of releases in this order: +GROUP RELEASES +1 default/default/external-secrets +2 default/default/my-release + +processing releases in group 1/2: default/default/external-secrets +processing releases in group 2/2: default/default/my-release +changing working directory back to "/path/to" diff --git a/pkg/config/template.go b/pkg/config/template.go index 30d2eea4..134cc6aa 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -30,6 +30,8 @@ type TemplateOptions struct { IncludeNeeds bool // IncludeTransitiveNeeds is the include transitive needs flag IncludeTransitiveNeeds bool + // No-Hooks is the no hooks flag + NoHooks bool // SkipCleanup is the skip cleanup flag SkipCleanup bool // Propagate '--post-renderer' to helmv3 template and helm install @@ -73,6 +75,11 @@ func (t *TemplateImpl) IncludeCRDs() bool { return t.TemplateOptions.IncludeCRDs } +// NoHooks returns the no hooks +func (t *TemplateImpl) NoHooks() bool { + return t.TemplateOptions.NoHooks +} + // IncludeNeeds returns the include needs func (t *TemplateImpl) IncludeNeeds() bool { return t.TemplateOptions.IncludeNeeds || t.IncludeTransitiveNeeds() diff --git a/pkg/state/state.go b/pkg/state/state.go index 421491b4..e918933b 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1484,6 +1484,7 @@ type TemplateOpts struct { SkipCleanup bool OutputDirTemplate string IncludeCRDs bool + NoHooks bool SkipTests bool PostRenderer string PostRendererArgs []string @@ -1566,6 +1567,10 @@ func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, flags = append(flags, "--include-crds") } + if opts.NoHooks { + flags = append(flags, "--no-hooks") + } + if opts.SkipTests { flags = append(flags, "--skip-tests") }