From 8beb69d08e440d72486eb4f338f43f8c4b2fc5f7 Mon Sep 17 00:00:00 2001 From: yxxhero Date: Sat, 6 Aug 2022 15:04:34 +0800 Subject: [PATCH 1/6] fix cobra flag default value Signed-off-by: yxxhero --- cmd/apply.go | 4 ++-- cmd/charts.go | 6 +++--- cmd/delete.go | 6 +++--- cmd/deps.go | 4 ++-- cmd/destroy.go | 4 ++-- cmd/diff.go | 6 +++--- cmd/fetch.go | 4 ++-- cmd/lint.go | 8 ++++---- cmd/list.go | 4 ++-- cmd/repos.go | 2 +- cmd/root.go | 30 +++++++++++++++--------------- cmd/status.go | 2 +- cmd/sync.go | 4 ++-- cmd/template.go | 4 ++-- cmd/test.go | 8 ++++---- cmd/write-values.go | 8 ++++---- 16 files changed, 52 insertions(+), 52 deletions(-) diff --git a/cmd/apply.go b/cmd/apply.go index f3bcd74b..8ad850e5 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -30,7 +30,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringSliceVar(&applyImpl.ApplyOptions.Values, "values", []string{}, "additional value files to be merged into the command") + f.StringSliceVar(&applyImpl.ApplyOptions.Values, "values", nil, "additional value files to be merged into the command") f.IntVar(&applyImpl.ApplyOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") f.BoolVar(&applyImpl.ApplyOptions.Validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions") f.IntVar(&applyImpl.ApplyOptions.Context, "context", 0, "output NUM lines of context around changes") @@ -45,7 +45,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.BoolVar(&applyImpl.ApplyOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`) f.BoolVar(&applyImpl.ApplyOptions.SkipDiffOnInstall, "skip-diff-on-install", false, "Skips running helm-diff on releases being newly installed on this apply. Useful when the release manifests are too huge to be reviewed, or it's too time-consuming to diff at all0") f.BoolVar(&applyImpl.ApplyOptions.IncludeTests, "include-tests", false, "enable the diffing of the helm test hooks") - f.StringArrayVar(&applyImpl.ApplyOptions.Suppress, "suppress", []string{}, "suppress specified Kubernetes objects in the diff output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret") + f.StringArrayVar(&applyImpl.ApplyOptions.Suppress, "suppress", nil, "suppress specified Kubernetes objects in the diff output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret") f.BoolVar(&applyImpl.ApplyOptions.SuppressSecrets, "suppress-secrets", false, "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases") f.BoolVar(&applyImpl.ApplyOptions.ShowSecrets, "show-secrets", false, "do not redact secret values in the diff output. should be used for debug purpose only") f.BoolVar(&applyImpl.ApplyOptions.SuppressDiff, "suppress-diff", false, "suppress diff in the output. Usable in new installs") diff --git a/cmd/charts.go b/cmd/charts.go index ee88a384..dd2853c5 100644 --- a/cmd/charts.go +++ b/cmd/charts.go @@ -30,9 +30,9 @@ func NewChartsCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&chartsOptions.Args, "args", chartsOptions.Args, "pass args to helm exec") - f.StringArrayVar(&chartsOptions.Set, "set", chartsOptions.Set, "additional values to be merged into the command") - f.StringArrayVar(&chartsOptions.Values, "values", chartsOptions.Values, "additional value files to be merged into the command") + f.StringVar(&chartsOptions.Args, "args", "", "pass args to helm exec") + f.StringArrayVar(&chartsOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&chartsOptions.Values, "values", nil, "additional value files to be merged into the command") f.IntVar(&chartsOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") return cmd diff --git a/cmd/delete.go b/cmd/delete.go index 7b22ad23..0d8dd940 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -30,10 +30,10 @@ func NewDeleteCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&deleteOptions.Args, "args", deleteOptions.Args, "pass args to helm exec") + f.StringVar(&deleteOptions.Args, "args", "", "pass args to helm exec") f.IntVar(&deleteOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&deleteOptions.Purge, "purge", deleteOptions.Purge, "purge releases i.e. free release names and histories") - f.BoolVar(&deleteOptions.SkipDeps, "skip-deps", deleteOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) + f.BoolVar(&deleteOptions.Purge, "purge", false, "purge releases i.e. free release names and histories") + f.BoolVar(&deleteOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) return cmd } diff --git a/cmd/deps.go b/cmd/deps.go index ab5f2bc4..ac1d1da0 100644 --- a/cmd/deps.go +++ b/cmd/deps.go @@ -30,8 +30,8 @@ func NewDepsCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&depsOptions.Args, "args", depsOptions.Args, "pass args to helm exec") - f.BoolVar(&depsOptions.SkipRepos, "skip-deps", depsOptions.SkipRepos, `skip running "helm repo update" and "helm dependency build"`) + f.StringVar(&depsOptions.Args, "args", "", "pass args to helm exec") + f.BoolVar(&depsOptions.SkipRepos, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) return cmd } diff --git a/cmd/destroy.go b/cmd/destroy.go index a88f36da..b4d86346 100644 --- a/cmd/destroy.go +++ b/cmd/destroy.go @@ -30,9 +30,9 @@ func NewDestroyCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&destroyOptions.Args, "args", destroyOptions.Args, "pass args to helm exec") + f.StringVar(&destroyOptions.Args, "args", "", "pass args to helm exec") f.IntVar(&destroyOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&destroyOptions.SkipDeps, "skip-deps", destroyOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) + f.BoolVar(&destroyOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) return cmd } diff --git a/cmd/diff.go b/cmd/diff.go index 3114ee58..2ce323bf 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -31,8 +31,8 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.StringVar(&diffOptions.Args, "args", "", "pass args to helm diff") - f.StringArrayVar(&diffOptions.Set, "set", []string{}, "additional values to be merged into the command") - f.StringArrayVar(&diffOptions.Values, "values", []string{}, "additional value files to be merged into the command") + f.StringArrayVar(&diffOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&diffOptions.Values, "values", nil, "additional value files to be merged into the command") f.IntVar(&diffOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") f.BoolVar(&diffOptions.Validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the diff of available API versions") f.BoolVar(&diffOptions.SkipNeeds, "skip-needs", false, `do not automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when when --selector/-l flag is not provided. Defaults to true when --include-needs or --include-transitive-needs is not provided`) @@ -46,7 +46,7 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { f.IntVar(&diffOptions.Context, "context", 0, "output NUM lines of context around changes") f.StringVar(&diffOptions.Output, "output", "", "output format for diff plugin") f.BoolVar(&diffOptions.SuppressSecrets, "suppress-secrets", false, "suppress secrets in the output. highly recommended to specify on CI/CD use-cases") - f.StringArrayVar(&diffOptions.Suppress, "suppress", []string{}, "suppress specified Kubernetes objects in the output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret") + f.StringArrayVar(&diffOptions.Suppress, "suppress", nil, "suppress specified Kubernetes objects in the output. Can be provided multiple times. For example: --suppress KeycloakClient --suppress VaultSecret") return cmd } diff --git a/cmd/fetch.go b/cmd/fetch.go index db2a5eb0..66c922e6 100644 --- a/cmd/fetch.go +++ b/cmd/fetch.go @@ -31,8 +31,8 @@ func NewFetchCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&fetchOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited") - f.BoolVar(&fetchOptions.SkipDeps, "skip-deps", fetchOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) - f.StringVar(&fetchOptions.OutputDir, "output-dir", fetchOptions.OutputDir, "directory to store charts (default: temporary directory which is deleted when the command terminates)") + f.BoolVar(&fetchOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) + f.StringVar(&fetchOptions.OutputDir, "output-dir", "", "directory to store charts (default: temporary directory which is deleted when the command terminates)") return cmd } diff --git a/cmd/lint.go b/cmd/lint.go index 99e252eb..f8d4a64f 100644 --- a/cmd/lint.go +++ b/cmd/lint.go @@ -31,10 +31,10 @@ func NewLintCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&lintOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") - f.BoolVar(&lintOptions.SkipDeps, "skip-deps", lintOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) - f.StringVar(&lintOptions.Args, "args", lintOptions.Args, "pass args to helm exec") - f.StringArrayVar(&lintOptions.Set, "set", lintOptions.Set, "additional values to be merged into the command") - f.StringArrayVar(&lintOptions.Values, "values", lintOptions.Values, "additional value files to be merged into the command") + f.BoolVar(&lintOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) + f.StringVar(&lintOptions.Args, "args", "", "pass args to helm exec") + f.StringArrayVar(&lintOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&lintOptions.Values, "values", nil, "additional value files to be merged into the command") return cmd } diff --git a/cmd/list.go b/cmd/list.go index 5b2c7997..4b9197ef 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -30,8 +30,8 @@ func NewListCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.BoolVar(&listOptions.KeepTempDir, "keep-temp-dir", listOptions.KeepTempDir, "Keep temporary directory") - f.StringVar(&listOptions.Output, "output", listOptions.Output, "output releases list as a json string") + f.BoolVar(&listOptions.KeepTempDir, "keep-temp-dir", false, "Keep temporary directory") + f.StringVar(&listOptions.Output, "output", "", "output releases list as a json string") return cmd } diff --git a/cmd/repos.go b/cmd/repos.go index 5cf1fe87..c67300d2 100644 --- a/cmd/repos.go +++ b/cmd/repos.go @@ -30,7 +30,7 @@ func NewReposCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&reposOptions.Args, "args", reposOptions.Args, "pass args to helm exec") + f.StringVar(&reposOptions.Args, "args", "", "pass args to helm exec") return cmd } diff --git a/cmd/root.go b/cmd/root.go index ae6c34dd..e88a0e4d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -103,24 +103,24 @@ func NewRootCmd(globalConfig *config.GlobalOptions, args []string) (*cobra.Comma func setGlobalOptionsForRootCmd(fs *pflag.FlagSet, globalOptions *config.GlobalOptions) { fs.StringVarP(&globalOptions.HelmBinary, "helm-binary", "b", app.DefaultHelmBinary, "Path to the helm binary") - fs.StringVarP(&globalOptions.File, "file", "f", globalOptions.File, "load config from file or directory. defaults to `helmfile.yaml` or `helmfile.d`(means `helmfile.d/*.yaml`) in this preference") - fs.StringVarP(&globalOptions.Environment, "environment", "e", globalOptions.Environment, `specify the environment name. defaults to "default"`) - fs.StringArrayVarP(&globalOptions.StateValuesSet, "state-values-set", "s", globalOptions.StateValuesSet, "set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") - fs.StringArrayVarP(&globalOptions.StateValuesFile, "state-values-file", "", globalOptions.StateValuesFile, "specify state values in a YAML file") - fs.BoolVarP(&globalOptions.Quiet, "quiet", "q", globalOptions.Quiet, "Silence output. Equivalent to log-level warn") - fs.StringVar(&globalOptions.KubeContext, "kube-context", globalOptions.KubeContext, "Set kubectl context. Uses current context by default") - fs.BoolVar(&globalOptions.Debug, "debug", globalOptions.Debug, "Enable verbose output for Helm and set log-level to debug, this disables --quiet/-q effect") - fs.BoolVar(&globalOptions.Color, "color", globalOptions.Color, "Output with color") - fs.BoolVar(&globalOptions.NoColor, "no-color", globalOptions.NoColor, "Output without color") - fs.StringVar(&globalOptions.LogLevel, "log-level", globalOptions.LogLevel, "Set log level, default info") - fs.StringVar(&globalOptions.Namespace, "namespace", globalOptions.Namespace, "Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}") - fs.StringVar(&globalOptions.Chart, "chart", globalOptions.Chart, "Set chart. Uses the chart set in release by default, and is available in template as {{ .Chart }}") - fs.StringArrayVarP(&globalOptions.Selector, "selector", "l", globalOptions.Selector, `Only run using the releases that match labels. Labels can take the form of foo=bar or foo!=bar. + fs.StringVarP(&globalOptions.File, "file", "f", "", "load config from file or directory. defaults to `helmfile.yaml` or `helmfile.d`(means `helmfile.d/*.yaml`) in this preference") + fs.StringVarP(&globalOptions.Environment, "environment", "e", "", `specify the environment name. defaults to "default"`) + fs.StringArrayVarP(&globalOptions.StateValuesSet, "state-values-set", "s", nil, "set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + fs.StringArrayVarP(&globalOptions.StateValuesFile, "state-values-file", "", nil, "specify state values in a YAML file") + fs.BoolVarP(&globalOptions.Quiet, "quiet", "q", false, "Silence output. Equivalent to log-level warn") + fs.StringVar(&globalOptions.KubeContext, "kube-context", "", "Set kubectl context. Uses current context by default") + fs.BoolVar(&globalOptions.Debug, "debug", false, "Enable verbose output for Helm and set log-level to debug, this disables --quiet/-q effect") + fs.BoolVar(&globalOptions.Color, "color", false, "Output with color") + fs.BoolVar(&globalOptions.NoColor, "no-color", false, "Output without color") + fs.StringVar(&globalOptions.LogLevel, "log-level", "info", "Set log level, default info") + fs.StringVar(&globalOptions.Namespace, "namespace", "", "Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}") + fs.StringVar(&globalOptions.Chart, "chart", "", "Set chart. Uses the chart set in release by default, and is available in template as {{ .Chart }}") + fs.StringArrayVarP(&globalOptions.Selector, "selector", "l", nil, `Only run using the releases that match labels. Labels can take the form of foo=bar or foo!=bar. A release must match all labels in a group in order to be used. Multiple groups can be specified at once. --selector tier=frontend,tier!=proxy --selector tier=backend. Will match all frontend, non-proxy releases AND all backend releases. The name of a release can be used as a label. --selector name=myrelease`) - fs.BoolVar(&globalOptions.AllowNoMatchingRelease, "allow-no-matching-release", globalOptions.AllowNoMatchingRelease, `Do not exit with an error code if the provided selector has no matching releases.`) - fs.BoolVarP(&globalOptions.Interactive, "interactive", "i", globalOptions.Interactive, "Request confirmation before attempting to modify clusters") + fs.BoolVar(&globalOptions.AllowNoMatchingRelease, "allow-no-matching-release", false, `Do not exit with an error code if the provided selector has no matching releases.`) + fs.BoolVarP(&globalOptions.Interactive, "interactive", "i", false, "Request confirmation before attempting to modify clusters") // avoid 'pflag: help requested' error (#251) fs.BoolP("help", "h", false, "help for helmfile") } diff --git a/cmd/status.go b/cmd/status.go index 8b30a107..32b5fa79 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -30,7 +30,7 @@ func NewStatusCmd(globalCfg *config.GlobalImpl) *cobra.Command { } f := cmd.Flags() - f.StringVar(&statusOptions.Args, "args", statusOptions.Args, "pass args to helm exec") + f.StringVar(&statusOptions.Args, "args", "", "pass args to helm exec") return cmd } diff --git a/cmd/sync.go b/cmd/sync.go index 7f7a86c3..adc6e920 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -31,8 +31,8 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.StringVar(&syncOptions.Args, "args", "", "pass args to helm sync") - f.StringArrayVar(&syncOptions.Set, "set", []string{}, "additional values to be merged into the command") - f.StringArrayVar(&syncOptions.Values, "values", []string{}, "additional value files to be merged into the command") + f.StringArrayVar(&syncOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&syncOptions.Values, "values", nil, "additional value files to be merged into the command") f.IntVar(&syncOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") f.BoolVar(&syncOptions.Validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the sync of available API versions") f.BoolVar(&syncOptions.SkipNeeds, "skip-needs", false, `do not automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when when --selector/-l flag is not provided. Defaults to true when --include-needs or --include-transitive-needs is not provided`) diff --git a/cmd/template.go b/cmd/template.go index a2d57306..08444fc1 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -31,8 +31,8 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.StringVar(&templateOptions.Args, "args", "", "pass args to helm template") - f.StringArrayVar(&templateOptions.Set, "set", []string{}, "additional values to be merged into the command") - f.StringArrayVar(&templateOptions.Values, "values", []string{}, "additional value files to be merged into the command") + f.StringArrayVar(&templateOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&templateOptions.Values, "values", nil, "additional value files to be merged into the command") f.StringVar(&templateOptions.OutputDir, "output-dir", "", "output directory to pass to helm template (helm template --output-dir)") f.StringVar(&templateOptions.OutputDirTemplate, "output-dir-template", "", "go text template for generating the output directory. Default: {{ .OutputDir }}/{{ .State.BaseName }}-{{ .State.AbsPathSHA1 }}-{{ .Release.Name}}") f.IntVar(&templateOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") diff --git a/cmd/test.go b/cmd/test.go index c4661cc4..91112273 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -32,10 +32,10 @@ func NewTestCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&testOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") - f.BoolVar(&testOptions.SkipDeps, "skip-deps", testOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) - f.BoolVar(&testOptions.Cleanup, "cleanup", testOptions.Cleanup, "delete test pods upon completion") - f.BoolVar(&testOptions.Logs, "logs", testOptions.Logs, "Dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") - f.StringVar(&testOptions.Args, "args", testOptions.Args, "pass args to helm exec") + f.BoolVar(&testOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) + f.BoolVar(&testOptions.Cleanup, "cleanup", false, "delete test pods upon completion") + f.BoolVar(&testOptions.Logs, "logs", false, "Dump the logs from test pods (this runs after all tests are complete, but before any cleanup)") + f.StringVar(&testOptions.Args, "args", "", "pass args to helm exec") f.IntVar(&testOptions.Timeout, "timeout", 300, "maximum time for tests to run before being considered failed") return cmd diff --git a/cmd/write-values.go b/cmd/write-values.go index 393f7196..be44f755 100644 --- a/cmd/write-values.go +++ b/cmd/write-values.go @@ -31,10 +31,10 @@ func NewWriteValuesCmd(globalCfg *config.GlobalImpl) *cobra.Command { f := cmd.Flags() f.IntVar(&writeValuesOptions.Concurrency, "concurrency", 0, "maximum number of concurrent downloads of release charts") - f.BoolVar(&writeValuesOptions.SkipDeps, "skip-deps", writeValuesOptions.SkipDeps, `skip running "helm repo update" and "helm dependency build"`) - f.StringArrayVar(&writeValuesOptions.Set, "set", writeValuesOptions.Set, "additional values to be merged into the command") - f.StringArrayVar(&writeValuesOptions.Values, "values", writeValuesOptions.Values, "additional value files to be merged into the command") - f.StringVar(&writeValuesOptions.OutputFileTemplate, "output-file-template", writeValuesOptions.OutputFileTemplate, "go text template for generating the output file. Default: {{ .State.BaseName }}-{{ .State.AbsPathSHA1 }}/{{ .Release.Name}}.yaml") + f.BoolVar(&writeValuesOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`) + f.StringArrayVar(&writeValuesOptions.Set, "set", nil, "additional values to be merged into the command") + f.StringArrayVar(&writeValuesOptions.Values, "values", nil, "additional value files to be merged into the command") + f.StringVar(&writeValuesOptions.OutputFileTemplate, "output-file-template", "", "go text template for generating the output file. Default: {{ .State.BaseName }}-{{ .State.AbsPathSHA1 }}/{{ .Release.Name}}.yaml") return cmd } From 13bac519d061b2661397a094c4b4dc8509dafe40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 15:35:45 +0000 Subject: [PATCH 2/6] build(deps): bump go.uber.org/zap from 1.21.0 to 1.22.0 Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.21.0 to 1.22.0. - [Release notes](https://github.com/uber-go/zap/releases) - [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md) - [Commits](https://github.com/uber-go/zap/compare/v1.21.0...v1.22.0) --- updated-dependencies: - dependency-name: go.uber.org/zap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6652c7ce..b7601c04 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/variantdev/dag v1.1.0 github.com/variantdev/vals v0.18.0 go.uber.org/multierr v1.6.0 - go.uber.org/zap v1.21.0 + go.uber.org/zap v1.22.0 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index d1655830..7fdfdba5 100644 --- a/go.sum +++ b/go.sum @@ -1331,15 +1331,14 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0= +go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From 6c1b6f855a43ff79f16d3245f5c604457633ee81 Mon Sep 17 00:00:00 2001 From: Vladimir Kuznichenkov Date: Thu, 11 Aug 2022 11:55:09 +0300 Subject: [PATCH 3/6] Add file existence check for remove values If remote file isn't present in repo we will add it anyway to the files list and check `if len(files) == 0 {` never will be true. That leads to missing section with `MissingFileHandler`. That fix check that cloned file actually exists. In that case if we add a link to non-existing remote file `MissingFileHandler` will be called as expected. Signed-off-by: Vladimir Kuznichenkov --- pkg/state/storage.go | 10 ++++- pkg/state/storage_test.go | 91 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 pkg/state/storage_test.go diff --git a/pkg/state/storage.go b/pkg/state/storage.go index df52b8bd..321ad1d2 100644 --- a/pkg/state/storage.go +++ b/pkg/state/storage.go @@ -38,8 +38,14 @@ func (st *Storage) resolveFile(missingFileHandler *string, tpe, path string) ([] if remote.IsRemote(path) { r := remote.NewRemote(st.logger, "", st.readFile, directoryExistsAt, fileExistsAt) - fetchedDir, _ := r.Fetch(path, "values") - files = []string{fetchedDir} + fetchedFilePath, err := r.Fetch(path, "values") + if err != nil { + return nil, false, err + } + + if fileExistsAt(fetchedFilePath) { + files = []string{fetchedFilePath} + } } else { files, err = st.ExpandPaths(path) } diff --git a/pkg/state/storage_test.go b/pkg/state/storage_test.go new file mode 100644 index 00000000..225e1e54 --- /dev/null +++ b/pkg/state/storage_test.go @@ -0,0 +1,91 @@ +package state + +import ( + "fmt" + "os" + "path/filepath" + "reflect" + "testing" + + "github.com/helmfile/helmfile/pkg/helmexec" + "github.com/helmfile/helmfile/pkg/remote" +) + +func TestStorage_resolveFile(t *testing.T) { + type args struct { + missingFileHandler *string + title string + path string + } + + cacheDir := remote.CacheDir() + infoHandler := MissingFileHandlerInfo + errorHandler := MissingFileHandlerError + + tests := []struct { + name string + args args + wantFiles []string + wantSkipped bool + wantErr bool + }{ + { + name: "non existing file in repo produce skip", + args: args{ + path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=v0.145.2", + title: "values", + missingFileHandler: &infoHandler, + }, + wantSkipped: true, + wantErr: false, + }, + { + name: "non existing file in repo produce skip", + args: args{ + path: "git::https://github.com/helmfile/helmfile.git@examples/values/non-existing-file.yaml?ref=v0.145.2", + title: "values", + missingFileHandler: &errorHandler, + }, + wantSkipped: false, + wantErr: true, + }, + { + name: "existing remote value fetched", + args: args{ + path: "git::https://github.com/helmfile/helmfile.git@examples/values/replica-values.yaml?ref=v0.145.2", + title: "values", + missingFileHandler: &infoHandler, + }, + wantFiles: []string{fmt.Sprintf("%s/%s", cacheDir, "values/https_github_com_helmfile_helmfile_git.ref=v0.145.2/examples/values/replica-values.yaml")}, + wantSkipped: false, + wantErr: false, + }, + { + name: "non existing remote repo produce an error", + args: args{ + path: "https://github.com/helmfile/helmfiles.git@examples/values/replica-values.yaml?ref=v0.145.2", + title: "values", + missingFileHandler: &infoHandler, + }, + wantSkipped: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + st := NewStorage(cacheDir, helmexec.NewLogger(os.Stderr, "debug"), filepath.Glob) + + files, skipped, err := st.resolveFile(tt.args.missingFileHandler, tt.args.title, tt.args.path) + if (err != nil) != tt.wantErr { + t.Errorf("resolveFile() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(files, tt.wantFiles) { + t.Errorf("resolveFile() files = %v, want %v", files, tt.wantFiles) + } + if skipped != tt.wantSkipped { + t.Errorf("resolveFile() skipped = %v, want %v", skipped, tt.wantSkipped) + } + }) + } +} From 75aa0e5a21a97f87be8f3a71f417fa8c913d5b3b Mon Sep 17 00:00:00 2001 From: Anatoly Rugalev Date: Sun, 14 Aug 2022 01:46:55 +0200 Subject: [PATCH 4/6] Update ArchLinux installation instructions Signed-off-by: Anatoly Rugalev --- README.md | 8 ++++---- docs/index.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b12cda12..26c85a69 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,10 @@ Note that we will try our best to document any backward incompatibility. And in ## Installation -* download one of [releases](https://github.com/helmfile/helmfile/releases) or -* [run as a container](https://helmfile.readthedocs.io/en/latest/#running-as-a-container) or -* Archlinux: install via `pacman -S helmfile` or from [AUR](https://aur.archlinux.org/packages/kubernetes-helmfile-bin/) or -* openSUSE: install via `zypper in helmfile` assuming you are on Tumbleweed; if you are on Leap you must add the [kubic](https://download.opensuse.org/repositories/devel:/kubic/) repo for your distribution version once before that command, e.g. `zypper ar https://download.opensuse.org/repositories/devel:/kubic/openSUSE_Leap_\$releasever kubic`, or +* download one of [releases](https://github.com/helmfile/helmfile/releases) +* [run as a container](https://helmfile.readthedocs.io/en/latest/#running-as-a-container) +* Archlinux: install via `pacman -S helmfile` +* openSUSE: install via `zypper in helmfile` assuming you are on Tumbleweed; if you are on Leap you must add the [kubic](https://download.opensuse.org/repositories/devel:/kubic/) repo for your distribution version once before that command, e.g. `zypper ar https://download.opensuse.org/repositories/devel:/kubic/openSUSE_Leap_\$releasever kubic` * Windows (using [scoop](https://scoop.sh/)): `scoop install helmfile` * macOS (using [homebrew](https://brew.sh/)): `brew install helmfile` diff --git a/docs/index.md b/docs/index.md index 6426b36d..35172779 100644 --- a/docs/index.md +++ b/docs/index.md @@ -414,10 +414,10 @@ If you wish to treat your enviroment variables as strings always, even if they a ## Installation -- download one of [releases](https://github.com/helmfile/helmfile/tags) or -- [run as a container](#running-as-a-container) or -- Archlinux: install via `pacman -S helmfile` or from [AUR](https://aur.archlinux.org/packages/kubernetes-helmfile-bin/) or -- openSUSE: install via `zypper in helmfile` assuming you are on Tumbleweed; if you are on Leap you must add the [kubic](https://download.opensuse.org/repositories/devel:/kubic/) repo for your distribution version once before that command, e.g. `zypper ar https://download.opensuse.org/repositories/devel:/kubic/openSUSE_Leap_\$releasever kubic`, or +- download one of [releases](https://github.com/helmfile/helmfile/releases) +- [run as a container](https://helmfile.readthedocs.io/en/latest/#running-as-a-container) +- Archlinux: install via `pacman -S helmfile` +- openSUSE: install via `zypper in helmfile` assuming you are on Tumbleweed; if you are on Leap you must add the [kubic](https://download.opensuse.org/repositories/devel:/kubic/) repo for your distribution version once before that command, e.g. `zypper ar https://download.opensuse.org/repositories/devel:/kubic/openSUSE_Leap_\$releasever kubic` - Windows (using [scoop](https://scoop.sh/)): `scoop install helmfile` - macOS (using [homebrew](https://brew.sh/)): `brew install helmfile` From cf94a4edb309493a12d9607a80ce8dfc887f266a Mon Sep 17 00:00:00 2001 From: David Ackroyd Date: Sun, 14 Aug 2022 11:47:47 +1000 Subject: [PATCH 5/6] Fix Inclusion of Releases for Other Environments (#276) Fixing releases being included which do not match the environment requested, which is a regression introduced by #234. The issue remains when Helmfile state values are supplied, which is not a regression and will be addressed separately. Partial resolution for #271 Signed-off-by: David Ackroyd Signed-off-by: David Ackroyd --- pkg/app/app.go | 2 +- pkg/app/app_list_test.go | 249 ++++++++++++++++++ pkg/app/app_test.go | 6 + .../default_environment_includes_all_releases | 199 ++++++++++++++ .../app_list_test/fail_on_unknown_environment | 196 ++++++++++++++ ...ses_for_environment_used_in_multiple_files | 198 ++++++++++++++ ...ases_for_environment_used_in_one_file_only | 197 ++++++++++++++ ...releases_matching_selector_and_environment | 197 ++++++++++++++ 8 files changed, 1243 insertions(+), 1 deletion(-) create mode 100644 pkg/app/app_list_test.go create mode 100644 pkg/app/testdata/app_list_test/default_environment_includes_all_releases create mode 100644 pkg/app/testdata/app_list_test/fail_on_unknown_environment create mode 100644 pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_multiple_files create mode 100644 pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_one_file_only create mode 100644 pkg/app/testdata/app_list_test/list_releases_matching_selector_and_environment diff --git a/pkg/app/app.go b/pkg/app/app.go index 06a7e4cf..e0be9820 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -985,7 +985,7 @@ func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converg envvals = append(envvals, v) } - if a.Set != nil { + if len(a.Set) > 0 { envvals = append(envvals, a.Set) } diff --git a/pkg/app/app_list_test.go b/pkg/app/app_list_test.go new file mode 100644 index 00000000..9b71c958 --- /dev/null +++ b/pkg/app/app_list_test.go @@ -0,0 +1,249 @@ +package app + +import ( + "bufio" + "bytes" + "io" + "path/filepath" + "sync" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + "github.com/variantdev/vals" + + "github.com/helmfile/helmfile/pkg/helmexec" + "github.com/helmfile/helmfile/pkg/testhelper" + "github.com/helmfile/helmfile/pkg/testutil" +) + +func TestListWithEnvironment(t *testing.T) { + type testcase struct { + environment string + ns string + error string + selectors []string + expected string + } + + check := func(t *testing.T, tc testcase) { + t.Helper() + + bs := &bytes.Buffer{} + + func() { + t.Helper() + + logReader, logWriter := io.Pipe() + + logFlushed := &sync.WaitGroup{} + // Ensure all the log is consumed into `bs` by calling `logWriter.Close()` followed by `logFlushed.Wait()` + logFlushed.Add(1) + go func() { + scanner := bufio.NewScanner(logReader) + for scanner.Scan() { + bs.Write(scanner.Bytes()) + bs.WriteString("\n") + } + logFlushed.Done() + }() + + defer func() { + // This is here to avoid data-trace on bytes buffer `bs` to capture logs + if err := logWriter.Close(); err != nil { + panic(err) + } + logFlushed.Wait() + }() + + logger := helmexec.NewLogger(logWriter, "debug") + + valsRuntime, err := vals.New(vals.Options{CacheSize: 32}) + if err != nil { + t.Errorf("unexpected error creating vals runtime: %v", err) + } + + files := map[string]string{ + "/path/to/helmfile.d/helmfile_1.yaml": ` +environments: + development: {} + shared: {} + +releases: +- name: logging + chart: incubator/raw + namespace: kube-system + +- name: kubernetes-external-secrets + chart: incubator/raw + namespace: kube-system + needs: + - kube-system/logging + +- name: external-secrets + chart: incubator/raw + namespace: default + labels: + app: test + needs: + - kube-system/kubernetes-external-secrets + +- name: my-release + chart: incubator/raw + namespace: default + labels: + app: test + needs: + - default/external-secrets + + +# Disabled releases are treated as missing +- name: disabled + chart: incubator/raw + namespace: kube-system + installed: false + +- name: test2 + chart: incubator/raw + needs: + - kube-system/disabled + +- name: test3 + chart: incubator/raw + needs: + - test2 +`, + "/path/to/helmfile.d/helmfile_2.yaml": ` +environments: + test: {} + shared: {} + +repositories: +- name: bitnami + url: https://charts.bitnami.com/bitnami + +releases: +- name: cache + namespace: my-app + chart: bitnami/redis + version: 17.0.7 + labels: + app: test + +- name: database + namespace: my-app + chart: bitnami/postgres + version: 11.6.22 +`, + "/path/to/helmfile.d/helmfile_3.yaml": ` +releases: +- name: global + chart: incubator/raw + namespace: kube-system +`, + } + + app := appWithFs(&App{ + OverrideHelmBinary: DefaultHelmBinary, + glob: filepath.Glob, + abs: filepath.Abs, + OverrideKubeContext: "default", + Env: tc.environment, + Logger: logger, + valsRuntime: valsRuntime, + }, files) + + expectNoCallsToHelm(app) + + if tc.ns != "" { + app.Namespace = tc.ns + } + + if tc.selectors != nil { + app.Selectors = tc.selectors + } + + var listErr error + out := testutil.CaptureStdout(func() { + listErr = app.ListReleases(configImpl{}) + }) + + var gotErr string + if listErr != nil { + gotErr = listErr.Error() + } + + if d := cmp.Diff(tc.error, gotErr); d != "" { + t.Fatalf("unexpected error: want (-), got (+): %s", d) + } + + assert.Equal(t, tc.expected, out) + }() + + testhelper.RequireLog(t, "app_list_test", bs) + } + + 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 +`, + }) + }) + + t.Run("fail on unknown environment", func(t *testing.T) { + check(t, testcase{ + environment: "staging", + error: `err: no releases found that matches specified selector() and environment(staging), in any helmfile`, + }) + }) + + t.Run("list releases matching selector and environment", func(t *testing.T) { + check(t, testcase{ + environment: "development", + selectors: []string{"app=test"}, + 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 +`, + }) + }) + + 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 +`, + }) + }) + + t.Run("filters releases for environment used in multiple files", func(t *testing.T) { + 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 +`, + }) + }) +} diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index f837d5ee..e6f0bde9 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -39,6 +39,12 @@ func appWithFs(app *App, files map[string]string) *App { } func injectFs(app *App, fs *testhelper.TestFs) *App { + if app.Set == nil { + // Consistent behavior with NewGlobalImpl. + // Doesn't really belong here, but simplest place for it until some refactoring happens + app.Set = make(map[string]interface{}) + } + app.readFile = fs.ReadFile app.glob = fs.Glob app.abs = fs.Abs diff --git a/pkg/app/testdata/app_list_test/default_environment_includes_all_releases b/pkg/app/testdata/app_list_test/default_environment_includes_all_releases new file mode 100644 index 00000000..f9682de0 --- /dev/null +++ b/pkg/app/testdata/app_list_test/default_environment_includes_all_releases @@ -0,0 +1,199 @@ +processing file "helmfile_1.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_1.yaml.part.0": inherited=&{default map[] map[]}, overrode= +first-pass uses: &{default map[] map[]} +first-pass rendering output of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +first-pass produced: &{default map[] map[]} +first-pass rendering result of "helmfile_1.yaml.part.0": {default map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +merged environment: &{default map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_2.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_2.yaml.part.0": inherited=&{default map[] map[]}, overrode= +first-pass uses: &{default map[] map[]} +first-pass rendering output of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +first-pass produced: &{default map[] map[]} +first-pass rendering result of "helmfile_2.yaml.part.0": {default map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +merged environment: &{default map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_3.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_3.yaml.part.0": inherited=&{default map[] map[]}, overrode= +first-pass uses: &{default map[] map[]} +first-pass rendering output of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +first-pass produced: &{default map[] map[]} +first-pass rendering result of "helmfile_3.yaml.part.0": {default map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +merged environment: &{default map[] map[]} +changing working directory back to "/path/to" diff --git a/pkg/app/testdata/app_list_test/fail_on_unknown_environment b/pkg/app/testdata/app_list_test/fail_on_unknown_environment new file mode 100644 index 00000000..ca68355a --- /dev/null +++ b/pkg/app/testdata/app_list_test/fail_on_unknown_environment @@ -0,0 +1,196 @@ +processing file "helmfile_1.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_1.yaml.part.0": inherited=&{staging map[] map[]}, overrode= +first-pass uses: &{staging map[] map[]} +first-pass rendering output of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +first-pass produced: &{staging map[] map[]} +first-pass rendering result of "helmfile_1.yaml.part.0": {staging map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +changing working directory back to "/path/to" +processing file "helmfile_2.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_2.yaml.part.0": inherited=&{staging map[] map[]}, overrode= +first-pass uses: &{staging map[] map[]} +first-pass rendering output of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +first-pass produced: &{staging map[] map[]} +first-pass rendering result of "helmfile_2.yaml.part.0": {staging map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +changing working directory back to "/path/to" +processing file "helmfile_3.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_3.yaml.part.0": inherited=&{staging map[] map[]}, overrode= +first-pass uses: &{staging map[] map[]} +first-pass rendering output of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +first-pass produced: &{staging map[] map[]} +first-pass rendering result of "helmfile_3.yaml.part.0": {staging map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +changing working directory back to "/path/to" diff --git a/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_multiple_files b/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_multiple_files new file mode 100644 index 00000000..0202a4b8 --- /dev/null +++ b/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_multiple_files @@ -0,0 +1,198 @@ +processing file "helmfile_1.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_1.yaml.part.0": inherited=&{shared map[] map[]}, overrode= +first-pass uses: &{shared map[] map[]} +first-pass rendering output of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +first-pass produced: &{shared map[] map[]} +first-pass rendering result of "helmfile_1.yaml.part.0": {shared map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +merged environment: &{shared map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_2.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_2.yaml.part.0": inherited=&{shared map[] map[]}, overrode= +first-pass uses: &{shared map[] map[]} +first-pass rendering output of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +first-pass produced: &{shared map[] map[]} +first-pass rendering result of "helmfile_2.yaml.part.0": {shared map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +merged environment: &{shared map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_3.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_3.yaml.part.0": inherited=&{shared map[] map[]}, overrode= +first-pass uses: &{shared map[] map[]} +first-pass rendering output of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +first-pass produced: &{shared map[] map[]} +first-pass rendering result of "helmfile_3.yaml.part.0": {shared map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +changing working directory back to "/path/to" diff --git a/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_one_file_only b/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_one_file_only new file mode 100644 index 00000000..402abbe2 --- /dev/null +++ b/pkg/app/testdata/app_list_test/filters_releases_for_environment_used_in_one_file_only @@ -0,0 +1,197 @@ +processing file "helmfile_1.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_1.yaml.part.0": inherited=&{test map[] map[]}, overrode= +first-pass uses: &{test map[] map[]} +first-pass rendering output of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +first-pass produced: &{test map[] map[]} +first-pass rendering result of "helmfile_1.yaml.part.0": {test map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +changing working directory back to "/path/to" +processing file "helmfile_2.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_2.yaml.part.0": inherited=&{test map[] map[]}, overrode= +first-pass uses: &{test map[] map[]} +first-pass rendering output of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +first-pass produced: &{test map[] map[]} +first-pass rendering result of "helmfile_2.yaml.part.0": {test map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +merged environment: &{test map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_3.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_3.yaml.part.0": inherited=&{test map[] map[]}, overrode= +first-pass uses: &{test map[] map[]} +first-pass rendering output of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +first-pass produced: &{test map[] map[]} +first-pass rendering result of "helmfile_3.yaml.part.0": {test map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +changing working directory back to "/path/to" diff --git a/pkg/app/testdata/app_list_test/list_releases_matching_selector_and_environment b/pkg/app/testdata/app_list_test/list_releases_matching_selector_and_environment new file mode 100644 index 00000000..2d498ce0 --- /dev/null +++ b/pkg/app/testdata/app_list_test/list_releases_matching_selector_and_environment @@ -0,0 +1,197 @@ +processing file "helmfile_1.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_1.yaml.part.0": inherited=&{development map[] map[]}, overrode= +first-pass uses: &{development map[] map[]} +first-pass rendering output of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +first-pass produced: &{development map[] map[]} +first-pass rendering result of "helmfile_1.yaml.part.0": {development map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_1.yaml.part.0": + 0: + 1: environments: + 2: development: {} + 3: shared: {} + 4: + 5: releases: + 6: - name: logging + 7: chart: incubator/raw + 8: namespace: kube-system + 9: +10: - name: kubernetes-external-secrets +11: chart: incubator/raw +12: namespace: kube-system +13: needs: +14: - kube-system/logging +15: +16: - name: external-secrets +17: chart: incubator/raw +18: namespace: default +19: labels: +20: app: test +21: needs: +22: - kube-system/kubernetes-external-secrets +23: +24: - name: my-release +25: chart: incubator/raw +26: namespace: default +27: labels: +28: app: test +29: needs: +30: - default/external-secrets +31: +32: +33: # Disabled releases are treated as missing +34: - name: disabled +35: chart: incubator/raw +36: namespace: kube-system +37: installed: false +38: +39: - name: test2 +40: chart: incubator/raw +41: needs: +42: - kube-system/disabled +43: +44: - name: test3 +45: chart: incubator/raw +46: needs: +47: - test2 +48: + +merged environment: &{development map[] map[]} +changing working directory back to "/path/to" +processing file "helmfile_2.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_2.yaml.part.0": inherited=&{development map[] map[]}, overrode= +first-pass uses: &{development map[] map[]} +first-pass rendering output of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +first-pass produced: &{development map[] map[]} +first-pass rendering result of "helmfile_2.yaml.part.0": {development map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_2.yaml.part.0": + 0: + 1: environments: + 2: test: {} + 3: shared: {} + 4: + 5: repositories: + 6: - name: bitnami + 7: url: https://charts.bitnami.com/bitnami + 8: + 9: releases: +10: - name: cache +11: namespace: my-app +12: chart: bitnami/redis +13: version: 17.0.7 +14: labels: +15: app: test +16: +17: - name: database +18: namespace: my-app +19: chart: bitnami/postgres +20: version: 11.6.22 +21: + +changing working directory back to "/path/to" +processing file "helmfile_3.yaml" in directory "/path/to/helmfile.d" +changing working directory to "/path/to/helmfile.d" +first-pass rendering starting for "helmfile_3.yaml.part.0": inherited=&{development map[] map[]}, overrode= +first-pass uses: &{development map[] map[]} +first-pass rendering output of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +first-pass produced: &{development map[] map[]} +first-pass rendering result of "helmfile_3.yaml.part.0": {development map[] map[]} +vals: +map[] +defaultVals:[] +second-pass rendering result of "helmfile_3.yaml.part.0": + 0: + 1: releases: + 2: - name: global + 3: chart: incubator/raw + 4: namespace: kube-system + 5: + +changing working directory back to "/path/to" From 94b7a6c128e405d0334c1ca9e044b83deb614b7a Mon Sep 17 00:00:00 2001 From: yxxhero <11087727+yxxhero@users.noreply.github.com> Date: Sun, 14 Aug 2022 11:17:02 +0800 Subject: [PATCH 6/6] Cleanup pkg/config/config.go (#287) Signed-off-by: yxxhero Signed-off-by: yxxhero --- cmd/apply.go | 2 +- cmd/build.go | 2 +- cmd/cache.go | 4 +- cmd/charts.go | 2 +- cmd/delete.go | 2 +- cmd/deps.go | 2 +- cmd/destroy.go | 2 +- cmd/diff.go | 2 +- cmd/fetch.go | 2 +- cmd/lint.go | 2 +- cmd/list.go | 2 +- cmd/repos.go | 2 +- cmd/status.go | 2 +- cmd/sync.go | 2 +- cmd/template.go | 2 +- cmd/test.go | 2 +- cmd/write-values.go | 2 +- pkg/config/config.go | 293 +------------------------------------------ 18 files changed, 19 insertions(+), 310 deletions(-) diff --git a/cmd/apply.go b/cmd/apply.go index 7e71482b..ae4f2107 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -15,7 +15,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "apply", Short: "Apply all resources from state file only when there are changes", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(applyImpl.GlobalImpl) + err := config.NewCLIConfigImpl(applyImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/build.go b/cmd/build.go index 44e9cd2e..9981dbdf 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -15,7 +15,7 @@ func NewBuildCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "build", Short: "Build all resources from state file only when there are changes", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(buildImpl.GlobalImpl) + err := config.NewCLIConfigImpl(buildImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/cache.go b/cmd/cache.go index ab7e3bd6..930fcabc 100644 --- a/cmd/cache.go +++ b/cmd/cache.go @@ -11,7 +11,7 @@ func NewCacheInfoSubcommand(cacheImpl *config.CacheImpl) *cobra.Command { Use: "info", Short: "cache info", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(cacheImpl.GlobalImpl) + err := config.NewCLIConfigImpl(cacheImpl.GlobalImpl) if err != nil { return err } @@ -33,7 +33,7 @@ func NewCacheCleanupSubcommand(cacheImpl *config.CacheImpl) *cobra.Command { Use: "cleanup", Short: "clean up cache directory", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(cacheImpl.GlobalImpl) + err := config.NewCLIConfigImpl(cacheImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/charts.go b/cmd/charts.go index 5e9457f7..265d1a36 100644 --- a/cmd/charts.go +++ b/cmd/charts.go @@ -15,7 +15,7 @@ func NewChartsCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "charts", Short: "DEPRECATED: sync releases from state file (helm upgrade --install)", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(chartsImpl.GlobalImpl) + err := config.NewCLIConfigImpl(chartsImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/delete.go b/cmd/delete.go index 89ab2aa8..55f15e8d 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -15,7 +15,7 @@ func NewDeleteCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "delete", Short: "DEPRECATED: delete releases from state file (helm delete)", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(deleteImpl.GlobalImpl) + err := config.NewCLIConfigImpl(deleteImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/deps.go b/cmd/deps.go index 690e4b8d..b87fb187 100644 --- a/cmd/deps.go +++ b/cmd/deps.go @@ -15,7 +15,7 @@ func NewDepsCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "deps", Short: "Update charts based on their requirements", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(depsImpl.GlobalImpl) + err := config.NewCLIConfigImpl(depsImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/destroy.go b/cmd/destroy.go index 523d9706..e5c729c3 100644 --- a/cmd/destroy.go +++ b/cmd/destroy.go @@ -15,7 +15,7 @@ func NewDestroyCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "destroy", Short: "Destroys and then purges releases", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(destroyImpl.GlobalImpl) + err := config.NewCLIConfigImpl(destroyImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/diff.go b/cmd/diff.go index 5633db1e..bc78613f 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -15,7 +15,7 @@ func NewDiffCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "diff", Short: "Diff releases defined in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(diffImpl.GlobalImpl) + err := config.NewCLIConfigImpl(diffImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/fetch.go b/cmd/fetch.go index 8c4bcb0b..3181b7be 100644 --- a/cmd/fetch.go +++ b/cmd/fetch.go @@ -15,7 +15,7 @@ func NewFetchCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "fetch", Short: "Fetch charts from state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(fetchImpl.GlobalImpl) + err := config.NewCLIConfigImpl(fetchImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/lint.go b/cmd/lint.go index 40100a73..742dbc4f 100644 --- a/cmd/lint.go +++ b/cmd/lint.go @@ -15,7 +15,7 @@ func NewLintCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "lint", Short: "Lint charts from state file (helm lint)", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(lintImpl.GlobalImpl) + err := config.NewCLIConfigImpl(lintImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/list.go b/cmd/list.go index 63d1c95b..41bc79f4 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -15,7 +15,7 @@ func NewListCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "list", Short: "List releases defined in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(listImpl.GlobalImpl) + err := config.NewCLIConfigImpl(listImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/repos.go b/cmd/repos.go index 2d3563a6..db85350c 100644 --- a/cmd/repos.go +++ b/cmd/repos.go @@ -15,7 +15,7 @@ func NewReposCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "repos", Short: "Repos releases defined in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(reposImpl.GlobalImpl) + err := config.NewCLIConfigImpl(reposImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/status.go b/cmd/status.go index 1414ce60..0c970ab6 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -15,7 +15,7 @@ func NewStatusCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "status", Short: "Retrieve status of releases in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(statusImpl.GlobalImpl) + err := config.NewCLIConfigImpl(statusImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/sync.go b/cmd/sync.go index 95e7930b..e6147998 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -15,7 +15,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "sync", Short: "Sync releases defined in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(syncImpl.GlobalImpl) + err := config.NewCLIConfigImpl(syncImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/template.go b/cmd/template.go index 384fa305..129994c8 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -15,7 +15,7 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "template", Short: "Template releases defined in state file", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(templateImpl.GlobalImpl) + err := config.NewCLIConfigImpl(templateImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/test.go b/cmd/test.go index efd466b7..177f1cac 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -15,7 +15,7 @@ func NewTestCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "test", Short: "Test charts from state file (helm test)", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(testImpl.GlobalImpl) + err := config.NewCLIConfigImpl(testImpl.GlobalImpl) if err != nil { return err } diff --git a/cmd/write-values.go b/cmd/write-values.go index f00c624d..d9d097b3 100644 --- a/cmd/write-values.go +++ b/cmd/write-values.go @@ -15,7 +15,7 @@ func NewWriteValuesCmd(globalCfg *config.GlobalImpl) *cobra.Command { Use: "write-values", Short: "Write values files for releases. Similar to `helmfile template`, write values files instead of manifests.", RunE: func(cmd *cobra.Command, args []string) error { - err := config.NewUrfaveCliConfigImplIns(writeValuesImpl.GlobalImpl) + err := config.NewCLIConfigImpl(writeValuesImpl.GlobalImpl) if err != nil { return err } diff --git a/pkg/config/config.go b/pkg/config/config.go index 242f3341..f7147a87 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,57 +1,12 @@ package config import ( - "fmt" - "os" "strings" "github.com/helmfile/helmfile/pkg/maputil" - "github.com/helmfile/helmfile/pkg/state" - "github.com/urfave/cli" - "go.uber.org/zap" - "golang.org/x/term" ) -// nolint: golint -type ConfigImpl struct { - c *cli.Context - - set map[string]interface{} -} - -func NewUrfaveCliConfigImpl(c *cli.Context) (ConfigImpl, error) { - if c.NArg() > 0 { - err := cli.ShowAppHelp(c) - if err != nil { - return ConfigImpl{}, err - } - return ConfigImpl{}, fmt.Errorf("err: extraneous arguments: %s", strings.Join(c.Args(), ", ")) - } - - conf := ConfigImpl{ - c: c, - } - - optsSet := c.GlobalStringSlice("state-values-set") - if len(optsSet) > 0 { - set := map[string]interface{}{} - for i := range optsSet { - ops := strings.Split(optsSet[i], ",") - for j := range ops { - op := strings.SplitN(ops[j], "=", 2) - k := maputil.ParseKey(op[0]) - v := op[1] - - maputil.Set(set, k, v) - } - } - conf.set = set - } - - return conf, nil -} - -func NewUrfaveCliConfigImplIns(g *GlobalImpl) error { +func NewCLIConfigImpl(g *GlobalImpl) error { optsSet := g.RawStateValuesSet() if len(optsSet) > 0 { set := map[string]interface{}{} @@ -70,249 +25,3 @@ func NewUrfaveCliConfigImplIns(g *GlobalImpl) error { return nil } - -func (c ConfigImpl) Set() []string { - return c.c.StringSlice("set") -} - -func (c ConfigImpl) SkipRepos() bool { - return c.c.Bool("skip-repos") -} - -func (c ConfigImpl) Wait() bool { - return c.c.Bool("wait") -} - -func (c ConfigImpl) WaitForJobs() bool { - return c.c.Bool("wait-for-jobs") -} - -func (c ConfigImpl) Values() []string { - return c.c.StringSlice("values") -} - -func (c ConfigImpl) Args() string { - args := c.c.String("args") - enableHelmDebug := c.c.GlobalBool("debug") - - if enableHelmDebug { - args = fmt.Sprintf("%s %s", args, "--debug") - } - return args -} - -func (c ConfigImpl) OutputDir() string { - return strings.TrimRight(c.c.String("output-dir"), fmt.Sprintf("%c", os.PathSeparator)) -} - -func (c ConfigImpl) OutputDirTemplate() string { - return c.c.String("output-dir-template") -} - -func (c ConfigImpl) OutputFileTemplate() string { - return c.c.String("output-file-template") -} - -func (c ConfigImpl) Validate() bool { - return c.c.Bool("validate") -} - -func (c ConfigImpl) Concurrency() int { - return c.c.Int("concurrency") -} - -func (c ConfigImpl) HasCommandName(name string) bool { - return c.c.Command.HasName(name) -} - -func (c ConfigImpl) SkipNeeds() bool { - if !c.IncludeNeeds() { - return c.c.Bool("skip-needs") - } - - return false -} - -func (c ConfigImpl) IncludeNeeds() bool { - return c.c.Bool("include-needs") || c.IncludeTransitiveNeeds() -} - -func (c ConfigImpl) IncludeTransitiveNeeds() bool { - return c.c.Bool("include-transitive-needs") -} - -// DiffConfig - -func (c ConfigImpl) SkipDeps() bool { - return c.c.Bool("skip-deps") -} - -func (c ConfigImpl) DetailedExitcode() bool { - return c.c.Bool("detailed-exitcode") -} - -func (c ConfigImpl) RetainValuesFiles() bool { - return c.c.Bool("retain-values-files") -} - -func (c ConfigImpl) IncludeTests() bool { - return c.c.Bool("include-tests") -} - -func (c ConfigImpl) Suppress() []string { - return c.c.StringSlice("suppress") -} - -func (c ConfigImpl) SuppressSecrets() bool { - return c.c.Bool("suppress-secrets") -} - -func (c ConfigImpl) ShowSecrets() bool { - return c.c.Bool("show-secrets") -} - -func (c ConfigImpl) SuppressDiff() bool { - return c.c.Bool("suppress-diff") -} - -// DeleteConfig - -func (c ConfigImpl) Purge() bool { - return c.c.Bool("purge") -} - -// TestConfig - -func (c ConfigImpl) Cleanup() bool { - return c.c.Bool("cleanup") -} - -func (c ConfigImpl) Logs() bool { - return c.c.Bool("logs") -} - -func (c ConfigImpl) Timeout() int { - if !c.c.IsSet("timeout") { - return state.EmptyTimeout - } - return c.c.Int("timeout") -} - -// ListConfig - -func (c ConfigImpl) Output() string { - return c.c.String("output") -} - -func (c ConfigImpl) KeepTempDir() bool { - return c.c.Bool("keep-temp-dir") -} - -// GlobalConfig - -func (c ConfigImpl) HelmBinary() string { - return c.c.GlobalString("helm-binary") -} - -func (c ConfigImpl) KubeContext() string { - return c.c.GlobalString("kube-context") -} - -func (c ConfigImpl) Namespace() string { - return c.c.GlobalString("namespace") -} - -func (c ConfigImpl) Chart() string { - return c.c.GlobalString("chart") -} - -func (c ConfigImpl) FileOrDir() string { - return c.c.GlobalString("file") -} - -func (c ConfigImpl) Selectors() []string { - return c.c.GlobalStringSlice("selector") -} - -func (c ConfigImpl) StateValuesSet() map[string]interface{} { - return c.set -} - -func (c ConfigImpl) StateValuesFiles() []string { - return c.c.GlobalStringSlice("state-values-file") -} - -func (c ConfigImpl) Interactive() bool { - return c.c.GlobalBool("interactive") -} - -func (c ConfigImpl) Color() bool { - if c := c.c.GlobalBool("color"); c { - return c - } - - if c.NoColor() { - return false - } - - // We replicate the helm-diff behavior in helmfile - // because when when helmfile calls helm-diff, helm-diff has no access to term and therefore - // we can't rely on helm-diff's ability to auto-detect term for color output. - // See https://github.com/roboll/helmfile/issues/2043 - - terminal := term.IsTerminal(int(os.Stdout.Fd())) - // https://github.com/databus23/helm-diff/issues/281 - dumb := os.Getenv("TERM") == "dumb" - return terminal && !dumb -} - -func (c ConfigImpl) NoColor() bool { - return c.c.GlobalBool("no-color") -} - -func (c ConfigImpl) Context() int { - return c.c.Int("context") -} - -func (c ConfigImpl) DiffOutput() string { - return c.c.String("output") -} - -func (c ConfigImpl) SkipCleanup() bool { - return c.c.Bool("skip-cleanup") -} - -func (c ConfigImpl) SkipCRDs() bool { - return c.c.Bool("skip-crds") -} - -func (c ConfigImpl) SkipDiffOnInstall() bool { - return c.c.Bool("skip-diff-on-install") -} - -func (c ConfigImpl) EmbedValues() bool { - return c.c.Bool("embed-values") -} - -func (c ConfigImpl) IncludeCRDs() bool { - return c.c.Bool("include-crds") -} - -func (c ConfigImpl) SkipTests() bool { - return c.c.Bool("skip-tests") -} - -func (c ConfigImpl) Logger() *zap.SugaredLogger { - return c.c.App.Metadata["logger"].(*zap.SugaredLogger) -} - -func (c ConfigImpl) Env() string { - env := c.c.GlobalString("environment") - if env == "" { - env = os.Getenv("HELMFILE_ENVIRONMENT") - if env == "" { - env = state.DefaultEnv - } - } - return env -}