mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-21 11:48:10 +02:00
feat: add labels for helm release (#1046)
feat: add labels for k8s resources Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
+7
-1
@@ -1106,13 +1106,17 @@ func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converg
|
||||
}
|
||||
}
|
||||
|
||||
// pre-overrides HelmState
|
||||
// pre-handles HelmState
|
||||
fHelmStatsWithOverrides := func(st *state.HelmState) (bool, []error) {
|
||||
var err error
|
||||
// override release settings
|
||||
st.Releases, err = st.GetReleasesWithOverrides()
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
|
||||
// override release labels
|
||||
st.Releases = st.GetReleasesWithLabels()
|
||||
return f(st)
|
||||
}
|
||||
|
||||
@@ -1502,6 +1506,7 @@ Do you really want to apply?
|
||||
SyncArgs: c.SyncArgs(),
|
||||
HideNotes: c.HideNotes(),
|
||||
TakeOwnership: c.TakeOwnership(),
|
||||
SyncReleaseLabels: c.SyncReleaseLabels(),
|
||||
}
|
||||
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts)
|
||||
}))
|
||||
@@ -1900,6 +1905,7 @@ Do you really want to sync?
|
||||
HideNotes: c.HideNotes(),
|
||||
TakeOwnership: c.TakeOwnership(),
|
||||
SkipSchemaValidation: c.SkipSchemaValidation(),
|
||||
SyncReleaseLabels: c.SyncReleaseLabels(),
|
||||
}
|
||||
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts)
|
||||
}))
|
||||
|
||||
+28
-28
@@ -159,17 +159,17 @@ releases:
|
||||
t.Run("default environment includes all releases", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
environment: "default",
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
logging kube-system true true incubator/raw
|
||||
kubernetes-external-secrets kube-system true true incubator/raw
|
||||
external-secrets default true true app:test incubator/raw
|
||||
my-release default true true app:test incubator/raw
|
||||
disabled kube-system true false incubator/raw
|
||||
test2 true true incubator/raw
|
||||
test3 true true incubator/raw
|
||||
cache my-app true true app:test bitnami/redis 17.0.7
|
||||
database my-app true true bitnami/postgres 11.6.22
|
||||
global kube-system true true incubator/raw
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
logging kube-system true true chart:raw,name:logging,namespace:kube-system incubator/raw
|
||||
kubernetes-external-secrets kube-system true true chart:raw,name:kubernetes-external-secrets,namespace:kube-system incubator/raw
|
||||
external-secrets default true true app:test,chart:raw,name:external-secrets,namespace:default incubator/raw
|
||||
my-release default true true app:test,chart:raw,name:my-release,namespace:default incubator/raw
|
||||
disabled kube-system true false chart:raw,name:disabled,namespace:kube-system incubator/raw
|
||||
test2 true true chart:raw,name:test2,namespace: incubator/raw
|
||||
test3 true true chart:raw,name:test3,namespace: incubator/raw
|
||||
cache my-app true true app:test,chart:redis,name:cache,namespace:my-app bitnami/redis 17.0.7
|
||||
database my-app true true chart:postgres,name:database,namespace:my-app bitnami/postgres 11.6.22
|
||||
global kube-system true true chart:raw,name:global,namespace:kube-system incubator/raw
|
||||
`,
|
||||
}, cfg)
|
||||
})
|
||||
@@ -185,9 +185,9 @@ global kube-system true true incubator/raw
|
||||
check(t, testcase{
|
||||
environment: "development",
|
||||
selectors: []string{"app=test"},
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
external-secrets default true true app:test incubator/raw
|
||||
my-release default true true app:test incubator/raw
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
external-secrets default true true app:test,chart:raw,name:external-secrets,namespace:default incubator/raw
|
||||
my-release default true true app:test,chart:raw,name:my-release,namespace:default incubator/raw
|
||||
`,
|
||||
}, cfg)
|
||||
})
|
||||
@@ -195,9 +195,9 @@ my-release default true true app:test incubator/raw
|
||||
t.Run("filters releases for environment used in one file only", func(t *testing.T) {
|
||||
check(t, testcase{
|
||||
environment: "test",
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
cache my-app true true app:test bitnami/redis 17.0.7
|
||||
database my-app true true bitnami/postgres 11.6.22
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
cache my-app true true app:test,chart:redis,name:cache,namespace:my-app bitnami/redis 17.0.7
|
||||
database my-app true true chart:postgres,name:database,namespace:my-app bitnami/postgres 11.6.22
|
||||
`,
|
||||
}, cfg)
|
||||
})
|
||||
@@ -206,16 +206,16 @@ database my-app true true bitnami/postgres 11.6.22
|
||||
check(t, testcase{
|
||||
environment: "shared",
|
||||
// 'global' release has no environments, so is still excluded
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
logging kube-system true true incubator/raw
|
||||
kubernetes-external-secrets kube-system true true incubator/raw
|
||||
external-secrets default true true app:test incubator/raw
|
||||
my-release default true true app:test incubator/raw
|
||||
disabled kube-system true false incubator/raw
|
||||
test2 true true incubator/raw
|
||||
test3 true true incubator/raw
|
||||
cache my-app true true app:test bitnami/redis 17.0.7
|
||||
database my-app true true bitnami/postgres 11.6.22
|
||||
expected: `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
logging kube-system true true chart:raw,name:logging,namespace:kube-system incubator/raw
|
||||
kubernetes-external-secrets kube-system true true chart:raw,name:kubernetes-external-secrets,namespace:kube-system incubator/raw
|
||||
external-secrets default true true app:test,chart:raw,name:external-secrets,namespace:default incubator/raw
|
||||
my-release default true true app:test,chart:raw,name:my-release,namespace:default incubator/raw
|
||||
disabled kube-system true false chart:raw,name:disabled,namespace:kube-system incubator/raw
|
||||
test2 true true chart:raw,name:test2,namespace: incubator/raw
|
||||
test3 true true chart:raw,name:test3,namespace: incubator/raw
|
||||
cache my-app true true app:test,chart:redis,name:cache,namespace:my-app bitnami/redis 17.0.7
|
||||
database my-app true true chart:postgres,name:database,namespace:my-app bitnami/postgres 11.6.22
|
||||
`,
|
||||
}, cfg)
|
||||
})
|
||||
@@ -285,7 +285,7 @@ releases:
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
expected := `[{"name":"myrelease1","namespace":"testNamespace","enabled":true,"installed":false,"labels":"id:myrelease1","chart":"mychart1","version":""},{"name":"myrelease2","namespace":"testNamespace","enabled":false,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease3","namespace":"testNamespace","enabled":true,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease4","namespace":"testNamespace","enabled":true,"installed":true,"labels":"id:myrelease1","chart":"mychart1","version":""}]
|
||||
expected := `[{"name":"myrelease1","namespace":"testNamespace","enabled":true,"installed":false,"labels":"chart:mychart1,id:myrelease1,name:myrelease1,namespace:testNamespace","chart":"mychart1","version":""},{"name":"myrelease2","namespace":"testNamespace","enabled":false,"installed":true,"labels":"chart:mychart1,name:myrelease2,namespace:testNamespace","chart":"mychart1","version":""},{"name":"myrelease3","namespace":"testNamespace","enabled":true,"installed":true,"labels":"chart:mychart1,name:myrelease3,namespace:testNamespace","chart":"mychart1","version":""},{"name":"myrelease4","namespace":"testNamespace","enabled":true,"installed":true,"labels":"chart:mychart1,id:myrelease1,name:myrelease4,namespace:testNamespace","chart":"mychart1","version":""}]
|
||||
`
|
||||
assert.Equal(t, expected, out)
|
||||
}
|
||||
|
||||
+10
-5
@@ -2259,6 +2259,7 @@ type applyConfig struct {
|
||||
showOnly []string
|
||||
hideNotes bool
|
||||
takeOwnership bool
|
||||
syncReleaseLabels bool
|
||||
|
||||
// template-only options
|
||||
includeCRDs, skipTests bool
|
||||
@@ -2453,6 +2454,10 @@ func (a applyConfig) TakeOwnership() bool {
|
||||
return a.takeOwnership
|
||||
}
|
||||
|
||||
func (a applyConfig) SyncReleaseLabels() bool {
|
||||
return a.syncReleaseLabels
|
||||
}
|
||||
|
||||
type depsConfig struct {
|
||||
skipRepos bool
|
||||
includeTransitiveNeeds bool
|
||||
@@ -3977,11 +3982,11 @@ releases:
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
expected := `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
myrelease1 testNamespace true false common:label,id:myrelease1 mychart1
|
||||
myrelease2 testNamespace false true common:label mychart1
|
||||
myrelease3 testNamespace true true mychart1
|
||||
myrelease4 testNamespace true true id:myrelease1 mychart1
|
||||
expected := `NAME NAMESPACE ENABLED INSTALLED LABELS CHART VERSION
|
||||
myrelease1 testNamespace true false chart:mychart1,common:label,id:myrelease1,name:myrelease1,namespace:testNamespace mychart1
|
||||
myrelease2 testNamespace false true chart:mychart1,common:label,name:myrelease2,namespace:testNamespace mychart1
|
||||
myrelease3 testNamespace true true chart:mychart1,name:myrelease3,namespace:testNamespace mychart1
|
||||
myrelease4 testNamespace true true chart:mychart1,id:myrelease1,name:myrelease4,namespace:testNamespace mychart1
|
||||
`
|
||||
|
||||
assert.Equal(t, expected, out)
|
||||
|
||||
@@ -80,6 +80,8 @@ type ApplyConfigProvider interface {
|
||||
DiffArgs() string
|
||||
SyncArgs() string
|
||||
|
||||
SyncReleaseLabels() bool
|
||||
|
||||
DAGConfig
|
||||
|
||||
concurrencyConfig
|
||||
@@ -112,6 +114,9 @@ type SyncConfigProvider interface {
|
||||
SkipNeeds() bool
|
||||
IncludeNeeds() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
|
||||
SyncReleaseLabels() bool
|
||||
|
||||
DAGConfig
|
||||
|
||||
concurrencyConfig
|
||||
|
||||
@@ -71,6 +71,8 @@ type ApplyOptions struct {
|
||||
|
||||
// TakeOwnership is true if the ownership should be taken
|
||||
TakeOwnership bool
|
||||
|
||||
SyncReleaseLabels bool
|
||||
}
|
||||
|
||||
// NewApply creates a new Apply
|
||||
@@ -266,3 +268,7 @@ func (a *ApplyImpl) HideNotes() bool {
|
||||
func (a *ApplyImpl) TakeOwnership() bool {
|
||||
return a.ApplyOptions.TakeOwnership
|
||||
}
|
||||
|
||||
func (a *ApplyImpl) SyncReleaseLabels() bool {
|
||||
return a.ApplyOptions.SyncReleaseLabels
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ type SyncOptions struct {
|
||||
HideNotes bool
|
||||
// TakeOwnership is the take ownership flag
|
||||
TakeOwnership bool
|
||||
// SyncReleaseLabels is the sync release labels flag
|
||||
SyncReleaseLabels bool
|
||||
}
|
||||
|
||||
// NewSyncOptions creates a new Apply
|
||||
@@ -167,3 +169,7 @@ func (t *SyncImpl) HideNotes() bool {
|
||||
func (t *SyncImpl) TakeOwnership() bool {
|
||||
return t.SyncOptions.TakeOwnership
|
||||
}
|
||||
|
||||
func (t *SyncImpl) SyncReleaseLabels() bool {
|
||||
return t.SyncOptions.SyncReleaseLabels
|
||||
}
|
||||
|
||||
@@ -4,9 +4,13 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/helmfile/chartify"
|
||||
"helm.sh/helm/v3/pkg/storage/driver"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
@@ -26,6 +30,39 @@ func (st *HelmState) appendHelmXFlags(flags []string, release *ReleaseSpec) []st
|
||||
return flags
|
||||
}
|
||||
|
||||
func formatLabels(labels map[string]string) string {
|
||||
var labelsList, keys []string
|
||||
for k := range labels {
|
||||
if k == "" || slices.Contains(driver.GetSystemLabels(), k) {
|
||||
continue
|
||||
}
|
||||
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
if len(keys) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, k := range keys {
|
||||
val := labels[k]
|
||||
labelsList = append(labelsList, fmt.Sprintf("%s=%s", k, val))
|
||||
}
|
||||
return strings.Join(labelsList, ",")
|
||||
}
|
||||
|
||||
// append labels flags to helm flags, starting from helm v3.13.0
|
||||
func (st *HelmState) appendLabelsFlags(flags []string, helm helmexec.Interface, release *ReleaseSpec, syncReleaseLabels bool) []string {
|
||||
if helm.IsVersionAtLeast("3.13.0") && (syncReleaseLabels || release.SyncReleaseLabels) {
|
||||
labels := formatLabels(release.Labels)
|
||||
if labels != "" {
|
||||
flags = append(flags, "--labels", labels)
|
||||
}
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
// append post-renderer flags to helm flags
|
||||
func (st *HelmState) appendPostRenderFlags(flags []string, release *ReleaseSpec, postRenderer string) []string {
|
||||
switch {
|
||||
|
||||
@@ -431,3 +431,54 @@ func TestAppendTakeOwnershipFlags(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatLabels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
labels map[string]string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty labels",
|
||||
labels: map[string]string{},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "single label",
|
||||
labels: map[string]string{"foo": "bar"},
|
||||
want: "foo=bar",
|
||||
},
|
||||
{
|
||||
name: "multiple labels",
|
||||
labels: map[string]string{"foo": "bar", "baz": "qux"},
|
||||
want: "baz=qux,foo=bar",
|
||||
},
|
||||
{
|
||||
name: "multiple labels with empty value",
|
||||
labels: map[string]string{"foo": "bar", "baz": "qux", "quux": ""},
|
||||
want: "baz=qux,foo=bar,quux=",
|
||||
},
|
||||
{
|
||||
name: "multiple labels with empty key",
|
||||
labels: map[string]string{"foo": "bar", "baz": "qux", "": "quux"},
|
||||
want: "baz=qux,foo=bar",
|
||||
},
|
||||
{
|
||||
name: "empty label value",
|
||||
labels: map[string]string{"foo": ""},
|
||||
want: "foo=",
|
||||
},
|
||||
{
|
||||
name: "empty label key",
|
||||
labels: map[string]string{"": "bar"},
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := formatLabels(tt.labels)
|
||||
require.Equal(t, tt.want, got, "formatLabels() = %v, want %v", got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,14 +108,14 @@ func TestSelectReleasesWithOverrides(t *testing.T) {
|
||||
}.MustLoadState(t, "/helmfile.yaml", "default")
|
||||
|
||||
for _, tc := range testcases {
|
||||
var err error
|
||||
state.Selectors = tc.selector
|
||||
|
||||
releases, err := state.GetReleasesWithOverrides()
|
||||
state.Releases = releases
|
||||
|
||||
state.Releases, err = state.GetReleasesWithOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("%s %s: %v", tc.selector, tc.subject, err)
|
||||
}
|
||||
state.Releases = state.GetReleasesWithLabels()
|
||||
|
||||
rs, err := state.GetSelectedReleases(false)
|
||||
if err != nil {
|
||||
@@ -144,13 +144,13 @@ func TestSelectReleasesWithOverridesWithIncludedTransitives(t *testing.T) {
|
||||
|
||||
testcases := []testcase{
|
||||
{
|
||||
subject: "include transitives",
|
||||
subject: "include transitives is false",
|
||||
selector: []string{"name=serviceA"},
|
||||
want: []string{"serviceA"},
|
||||
includeTransitiveNeeds: false,
|
||||
},
|
||||
{
|
||||
subject: "include transitives",
|
||||
subject: "include transitives is true",
|
||||
selector: []string{"name=serviceA"},
|
||||
want: []string{"serviceA", "serviceB", "serviceC"},
|
||||
includeTransitiveNeeds: true,
|
||||
@@ -184,13 +184,13 @@ func TestSelectReleasesWithOverridesWithIncludedTransitives(t *testing.T) {
|
||||
}.MustLoadState(t, "/helmfile.yaml", "default")
|
||||
|
||||
for _, tc := range testcases {
|
||||
var err error
|
||||
state.Selectors = tc.selector
|
||||
releases, err := state.GetReleasesWithOverrides()
|
||||
state.Releases, err = state.GetReleasesWithOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("%s %s: %v", tc.selector, tc.subject, err)
|
||||
}
|
||||
|
||||
state.Releases = releases
|
||||
state.Releases = state.GetReleasesWithLabels()
|
||||
|
||||
rs, err := state.GetSelectedReleases(tc.includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
|
||||
+40
-29
@@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -208,6 +207,8 @@ type HelmSpec struct {
|
||||
DeleteWait bool `yaml:"deleteWait"`
|
||||
// Timeout is the time in seconds to wait for helmfile delete command (default 300)
|
||||
DeleteTimeout int `yaml:"deleteTimeout"`
|
||||
// SyncReleaseLabels is true if the release labels should be synced with the helmfile labels
|
||||
SyncReleaseLabels bool `yaml:"syncReleaseLabels"`
|
||||
}
|
||||
|
||||
// RepositorySpec that defines values for a helm repo
|
||||
@@ -408,6 +409,8 @@ type ReleaseSpec struct {
|
||||
DeleteWait *bool `yaml:"deleteWait,omitempty"`
|
||||
// Timeout is the time in seconds to wait for helmfile delete command (default 300)
|
||||
DeleteTimeout *int `yaml:"deleteTimeout,omitempty"`
|
||||
// SyncReleaseLabels is true if the release labels should be synced with the helmfile labels
|
||||
SyncReleaseLabels bool `yaml:"syncReleaseLabels"`
|
||||
}
|
||||
|
||||
func (r *Inherits) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
@@ -783,6 +786,7 @@ type SyncOpts struct {
|
||||
Wait bool
|
||||
WaitRetries int
|
||||
WaitForJobs bool
|
||||
SyncReleaseLabels bool
|
||||
ReuseValues bool
|
||||
ResetValues bool
|
||||
PostRenderer string
|
||||
@@ -2262,16 +2266,40 @@ func (st *HelmState) GetReleasesWithOverrides() ([]ReleaseSpec, error) {
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func (st *HelmState) GetReleasesWithLabels() []ReleaseSpec {
|
||||
var rs []ReleaseSpec
|
||||
for _, r := range st.Releases {
|
||||
spec := r
|
||||
labels := map[string]string{}
|
||||
// apply common labels
|
||||
for k, v := range st.CommonLabels {
|
||||
labels[k] = v
|
||||
}
|
||||
for k, v := range spec.Labels {
|
||||
labels[k] = v
|
||||
}
|
||||
// Let the release name, namespace, and chart be used as a tag
|
||||
labels["name"] = r.Name
|
||||
labels["namespace"] = r.Namespace
|
||||
// Strip off just the last portion for the name stable/newrelic would give newrelic
|
||||
chartSplit := strings.Split(r.Chart, "/")
|
||||
labels["chart"] = chartSplit[len(chartSplit)-1]
|
||||
spec.Labels = labels
|
||||
rs = append(rs, spec)
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
||||
func (st *HelmState) SelectReleases(includeTransitiveNeeds bool) ([]Release, error) {
|
||||
values := st.Values()
|
||||
rs, err := markExcludedReleases(st.Releases, st.Selectors, st.CommonLabels, values, includeTransitiveNeeds)
|
||||
rs, err := markExcludedReleases(st.Releases, st.Selectors, values, includeTransitiveNeeds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func markExcludedReleases(releases []ReleaseSpec, selectors []string, commonLabels map[string]string, values map[string]any, includeTransitiveNeeds bool) ([]Release, error) {
|
||||
func markExcludedReleases(releases []ReleaseSpec, selectors []string, values map[string]any, includeTransitiveNeeds bool) ([]Release, error) {
|
||||
var filteredReleases []Release
|
||||
filters := []ReleaseFilter{}
|
||||
for _, label := range selectors {
|
||||
@@ -2282,29 +2310,8 @@ func markExcludedReleases(releases []ReleaseSpec, selectors []string, commonLabe
|
||||
filters = append(filters, f)
|
||||
}
|
||||
for _, r := range releases {
|
||||
orginReleaseLabel := maps.Clone(r.Labels)
|
||||
if r.Labels == nil {
|
||||
r.Labels = map[string]string{}
|
||||
} else {
|
||||
// Make a copy of the labels to avoid mutating the original
|
||||
r.Labels = maps.Clone(r.Labels)
|
||||
}
|
||||
// Let the release name, namespace, and chart be used as a tag
|
||||
r.Labels["name"] = r.Name
|
||||
r.Labels["namespace"] = r.Namespace
|
||||
// Strip off just the last portion for the name stable/newrelic would give newrelic
|
||||
chartSplit := strings.Split(r.Chart, "/")
|
||||
r.Labels["chart"] = chartSplit[len(chartSplit)-1]
|
||||
// Merge CommonLabels into release labels
|
||||
for k, v := range commonLabels {
|
||||
r.Labels[k] = v
|
||||
}
|
||||
|
||||
var filterMatch bool
|
||||
for _, f := range filters {
|
||||
if r.Labels == nil {
|
||||
r.Labels = map[string]string{}
|
||||
}
|
||||
if f.Match(r) {
|
||||
filterMatch = true
|
||||
break
|
||||
@@ -2316,7 +2323,6 @@ func markExcludedReleases(releases []ReleaseSpec, selectors []string, commonLabe
|
||||
return nil, fmt.Errorf("failed to parse condition in release %s: %w", r.Name, err)
|
||||
}
|
||||
// reset the labels to the original
|
||||
r.Labels = orginReleaseLabel
|
||||
res := Release{
|
||||
ReleaseSpec: r,
|
||||
Filtered: (len(filters) > 0 && !filterMatch) || (!conditionMatch),
|
||||
@@ -2776,15 +2782,20 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp
|
||||
flags = append(flags, "--disable-openapi-validation")
|
||||
}
|
||||
|
||||
postRenderer := ""
|
||||
syncReleaseLabels := false
|
||||
if opt != nil {
|
||||
postRenderer = opt.PostRenderer
|
||||
syncReleaseLabels = opt.SyncReleaseLabels
|
||||
}
|
||||
|
||||
flags = st.appendConnectionFlags(flags, release)
|
||||
flags = st.appendChartDownloadFlags(flags, release)
|
||||
|
||||
flags = st.appendHelmXFlags(flags, release)
|
||||
|
||||
postRenderer := ""
|
||||
if opt != nil {
|
||||
postRenderer = opt.PostRenderer
|
||||
}
|
||||
flags = st.appendLabelsFlags(flags, helm, release, syncReleaseLabels)
|
||||
|
||||
flags = st.appendPostRenderFlags(flags, release, postRenderer)
|
||||
|
||||
var postRendererArgs []string
|
||||
|
||||
@@ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) {
|
||||
run(testcase{
|
||||
subject: "baseline",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
want: "foo-values-669d45cd7b",
|
||||
want: "foo-values-6584bf5db7",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different bytes content",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
data: []byte(`{"k":"v"}`),
|
||||
want: "foo-values-67d8c67fcf",
|
||||
want: "foo-values-6b8c446b76",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different map content",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
data: map[string]any{"k": "v"},
|
||||
want: "foo-values-b9bc64677",
|
||||
want: "foo-values-6b499b6fb6",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different chart",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"},
|
||||
want: "foo-values-585c4565f5",
|
||||
want: "foo-values-775cbccfb",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different name",
|
||||
release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"},
|
||||
want: "bar-values-c94846459",
|
||||
want: "bar-values-849dcf78b4",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "specific ns",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"},
|
||||
want: "myns-foo-values-798d69477",
|
||||
want: "myns-foo-values-d57499c58",
|
||||
})
|
||||
|
||||
for id, n := range ids {
|
||||
|
||||
Reference in New Issue
Block a user