diff --git a/cmd/root.go b/cmd/root.go index eda150de..c47f8688 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -141,7 +141,7 @@ func setGlobalOptionsForRootCmd(fs *pflag.FlagSet, globalOptions *config.GlobalO 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.StringVarP(&globalOptions.Namespace, "namespace", "n", "", "Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}") + fs.StringVarP(&globalOptions.Namespace, "namespace", "n", "", `Set namespace. Overrides "HELMFILE_NAMESPACE" OS environment variable when specified. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}`) fs.StringVarP(&globalOptions.Chart, "chart", "c", "", "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. diff --git a/docs/cli.md b/docs/cli.md index cbde76a3..217966b7 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -52,7 +52,7 @@ Flags: --kube-context string Set kubectl context. Overrides "HELMFILE_KUBE_CONTEXT" OS environment variable when specified. Uses current kubectl context by default -k, --kustomize-binary string Path to the kustomize binary (default "kustomize") --log-level string Set log level, default info (default "info") - -n, --namespace string Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }} + -n, --namespace string Set namespace. Overrides "HELMFILE_NAMESPACE" OS environment variable when specified. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }} --no-color Output without color -q, --quiet Silence output. Equivalent to log-level warn -l, --selector stringArray Only run using the releases that match labels. Labels can take the form of foo=bar or foo!=bar. diff --git a/docs/templating.md b/docs/templating.md index 9a596a27..b9e9bff1 100644 --- a/docs/templating.md +++ b/docs/templating.md @@ -67,6 +67,7 @@ Helmfile uses some OS environment variables to override default behaviour: * `HELMFILE_EXPERIMENTAL` - enable experimental features, expecting `true` lower case * `HELMFILE_ENVIRONMENT` - specify [Helmfile environment](environments.md), it has lower priority than CLI argument `--environment` * `HELMFILE_KUBE_CONTEXT` - specify the kubectl context, it has lower priority than CLI argument `--kube-context` +* `HELMFILE_NAMESPACE` - specify the namespace, it has lower priority than CLI argument `--namespace` * `HELMFILE_TEMPDIR` - specify directory to store temporary files * `HELMFILE_UPGRADE_NOTICE_DISABLED` - expecting any non-empty value to skip the check for the latest version of Helmfile in [helmfile version](cli.md#version) * `HELMFILE_GO_YAML_V3` - use *go.yaml.in/yaml/v3* instead of *go.yaml.in/yaml/v2*. It's `false` by default in Helmfile v0.x, and `true` in Helmfile v1.x. diff --git a/pkg/config/global.go b/pkg/config/global.go index 8811ff37..d96655a5 100644 --- a/pkg/config/global.go +++ b/pkg/config/global.go @@ -139,7 +139,17 @@ func (g *GlobalImpl) KubeContext() string { // Namespace returns the namespace to use. func (g *GlobalImpl) Namespace() string { - return g.GlobalOptions.Namespace + var namespace string + + switch { + case g.GlobalOptions.Namespace != "": + namespace = g.GlobalOptions.Namespace + case os.Getenv("HELMFILE_NAMESPACE") != "": + namespace = os.Getenv("HELMFILE_NAMESPACE") + default: + namespace = "" + } + return namespace } // Chart returns the chart to use. diff --git a/pkg/config/global_test.go b/pkg/config/global_test.go index b77751dc..e5b91f4c 100644 --- a/pkg/config/global_test.go +++ b/pkg/config/global_test.go @@ -82,3 +82,40 @@ func TestKubeContext(t *testing.T) { } os.Unsetenv(envvar.KubeContext) } + +// TestNamespace tests the namespace flag and HELMFILE_NAMESPACE env var fallback +func TestNamespace(t *testing.T) { + tests := []struct { + opts GlobalOptions + env string + expected string + }{ + { + opts: GlobalOptions{}, + env: "", + expected: "", + }, + { + opts: GlobalOptions{}, + env: "envset", + expected: "envset", + }, + { + opts: GlobalOptions{Namespace: "flagset"}, + env: "", + expected: "flagset", + }, + { + opts: GlobalOptions{Namespace: "flagset"}, + env: "envset", + expected: "flagset", + }, + } + + for _, test := range tests { + os.Setenv(envvar.Namespace, test.env) + received := NewGlobalImpl(&test.opts).Namespace() + require.Equalf(t, test.expected, received, "Namespace expected %s, received %s", test.expected, received) + } + os.Unsetenv(envvar.Namespace) +} diff --git a/pkg/envvar/const.go b/pkg/envvar/const.go index f220e505..d6f1575f 100644 --- a/pkg/envvar/const.go +++ b/pkg/envvar/const.go @@ -10,6 +10,7 @@ const ( Experimental = "HELMFILE_EXPERIMENTAL" // environment variable for experimental features, expecting "true" lower case Environment = "HELMFILE_ENVIRONMENT" KubeContext = "HELMFILE_KUBE_CONTEXT" + Namespace = "HELMFILE_NAMESPACE" FilePath = "HELMFILE_FILE_PATH" TempDir = "HELMFILE_TEMPDIR" UpgradeNoticeDisabled = "HELMFILE_UPGRADE_NOTICE_DISABLED"