Fix false-positive duplicate release with kubeContext (#1390)

Helmfile has been incorrectly showing releases with the same name but in different kubeContexts as duplicates. This fixes that.
This commit is contained in:
KUOKA Yusuke 2020-08-01 12:12:54 +09:00 committed by GitHub
parent 4fb47a833a
commit 87573089e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 8 deletions

View File

@ -827,7 +827,7 @@ func processFilteredReleases(st *state.HelmState, helm helmexec.Interface, conve
} }
type Key struct { type Key struct {
TillerNamespace, Name string TillerNamespace, Name, KubeContext string
} }
releaseNameCounts := map[Key]int{} releaseNameCounts := map[Key]int{}
@ -840,11 +840,21 @@ func processFilteredReleases(st *state.HelmState, helm helmexec.Interface, conve
namespace = st.HelmDefaults.TillerNamespace namespace = st.HelmDefaults.TillerNamespace
} }
} }
releaseNameCounts[Key{namespace, r.Name}]++ releaseNameCounts[Key{namespace, r.Name, r.KubeContext}]++
} }
for name, c := range releaseNameCounts { for name, c := range releaseNameCounts {
if c > 1 { if c > 1 {
return false, []error{fmt.Errorf("duplicate release \"%s\" found in \"%s\": there were %d releases named \"%s\" matching specified selector", name.Name, name.TillerNamespace, c, name.Name)} var msg string
if name.TillerNamespace != "" {
msg += fmt.Sprintf(" in namespace %q", name.TillerNamespace)
}
if name.KubeContext != "" {
msg += fmt.Sprintf(" in kubecontext %q", name.KubeContext)
}
return false, []error{fmt.Errorf("duplicate release %q found%s: there were %d releases named \"%s\" matching specified selector", name.Name, msg, c, name.Name)}
} }
} }

View File

@ -456,11 +456,23 @@ releases:
- name: foo - name: foo
chart: charts/foo chart: charts/foo
labels: labels:
duplicated: yes duplicatedNs: yes
- name: foo - name: foo
chart: charts/foo chart: charts/foo
labels: labels:
duplicated: yes duplicatedNs: yes
- name: grafana
chart: stable/grafana
- name: foo
chart: charts/foo
kubeContext: baz
labels:
duplicatedCtx: yes
- name: foo
chart: charts/foo
kubeContext: baz
labels:
duplicatedCtx: yes
- name: bar - name: bar
chart: charts/foo chart: charts/foo
tillerNamespace: bar1 tillerNamespace: bar1
@ -485,7 +497,8 @@ releases:
{label: "name!=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name!=. Expected label in form k=v or k!=v"}, {label: "name!=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name!=. Expected label in form k=v or k!=v"},
{label: "name", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name. Expected label in form k=v or k!=v"}, {label: "name", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name. Expected label in form k=v or k!=v"},
// See https://github.com/roboll/helmfile/issues/193 // See https://github.com/roboll/helmfile/issues/193
{label: "duplicated=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in \"zoo\": there were 2 releases named \"foo\" matching specified selector"}, {label: "duplicatedNs=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\": there were 2 releases named \"foo\" matching specified selector"},
{label: "duplicatedCtx=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\" in kubecontext \"baz\": there were 2 releases named \"foo\" matching specified selector"},
{label: "duplicatedOK=yes", expectedCount: 2, expectErr: false}, {label: "duplicatedOK=yes", expectedCount: 2, expectErr: false},
} }
@ -1302,7 +1315,7 @@ releases:
SetFilter(true), SetFilter(true),
) )
expected := "in ./helmfile.yaml: duplicate release \"foo\" found in \"\": there were 2 releases named \"foo\" matching specified selector" expected := "in ./helmfile.yaml: duplicate release \"foo\" found: there were 2 releases named \"foo\" matching specified selector"
if err == nil { if err == nil {
t.Errorf("error expected but not happened") t.Errorf("error expected but not happened")
} else if err.Error() != expected { } else if err.Error() != expected {
@ -1436,7 +1449,54 @@ releases:
SetFilter(true), SetFilter(true),
) )
expected := "in ./helmfile.yaml: duplicate release \"foo\" found in \"foo\": there were 2 releases named \"foo\" matching specified selector" expected := "in ./helmfile.yaml: duplicate release \"foo\" found in namespace \"foo\": there were 2 releases named \"foo\" matching specified selector"
if err == nil {
t.Errorf("error expected but not happened")
} else if err.Error() != expected {
t.Errorf("unexpected error message: expected=\"%s\", actual=\"%s\"", expected, err.Error())
}
}
func TestVisitDesiredStatesWithReleases_DuplicateReleasesInNsKubeContextHelm3(t *testing.T) {
files := map[string]string{
"/path/to/helmfile.yaml": `
releases:
- name: foo
namespace: foo
chart: charts/foo
kubeContext: foo
- name: foo
namespace: foo
chart: charts/foo
kubeContext: foo
`,
}
actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases {
actual = append(actual, r)
}
return false, []error{}
}
app := appWithFs(&App{
OverrideHelmBinary: DefaultHelmBinary,
OverrideKubeContext: "default",
Logger: helmexec.NewLogger(os.Stderr, "debug"),
Namespace: "",
Env: "default",
FileOrDir: "helmfile.yaml",
}, files)
expectNoCallsToHelmVersion(app, true)
err := app.ForEachState(
collectReleases,
SetFilter(true),
)
expected := "in ./helmfile.yaml: duplicate release \"foo\" found in namespace \"foo\" in kubecontext \"foo\": there were 2 releases named \"foo\" matching specified selector"
if err == nil { if err == nil {
t.Errorf("error expected but not happened") t.Errorf("error expected but not happened")
} else if err.Error() != expected { } else if err.Error() != expected {