From 22ad21c1ae6aa542d40f0049c7eb965f0d0853cb Mon Sep 17 00:00:00 2001 From: yxxhero <11087727+yxxhero@users.noreply.github.com> Date: Sat, 11 Jan 2025 22:41:10 +0800 Subject: [PATCH] feat: add --take-ownership flag to apply and sync commands (#1863) Signed-off-by: yxxhero --- cmd/apply.go | 1 + cmd/sync.go | 1 + pkg/app/app.go | 2 ++ pkg/app/app_test.go | 5 +++++ pkg/app/config.go | 2 ++ pkg/config/apply.go | 9 +++++++++ pkg/config/sync.go | 8 ++++++++ pkg/state/helmx.go | 13 ++++++++++++ pkg/state/helmx_test.go | 45 +++++++++++++++++++++++++++++++++++++++++ pkg/state/state.go | 4 ++++ 10 files changed, 90 insertions(+) diff --git a/cmd/apply.go b/cmd/apply.go index b019e6f2..9e6cfa47 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -62,6 +62,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&applyOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the diff output. should be used for debug purpose only") f.BoolVar(&applyOptions.NoHooks, "no-hooks", false, "do not diff changes made by hooks.") f.BoolVar(&applyOptions.HideNotes, "hide-notes", false, "add --hide-notes flag to helm") + f.BoolVar(&applyOptions.TakeOwnership, "take-ownership", false, "add --take-ownership flag to helm") f.BoolVar(&applyOptions.SuppressDiff, "suppress-diff", false, "suppress diff in the output. Usable in new installs") f.BoolVar(&applyOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&applyOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) diff --git a/cmd/sync.go b/cmd/sync.go index ae2af7fc..418bf32c 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -42,6 +42,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&syncOptions.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(&syncOptions.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(&syncOptions.HideNotes, "hide-notes", false, "add --hide-notes flag to helm") + f.BoolVar(&syncOptions.TakeOwnership, "take-ownership", false, `add --take-ownership flag to helm`) f.BoolVar(&syncOptions.Wait, "wait", false, `Override helmDefaults.wait setting "helm upgrade --install --wait"`) f.BoolVar(&syncOptions.WaitForJobs, "wait-for-jobs", false, `Override helmDefaults.waitForJobs setting "helm upgrade --install --wait-for-jobs"`) f.BoolVar(&syncOptions.ReuseValues, "reuse-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reuse-values"`) diff --git a/pkg/app/app.go b/pkg/app/app.go index a99e79fa..7991c144 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1550,6 +1550,7 @@ Do you really want to apply? SkipSchemaValidation: c.SkipSchemaValidation(), SyncArgs: c.SyncArgs(), HideNotes: c.HideNotes(), + TakeOwnership: c.TakeOwnership(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) })) @@ -1945,6 +1946,7 @@ Do you really want to sync? PostRendererArgs: c.PostRendererArgs(), SyncArgs: c.SyncArgs(), HideNotes: c.HideNotes(), + TakeOwnership: c.TakeOwnership(), } return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) })) diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 21860443..b6198f38 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2248,6 +2248,7 @@ type applyConfig struct { suppressOutputLineRegex []string showOnly []string hideNotes bool + takeOwnership bool // template-only options includeCRDs, skipTests bool @@ -2440,6 +2441,10 @@ func (a applyConfig) HideNotes() bool { return a.hideNotes } +func (a applyConfig) TakeOwnership() bool { + return a.takeOwnership +} + type depsConfig struct { skipRepos bool includeTransitiveNeeds bool diff --git a/pkg/app/config.go b/pkg/app/config.go index d52feabe..bb76811a 100644 --- a/pkg/app/config.go +++ b/pkg/app/config.go @@ -54,6 +54,7 @@ type ApplyConfigProvider interface { SkipSchemaValidation() bool Cascade() string HideNotes() bool + TakeOwnership() bool SuppressOutputLineRegex() []string Values() []string @@ -103,6 +104,7 @@ type SyncConfigProvider interface { PostRenderer() string PostRendererArgs() []string HideNotes() bool + TakeOwnership() bool Cascade() string Values() []string diff --git a/pkg/config/apply.go b/pkg/config/apply.go index fdb157e0..4d67aa61 100644 --- a/pkg/config/apply.go +++ b/pkg/config/apply.go @@ -70,6 +70,9 @@ type ApplyOptions struct { SyncArgs string // HideNotes is the hide notes flag HideNotes bool + + // TakeOwnership is true if the ownership should be taken + TakeOwnership bool } // NewApply creates a new Apply @@ -257,6 +260,12 @@ func (a *ApplyImpl) SyncArgs() string { return a.ApplyOptions.SyncArgs } +// HideNotes returns the HideNotes. func (a *ApplyImpl) HideNotes() bool { return a.ApplyOptions.HideNotes } + +// TakeOwnership returns the TakeOwnership. +func (a *ApplyImpl) TakeOwnership() bool { + return a.ApplyOptions.TakeOwnership +} diff --git a/pkg/config/sync.go b/pkg/config/sync.go index 1ee69e5c..c8927b72 100644 --- a/pkg/config/sync.go +++ b/pkg/config/sync.go @@ -38,6 +38,8 @@ type SyncOptions struct { SyncArgs string // HideNotes is the hide notes flag HideNotes bool + // TakeOwnership is the take ownership flag + TakeOwnership bool } // NewSyncOptions creates a new Apply @@ -149,6 +151,12 @@ func (t *SyncImpl) SyncArgs() string { return t.SyncOptions.SyncArgs } +// HideNotes returns the hide notes func (t *SyncImpl) HideNotes() bool { return t.SyncOptions.HideNotes } + +// TakeOwnership returns the take ownership +func (t *SyncImpl) TakeOwnership() bool { + return t.SyncOptions.TakeOwnership +} diff --git a/pkg/state/helmx.go b/pkg/state/helmx.go index bf584e34..e03a095a 100644 --- a/pkg/state/helmx.go +++ b/pkg/state/helmx.go @@ -148,6 +148,19 @@ func (st *HelmState) appendHideNotesFlags(flags []string, helm helmexec.Interfac return flags } +// append take-ownership flags to helm flags +func (st *HelmState) appendTakeOwnershipFlags(flags []string, helm helmexec.Interface, ops *SyncOpts) []string { + // see https://github.com/helm/helm/releases/tag/v3.17.0 + if !helm.IsVersionAtLeast("3.17.0") { + return flags + } + switch { + case ops.HideNotes: + flags = append(flags, "--take-ownership") + } + return flags +} + // append show-only flags to helm flags func (st *HelmState) appendShowOnlyFlags(flags []string, showOnly []string) []string { showOnlyFlags := []string{} diff --git a/pkg/state/helmx_test.go b/pkg/state/helmx_test.go index fae63bfc..77e91203 100644 --- a/pkg/state/helmx_test.go +++ b/pkg/state/helmx_test.go @@ -321,3 +321,48 @@ func TestAppendHideNotesFlags(t *testing.T) { }) } } + +func TestAppendTakeOwnershipFlags(t *testing.T) { + type args struct { + flags []string + helm helmexec.Interface + helmSpec HelmSpec + opt *SyncOpts + expected []string + } + tests := []struct { + name string + args args + }{ + { + name: "no take-ownership when helm less than 3.17.0", + args: args{ + flags: []string{}, + helm: testutil.NewVersionHelmExec("3.16.0"), + opt: &SyncOpts{ + HideNotes: true, + }, + expected: []string{}, + }, + }, + { + name: "hide-notes from cmd flag", + args: args{ + flags: []string{}, + helm: testutil.NewVersionHelmExec("3.17.0"), + opt: &SyncOpts{ + HideNotes: true, + }, + expected: []string{"--take-ownership"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + st := &HelmState{} + st.HelmDefaults = tt.args.helmSpec + got := st.appendTakeOwnershipFlags(tt.args.flags, tt.args.helm, tt.args.opt) + require.Equalf(t, tt.args.expected, got, "appendTakeOwnershipFlags() = %v, want %v", got, tt.args.expected) + }) + } +} diff --git a/pkg/state/state.go b/pkg/state/state.go index 61ac599b..9c501774 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -789,6 +789,7 @@ type SyncOpts struct { PostRendererArgs []string SyncArgs string HideNotes bool + TakeOwnership bool } type SyncOpt interface{ Apply(*SyncOpts) } @@ -2775,6 +2776,9 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp // append hide-notes flag flags = st.appendHideNotesFlags(flags, helm, opt) + // append take-ownership flag + flags = st.appendTakeOwnershipFlags(flags, helm, opt) + flags = st.appendExtraSyncFlags(flags, opt) common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex)