feat: Add "--no-hooks" to helmfile template (#1813)

* Adding support for no-hooks in template cmd

Signed-off-by: Justin Lai <justin.lai@invitae.com>
This commit is contained in:
Justin Lai 2025-01-15 00:33:16 -05:00 committed by GitHub
parent a3f7146a6e
commit afe18e8031
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 151 additions and 2 deletions

View File

@ -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"`)

View File

@ -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(),

View File

@ -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"},

View File

@ -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
}

View File

@ -248,6 +248,7 @@ type TemplateConfigProvider interface {
SkipTests() bool
OutputDir() string
IncludeCRDs() bool
NoHooks() bool
KubeVersion() string
ShowOnly() []string

View File

@ -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=<nil>
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"

View File

@ -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()

View File

@ -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")
}