Add helmfile template --show-only (#1494)
Add a `--show-only` parameter to the `helmfile template` command to pass on to the `helm template` command. Signed-off-by: Jim Barber <jim.barber@healthengine.com.au>
This commit is contained in:
parent
f2a0467b05
commit
f73da1e2a1
|
|
@ -47,6 +47,7 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command {
|
||||||
f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`)
|
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.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`)
|
f.StringVar(&templateOptions.KubeVersion, "kube-version", "", `pass --kube-version to "helm template". Overrides kubeVersion in helmfile.yaml`)
|
||||||
|
f.StringArrayVar(&templateOptions.ShowOnly, "show-only", nil, `pass --show-only to "helm template"`)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1964,6 +1964,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
||||||
PostRenderer: c.PostRenderer(),
|
PostRenderer: c.PostRenderer(),
|
||||||
PostRendererArgs: c.PostRendererArgs(),
|
PostRendererArgs: c.PostRendererArgs(),
|
||||||
KubeVersion: c.KubeVersion(),
|
KubeVersion: c.KubeVersion(),
|
||||||
|
ShowOnly: c.ShowOnly(),
|
||||||
}
|
}
|
||||||
return st.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), c.Validate(), opts)
|
return st.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), c.Validate(), opts)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ func TestTemplate(t *testing.T) {
|
||||||
skipNeeds bool
|
skipNeeds bool
|
||||||
includeNeeds bool
|
includeNeeds bool
|
||||||
includeTransitiveNeeds bool
|
includeTransitiveNeeds bool
|
||||||
|
showOnly []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type testcase struct {
|
type testcase struct {
|
||||||
|
|
@ -131,6 +132,7 @@ releases:
|
||||||
skipNeeds: tc.fields.skipNeeds,
|
skipNeeds: tc.fields.skipNeeds,
|
||||||
includeNeeds: tc.fields.includeNeeds,
|
includeNeeds: tc.fields.includeNeeds,
|
||||||
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
||||||
|
showOnly: tc.fields.showOnly,
|
||||||
})
|
})
|
||||||
|
|
||||||
var gotErr string
|
var gotErr string
|
||||||
|
|
@ -304,6 +306,18 @@ releases:
|
||||||
error: "err: no releases found that matches specified selector(app=test_non_existent) and environment(default), in any helmfile",
|
error: "err: no releases found that matches specified selector(app=test_non_existent) and environment(default), in any helmfile",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("show-only", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
fields: fields{
|
||||||
|
showOnly: []string{"templates/resources.yaml"},
|
||||||
|
},
|
||||||
|
selectors: []string{"name=logging"},
|
||||||
|
templated: []exectest.Release{
|
||||||
|
{Name: "logging", Flags: []string{"--show-only", "templates/resources.yaml", "--namespace", "kube-system"}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTemplate_StrictParsing(t *testing.T) {
|
func TestTemplate_StrictParsing(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -2189,6 +2189,10 @@ func (c configImpl) KubeVersion() string {
|
||||||
return c.kubeVersion
|
return c.kubeVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c configImpl) ShowOnly() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type applyConfig struct {
|
type applyConfig struct {
|
||||||
args string
|
args string
|
||||||
cascade string
|
cascade string
|
||||||
|
|
@ -2230,6 +2234,7 @@ type applyConfig struct {
|
||||||
postRendererArgs []string
|
postRendererArgs []string
|
||||||
kubeVersion string
|
kubeVersion string
|
||||||
suppressOutputLineRegex []string
|
suppressOutputLineRegex []string
|
||||||
|
showOnly []string
|
||||||
|
|
||||||
// template-only options
|
// template-only options
|
||||||
includeCRDs, skipTests bool
|
includeCRDs, skipTests bool
|
||||||
|
|
@ -2406,6 +2411,10 @@ func (a applyConfig) KubeVersion() string {
|
||||||
return a.kubeVersion
|
return a.kubeVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a applyConfig) ShowOnly() []string {
|
||||||
|
return a.showOnly
|
||||||
|
}
|
||||||
|
|
||||||
type depsConfig struct {
|
type depsConfig struct {
|
||||||
skipRepos bool
|
skipRepos bool
|
||||||
includeTransitiveNeeds bool
|
includeTransitiveNeeds bool
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,7 @@ type TemplateConfigProvider interface {
|
||||||
OutputDir() string
|
OutputDir() string
|
||||||
IncludeCRDs() bool
|
IncludeCRDs() bool
|
||||||
KubeVersion() string
|
KubeVersion() string
|
||||||
|
ShowOnly() []string
|
||||||
|
|
||||||
DAGConfig
|
DAGConfig
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
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
|
||||||
|
1 release(s) matching name=logging found in helmfile.yaml
|
||||||
|
|
||||||
|
processing 1 groups of releases in this order:
|
||||||
|
GROUP RELEASES
|
||||||
|
1 default/kube-system/logging
|
||||||
|
|
||||||
|
processing releases in group 1/1: default/kube-system/logging
|
||||||
|
changing working directory back to "/path/to"
|
||||||
|
|
@ -38,6 +38,8 @@ type TemplateOptions struct {
|
||||||
PostRendererArgs []string
|
PostRendererArgs []string
|
||||||
// KubeVersion is the kube-version flag
|
// KubeVersion is the kube-version flag
|
||||||
KubeVersion string
|
KubeVersion string
|
||||||
|
// Propagate '--show-only` to helm template
|
||||||
|
ShowOnly []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTemplateOptions creates a new Apply
|
// NewTemplateOptions creates a new Apply
|
||||||
|
|
@ -137,3 +139,8 @@ func (t *TemplateImpl) PostRendererArgs() []string {
|
||||||
func (t *TemplateImpl) KubeVersion() string {
|
func (t *TemplateImpl) KubeVersion() string {
|
||||||
return t.TemplateOptions.KubeVersion
|
return t.TemplateOptions.KubeVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowOnly returns the ShowOnly.
|
||||||
|
func (t *TemplateImpl) ShowOnly() []string {
|
||||||
|
return t.TemplateOptions.ShowOnly
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,20 @@ func (st *HelmState) appendCascadeFlags(flags []string, helm helmexec.Interface,
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append show-only flags to helm flags
|
||||||
|
func (st *HelmState) appendShowOnlyFlags(flags []string, showOnly []string) []string {
|
||||||
|
showOnlyFlags := []string{}
|
||||||
|
if len(showOnly) != 0 {
|
||||||
|
showOnlyFlags = showOnly
|
||||||
|
}
|
||||||
|
for _, arg := range showOnlyFlags {
|
||||||
|
if arg != "" {
|
||||||
|
flags = append(flags, "--show-only", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
type Chartify struct {
|
type Chartify struct {
|
||||||
Opts *chartify.ChartifyOpts
|
Opts *chartify.ChartifyOpts
|
||||||
Clean func()
|
Clean func()
|
||||||
|
|
|
||||||
|
|
@ -249,3 +249,30 @@ func TestAppendSuppressOutputLineRegexFlags(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppendShowOnlyFlags(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
templateOpts []string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "cli template show only with 1 file",
|
||||||
|
templateOpts: []string{"templates/config.yaml"},
|
||||||
|
expected: []string{"--show-only", "templates/config.yaml"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cli template show only with 2 files",
|
||||||
|
templateOpts: []string{"templates/config.yaml", "templates/resources.yaml"},
|
||||||
|
expected: []string{"--show-only", "templates/config.yaml", "--show-only", "templates/resources.yaml"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
st := &HelmState{}
|
||||||
|
got := st.appendShowOnlyFlags([]string{}, tt.templateOpts)
|
||||||
|
require.Equalf(t, tt.expected, got, "appendShowOnlyFlags() = %v, want %v", got, tt.expected)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1437,6 +1437,7 @@ type TemplateOpts struct {
|
||||||
PostRenderer string
|
PostRenderer string
|
||||||
PostRendererArgs []string
|
PostRendererArgs []string
|
||||||
KubeVersion string
|
KubeVersion string
|
||||||
|
ShowOnly []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type TemplateOpt interface{ Apply(*TemplateOpts) }
|
type TemplateOpt interface{ Apply(*TemplateOpts) }
|
||||||
|
|
@ -2691,15 +2692,18 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS
|
||||||
postRenderer := ""
|
postRenderer := ""
|
||||||
var postRendererArgs []string
|
var postRendererArgs []string
|
||||||
kubeVersion := ""
|
kubeVersion := ""
|
||||||
|
var showOnly []string
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
postRenderer = opt.PostRenderer
|
postRenderer = opt.PostRenderer
|
||||||
postRendererArgs = opt.PostRendererArgs
|
postRendererArgs = opt.PostRendererArgs
|
||||||
kubeVersion = opt.KubeVersion
|
kubeVersion = opt.KubeVersion
|
||||||
|
showOnly = opt.ShowOnly
|
||||||
}
|
}
|
||||||
flags = st.appendPostRenderFlags(flags, release, postRenderer)
|
flags = st.appendPostRenderFlags(flags, release, postRenderer)
|
||||||
flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs)
|
flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs)
|
||||||
flags = st.appendApiVersionsFlags(flags, release, kubeVersion)
|
flags = st.appendApiVersionsFlags(flags, release, kubeVersion)
|
||||||
flags = st.appendChartDownloadTLSFlags(flags, release)
|
flags = st.appendChartDownloadTLSFlags(flags, release)
|
||||||
|
flags = st.appendShowOnlyFlags(flags, showOnly)
|
||||||
|
|
||||||
common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
|
common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue