feat: Option to pass apiVersions to `helm diff` and `helm template` (#1046)
This makes it possible to pass the API Capabilities to helmfile when executing a task that does not render against an actual cluster (diff, template, apply). Resolves #1014
This commit is contained in:
parent
fb7cc60afe
commit
9cf6b59cd8
13
README.md
13
README.md
|
|
@ -95,7 +95,6 @@ helmDefaults:
|
|||
# limit the maximum number of revisions saved per release. Use 0 for no limit (default 10)
|
||||
historyMax: 10
|
||||
|
||||
|
||||
# The desired states of Helm releases.
|
||||
#
|
||||
# Helmfile runs various helm commands to converge the current state in the live cluster to the desired state defined here.
|
||||
|
|
@ -267,6 +266,18 @@ bases:
|
|||
- environments.yaml
|
||||
- defaults.yaml
|
||||
- templates.yaml
|
||||
|
||||
#
|
||||
# Advanced Configuration: API Capabilities
|
||||
#
|
||||
# Some helmfile tasks render releases locally without querying an actual cluster (diff, apply, template),
|
||||
# and in this case `.Capabilities.APIVersions` cannot be populated.
|
||||
# When a chart queries for a specific CRD, this can lead to unexpected results.
|
||||
#
|
||||
# Configure a fixed list of api versions to pass to helm via the --api-versions flag:
|
||||
apiVersions:
|
||||
- example/v1
|
||||
|
||||
```
|
||||
|
||||
## Templating
|
||||
|
|
|
|||
|
|
@ -2092,6 +2092,64 @@ releases:
|
|||
}
|
||||
}
|
||||
|
||||
func TestTemplate_ApiVersions(t *testing.T) {
|
||||
files := map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
apiVersions:
|
||||
- helmfile.test/v1
|
||||
- helmfile.test/v2
|
||||
releases:
|
||||
- name: myrelease1
|
||||
chart: mychart1
|
||||
`,
|
||||
}
|
||||
|
||||
var helm = &mockHelmExec{}
|
||||
var wantReleases = []mockTemplates{
|
||||
{name: "myrelease1", chart: "mychart1", flags: []string{"--api-versions", "helmfile.test/v1", "--api-versions", "helmfile.test/v2", "--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}},
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
logger := helmexec.NewLogger(&buffer, "debug")
|
||||
|
||||
valsRuntime, err := vals.New(vals.Options{CacheSize: 32})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error creating vals runtime: %v", err)
|
||||
}
|
||||
|
||||
app := appWithFs(&App{
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
KubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
helmExecer: helm,
|
||||
Namespace: "testNamespace",
|
||||
valsRuntime: valsRuntime,
|
||||
}, files)
|
||||
app.Template(configImpl{})
|
||||
|
||||
for i := range wantReleases {
|
||||
if wantReleases[i].name != helm.templated[i].name {
|
||||
t.Errorf("name = [%v], want %v", helm.templated[i].name, wantReleases[i].name)
|
||||
}
|
||||
if !strings.Contains(helm.templated[i].chart, wantReleases[i].chart) {
|
||||
t.Errorf("chart = [%v], want %v", helm.templated[i].chart, wantReleases[i].chart)
|
||||
}
|
||||
for j := range wantReleases[i].flags {
|
||||
if j == 7 {
|
||||
matched, _ := regexp.Match(wantReleases[i].flags[j], []byte(helm.templated[i].flags[j]))
|
||||
if !matched {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
}
|
||||
} else if wantReleases[i].flags[j] != helm.templated[i].flags[j] {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
|
|
@ -3351,6 +3409,25 @@ Affected releases are:
|
|||
err: "foo" has dependency to inexistent release "bar"
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "pass apiVersions to helm diff",
|
||||
loc: location(),
|
||||
files: map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
apiVersions:
|
||||
- xxx/v1
|
||||
releases:
|
||||
- name: foo
|
||||
chart: mychart1
|
||||
`,
|
||||
},
|
||||
diffs: map[exectest.DiffKey]error{
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--api-versionsxxx/v1--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
upgraded: []exectest.Release{
|
||||
{Name: "foo", Flags: []string{"--kube-context", "default"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testcases {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type HelmState struct {
|
|||
Repositories []RepositorySpec `yaml:"repositories,omitempty"`
|
||||
Releases []ReleaseSpec `yaml:"releases,omitempty"`
|
||||
Selectors []string `yaml:"-"`
|
||||
ApiVersions []string `yaml:"apiVersions,omitempty"`
|
||||
|
||||
Templates map[string]TemplateSpec `yaml:"templates"`
|
||||
|
||||
|
|
@ -1590,6 +1591,8 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS
|
|||
return nil, err
|
||||
}
|
||||
|
||||
flags = st.appendApiVersionsFlags(flags)
|
||||
|
||||
common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1615,6 +1618,8 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
flags = st.appendApiVersionsFlags(flags)
|
||||
|
||||
common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1622,6 +1627,13 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
|
|||
return append(flags, common...), nil
|
||||
}
|
||||
|
||||
func (st *HelmState) appendApiVersionsFlags(flags []string) []string {
|
||||
for _, a := range st.ApiVersions {
|
||||
flags = append(flags, "--api-versions", a)
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
func (st *HelmState) isDevelopment(release *ReleaseSpec) bool {
|
||||
result := st.HelmDefaults.Devel
|
||||
if release.Devel != nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue