Add the SyncArgs option and --sync-args flag (#1375)
* add the SyncArgs option Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add syncArgs to helmDefaults and update index.md Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add --sync-args flags to helmfile sync Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> * add tests for appendExtraDiffFlags and appendExtraSyncFlags Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --------- Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									dc2ccd6e67
								
							
						
					
					
						commit
						7ccacb7ee5
					
				|  | @ -42,6 +42,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { | ||||||
| 	f.BoolVar(&applyOptions.DetailedExitcode, "detailed-exitcode", false, "return a non-zero exit code 2 instead of 0 when there were changes detected AND the changes are synced successfully") | 	f.BoolVar(&applyOptions.DetailedExitcode, "detailed-exitcode", false, "return a non-zero exit code 2 instead of 0 when there were changes detected AND the changes are synced successfully") | ||||||
| 	f.BoolVar(&applyOptions.StripTrailingCR, "strip-trailing-cr", false, "strip trailing carriage return on input") | 	f.BoolVar(&applyOptions.StripTrailingCR, "strip-trailing-cr", false, "strip trailing carriage return on input") | ||||||
| 	f.StringVar(&applyOptions.DiffArgs, "diff-args", "", `pass args to helm helm-diff`) | 	f.StringVar(&applyOptions.DiffArgs, "diff-args", "", `pass args to helm helm-diff`) | ||||||
|  | 	f.StringVar(&applyOptions.SyncArgs, "sync-args", "", `pass args to helm upgrade`) | ||||||
| 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") | 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm exec") | ||||||
| 	if !runtime.V1Mode { | 	if !runtime.V1Mode { | ||||||
| 		// TODO: Remove this function once Helmfile v0.x
 | 		// TODO: Remove this function once Helmfile v0.x
 | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { | ||||||
| 
 | 
 | ||||||
| 	f := cmd.Flags() | 	f := cmd.Flags() | ||||||
| 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm sync") | 	f.StringVar(&globalCfg.GlobalOptions.Args, "args", "", "pass args to helm sync") | ||||||
|  | 	f.StringVar(&syncOptions.SyncArgs, "sync-args", "", "pass args to helm upgrade") | ||||||
| 	f.StringArrayVar(&syncOptions.Set, "set", nil, "additional values to be merged into the helm command --set flag") | 	f.StringArrayVar(&syncOptions.Set, "set", nil, "additional values to be merged into the helm command --set flag") | ||||||
| 	f.StringArrayVar(&syncOptions.Values, "values", nil, "additional value files to be merged into the helm command --values flag") | 	f.StringArrayVar(&syncOptions.Values, "values", nil, "additional value files to be merged into the helm command --values flag") | ||||||
| 	f.IntVar(&syncOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") | 	f.IntVar(&syncOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") | ||||||
|  |  | ||||||
|  | @ -184,6 +184,8 @@ helmDefaults: | ||||||
|     - "--set k=v" |     - "--set k=v" | ||||||
|   diffArgs: |   diffArgs: | ||||||
|     - "--suppress-secrets" |     - "--suppress-secrets" | ||||||
|  |   syncArgs: | ||||||
|  |     - "--labels=app.kubernetes.io/managed-by=helmfile" | ||||||
|   # verify the chart before upgrading (only works with packaged charts not directories) (default false) |   # verify the chart before upgrading (only works with packaged charts not directories) (default false) | ||||||
|   verify: true |   verify: true | ||||||
|   keyring: path/to/keyring.gpg |   keyring: path/to/keyring.gpg | ||||||
|  |  | ||||||
|  | @ -1476,6 +1476,7 @@ Do you really want to apply? | ||||||
| 					ResetValues:      c.ResetValues(), | 					ResetValues:      c.ResetValues(), | ||||||
| 					PostRenderer:     c.PostRenderer(), | 					PostRenderer:     c.PostRenderer(), | ||||||
| 					PostRendererArgs: c.PostRendererArgs(), | 					PostRendererArgs: c.PostRendererArgs(), | ||||||
|  | 					SyncArgs:         c.SyncArgs(), | ||||||
| 				} | 				} | ||||||
| 				return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) | 				return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) | ||||||
| 			})) | 			})) | ||||||
|  | @ -1869,6 +1870,7 @@ Do you really want to sync? | ||||||
| 					ResetValues:      c.ResetValues(), | 					ResetValues:      c.ResetValues(), | ||||||
| 					PostRenderer:     c.PostRenderer(), | 					PostRenderer:     c.PostRenderer(), | ||||||
| 					PostRendererArgs: c.PostRendererArgs(), | 					PostRendererArgs: c.PostRendererArgs(), | ||||||
|  | 					SyncArgs:         c.SyncArgs(), | ||||||
| 				} | 				} | ||||||
| 				return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) | 				return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) | ||||||
| 			})) | 			})) | ||||||
|  |  | ||||||
|  | @ -2220,6 +2220,7 @@ type applyConfig struct { | ||||||
| 	stripTrailingCR         bool | 	stripTrailingCR         bool | ||||||
| 	interactive             bool | 	interactive             bool | ||||||
| 	skipDiffOnInstall       bool | 	skipDiffOnInstall       bool | ||||||
|  | 	syncArgs                string | ||||||
| 	diffArgs                string | 	diffArgs                string | ||||||
| 	logger                  *zap.SugaredLogger | 	logger                  *zap.SugaredLogger | ||||||
| 	wait                    bool | 	wait                    bool | ||||||
|  | @ -2356,6 +2357,10 @@ func (a applyConfig) SkipDiffOnInstall() bool { | ||||||
| 	return a.skipDiffOnInstall | 	return a.skipDiffOnInstall | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (a applyConfig) SyncArgs() string { | ||||||
|  | 	return a.syncArgs | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (a applyConfig) DiffArgs() string { | func (a applyConfig) DiffArgs() string { | ||||||
| 	return a.diffArgs | 	return a.diffArgs | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -83,6 +83,7 @@ type ApplyConfigProvider interface { | ||||||
| 	SkipDiffOnInstall() bool | 	SkipDiffOnInstall() bool | ||||||
| 
 | 
 | ||||||
| 	DiffArgs() string | 	DiffArgs() string | ||||||
|  | 	SyncArgs() string | ||||||
| 
 | 
 | ||||||
| 	DAGConfig | 	DAGConfig | ||||||
| 
 | 
 | ||||||
|  | @ -104,6 +105,7 @@ type SyncConfigProvider interface { | ||||||
| 	SkipDeps() bool | 	SkipDeps() bool | ||||||
| 	Wait() bool | 	Wait() bool | ||||||
| 	WaitForJobs() bool | 	WaitForJobs() bool | ||||||
|  | 	SyncArgs() string | ||||||
| 
 | 
 | ||||||
| 	Validate() bool | 	Validate() bool | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -64,6 +64,8 @@ type ApplyOptions struct { | ||||||
| 	Cascade string | 	Cascade string | ||||||
| 	// SuppressOutputLineRegex is a list of regexes to suppress output lines
 | 	// SuppressOutputLineRegex is a list of regexes to suppress output lines
 | ||||||
| 	SuppressOutputLineRegex []string | 	SuppressOutputLineRegex []string | ||||||
|  | 	// SyncArgs is the list of arguments to pass to helm upgrade.
 | ||||||
|  | 	SyncArgs string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewApply creates a new Apply
 | // NewApply creates a new Apply
 | ||||||
|  | @ -240,3 +242,8 @@ func (a *ApplyImpl) Cascade() string { | ||||||
| func (a *ApplyImpl) SuppressOutputLineRegex() []string { | func (a *ApplyImpl) SuppressOutputLineRegex() []string { | ||||||
| 	return a.ApplyOptions.SuppressOutputLineRegex | 	return a.ApplyOptions.SuppressOutputLineRegex | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // SyncArgs returns the SyncArgs.
 | ||||||
|  | func (a *ApplyImpl) SyncArgs() string { | ||||||
|  | 	return a.ApplyOptions.SyncArgs | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ type SyncOptions struct { | ||||||
| 	PostRendererArgs []string | 	PostRendererArgs []string | ||||||
| 	// Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background
 | 	// Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background
 | ||||||
| 	Cascade string | 	Cascade string | ||||||
|  | 	// SyncArgs is the list of arguments to pass to the helm upgrade command.
 | ||||||
|  | 	SyncArgs string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewSyncOptions creates a new Apply
 | // NewSyncOptions creates a new Apply
 | ||||||
|  | @ -132,3 +134,8 @@ func (t *SyncImpl) PostRendererArgs() []string { | ||||||
| func (t *SyncImpl) Cascade() string { | func (t *SyncImpl) Cascade() string { | ||||||
| 	return t.SyncOptions.Cascade | 	return t.SyncOptions.Cascade | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // SyncArgs returns the sync args
 | ||||||
|  | func (t *SyncImpl) SyncArgs() string { | ||||||
|  | 	return t.SyncOptions.SyncArgs | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -152,6 +152,7 @@ type HelmSpec struct { | ||||||
| 	KubeContext string   `yaml:"kubeContext,omitempty"` | 	KubeContext string   `yaml:"kubeContext,omitempty"` | ||||||
| 	Args        []string `yaml:"args,omitempty"` | 	Args        []string `yaml:"args,omitempty"` | ||||||
| 	DiffArgs    []string `yaml:"diffArgs,omitempty"` | 	DiffArgs    []string `yaml:"diffArgs,omitempty"` | ||||||
|  | 	SyncArgs    []string `yaml:"syncArgs,omitempty"` | ||||||
| 	Verify      bool     `yaml:"verify"` | 	Verify      bool     `yaml:"verify"` | ||||||
| 	Keyring     string   `yaml:"keyring,omitempty"` | 	Keyring     string   `yaml:"keyring,omitempty"` | ||||||
| 	// EnableDNS, when set to true, enable DNS lookups when rendering templates
 | 	// EnableDNS, when set to true, enable DNS lookups when rendering templates
 | ||||||
|  | @ -740,6 +741,7 @@ type SyncOpts struct { | ||||||
| 	ResetValues      bool | 	ResetValues      bool | ||||||
| 	PostRenderer     string | 	PostRenderer     string | ||||||
| 	PostRendererArgs []string | 	PostRendererArgs []string | ||||||
|  | 	SyncArgs         string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type SyncOpt interface{ Apply(*SyncOpts) } | type SyncOpt interface{ Apply(*SyncOpts) } | ||||||
|  | @ -2517,6 +2519,20 @@ func (st *HelmState) appendExtraDiffFlags(flags []string, opt *DiffOpts) []strin | ||||||
| 	return flags | 	return flags | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // appendExtraSyncFlags appends extra diff flags to the given flags slice based on the provided options.
 | ||||||
|  | // If opt is not nil and opt.SyncArgs is not empty, it collects the arguments from opt.SyncArgs and appends them to flags.
 | ||||||
|  | // If st.HelmDefaults.SyncArgs is not nil, it joins the arguments with a space and appends them to flags.
 | ||||||
|  | // The updated flags slice is returned.
 | ||||||
|  | func (st *HelmState) appendExtraSyncFlags(flags []string, opt *SyncOpts) []string { | ||||||
|  | 	switch { | ||||||
|  | 	case opt != nil && opt.SyncArgs != "": | ||||||
|  | 		flags = append(flags, argparser.CollectArgs(opt.SyncArgs)...) | ||||||
|  | 	case st.HelmDefaults.SyncArgs != nil: | ||||||
|  | 		flags = append(flags, argparser.CollectArgs(strings.Join(st.HelmDefaults.SyncArgs, " "))...) | ||||||
|  | 	} | ||||||
|  | 	return flags | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // appendKeyringFlags append all the helm command-line flags related to keyring
 | // appendKeyringFlags append all the helm command-line flags related to keyring
 | ||||||
| func (st *HelmState) appendKeyringFlags(flags []string, release *ReleaseSpec) []string { | func (st *HelmState) appendKeyringFlags(flags []string, release *ReleaseSpec) []string { | ||||||
| 	switch { | 	switch { | ||||||
|  | @ -2633,6 +2649,8 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp | ||||||
| 	} | 	} | ||||||
| 	flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) | 	flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) | ||||||
| 
 | 
 | ||||||
|  | 	flags = st.appendExtraSyncFlags(flags, opt) | ||||||
|  | 
 | ||||||
| 	common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex) | 	common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, clean, err | 		return nil, clean, err | ||||||
|  |  | ||||||
|  | @ -3477,3 +3477,99 @@ func TestHideChartURL(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func Test_appendExtraDiffFlags(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name          string | ||||||
|  | 		inputFlags    []string | ||||||
|  | 		inputOpts     *DiffOpts | ||||||
|  | 		inputDefaults []string | ||||||
|  | 
 | ||||||
|  | 		expected []string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:       "Skipping default flags, because diffOpts is provided", | ||||||
|  | 			inputFlags: []string{"aaaaa"}, | ||||||
|  | 			inputOpts: &DiffOpts{ | ||||||
|  | 				DiffArgs: "-bbbb --cccc", | ||||||
|  | 			}, | ||||||
|  | 			inputDefaults: []string{"-dddd", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-bbbb", "--cccc"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "Use default flags, because diffOpts is not provided", | ||||||
|  | 			inputFlags:    []string{"aaaaa"}, | ||||||
|  | 			inputDefaults: []string{"-dddd", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-dddd", "--eeee"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "Don't add non-flag arguments", | ||||||
|  | 			inputFlags:    []string{"aaaaa"}, | ||||||
|  | 			inputDefaults: []string{"-d=ddd", "non-flag", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-d=ddd", "--eeee"}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, test := range tests { | ||||||
|  | 		t.Run(test.name, func(t *testing.T) { | ||||||
|  | 			result := (&HelmState{ | ||||||
|  | 				ReleaseSetSpec: ReleaseSetSpec{ | ||||||
|  | 					HelmDefaults: HelmSpec{ | ||||||
|  | 						DiffArgs: test.inputDefaults, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}).appendExtraDiffFlags(test.inputFlags, test.inputOpts) | ||||||
|  | 			if !reflect.DeepEqual(result, test.expected) { | ||||||
|  | 				t.Errorf("For input %v %v, expected %v, but got %v", test.inputFlags, test.inputOpts, test.expected, result) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Test_appendExtraSyncFlags(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name          string | ||||||
|  | 		inputFlags    []string | ||||||
|  | 		inputOpts     *SyncOpts | ||||||
|  | 		inputDefaults []string | ||||||
|  | 
 | ||||||
|  | 		expected []string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:       "Skipping default flags, because diffOpts is provided", | ||||||
|  | 			inputFlags: []string{"aaaaa"}, | ||||||
|  | 			inputOpts: &SyncOpts{ | ||||||
|  | 				SyncArgs: "-bbbb --cccc", | ||||||
|  | 			}, | ||||||
|  | 			inputDefaults: []string{"-dddd", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-bbbb", "--cccc"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "Use default flags, because diffOpts is not provided", | ||||||
|  | 			inputFlags:    []string{"aaaaa"}, | ||||||
|  | 			inputDefaults: []string{"-dddd", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-dddd", "--eeee"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "Don't add non-flag arguments", | ||||||
|  | 			inputFlags:    []string{"aaaaa"}, | ||||||
|  | 			inputDefaults: []string{"-d=ddd", "non-flag", "--eeee"}, | ||||||
|  | 			expected:      []string{"aaaaa", "-d=ddd", "--eeee"}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, test := range tests { | ||||||
|  | 		t.Run(test.name, func(t *testing.T) { | ||||||
|  | 			result := (&HelmState{ | ||||||
|  | 				ReleaseSetSpec: ReleaseSetSpec{ | ||||||
|  | 					HelmDefaults: HelmSpec{ | ||||||
|  | 						SyncArgs: test.inputDefaults, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}).appendExtraSyncFlags(test.inputFlags, test.inputOpts) | ||||||
|  | 			if !reflect.DeepEqual(result, test.expected) { | ||||||
|  | 				t.Errorf("For input %v %v, expected %v, but got %v", test.inputFlags, test.inputOpts, test.expected, result) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue