diff --git a/docs/cmd_reference.md b/docs/cmd_reference.md index af4337b8..3180df83 100644 --- a/docs/cmd_reference.md +++ b/docs/cmd_reference.md @@ -69,6 +69,9 @@ This lists available CMD options in Helmsman: `--no-env-subst` turn off environment substitution globally. + `--no-recursive-env-expand` + disable recursive environment variables expansion. + `--subst-env-values` turn on environment substitution in values files. diff --git a/internal/app/cli.go b/internal/app/cli.go index d959304f..6b58edb0 100644 --- a/internal/app/cli.go +++ b/internal/app/cli.go @@ -79,6 +79,7 @@ type cli struct { diffContext int noEnvSubst bool substEnvValues bool + noRecursiveEnvExpand bool noSSMSubst bool substSSMValues bool detailedExitCode bool @@ -138,6 +139,7 @@ func (c *cli) setup() { flag.BoolVar(&c.detailedExitCode, "detailed-exit-code", false, "returns a detailed exit code (0 - no changes, 1 - error, 2 - changes present)") flag.BoolVar(&c.noEnvSubst, "no-env-subst", false, "turn off environment substitution globally") flag.BoolVar(&c.substEnvValues, "subst-env-values", false, "turn on environment substitution in values files.") + flag.BoolVar(&c.noRecursiveEnvExpand, "no-recursive-env-expand", false, "disable recursive environment values expansion") flag.BoolVar(&c.noSSMSubst, "no-ssm-subst", false, "turn off SSM parameter substitution globally") flag.BoolVar(&c.substSSMValues, "subst-ssm-values", false, "turn on SSM parameter substitution in values files.") flag.BoolVar(&c.updateDeps, "update-deps", false, "run 'helm dep up' for local charts") @@ -231,6 +233,11 @@ func (c *cli) parse() { log.Verbose("Substitution of env variables in values enabled") } } + + if !c.noRecursiveEnvExpand { + log.Verbose("Recursive environment variables expansion is enabled") + } + if !c.noSSMSubst { log.Verbose("Substitution of SSM variables enabled") if c.substSSMValues { diff --git a/internal/app/main.go b/internal/app/main.go index 423a1a27..ec9a31b0 100644 --- a/internal/app/main.go +++ b/internal/app/main.go @@ -8,7 +8,7 @@ import ( const ( helmBin = "helm" kubectlBin = "kubectl" - appVersion = "v3.16.4" + appVersion = "v3.16.4-fix" tempFilesDir = ".helmsman-tmp" defaultContextName = "default" resourcePool = 10 diff --git a/internal/app/utils.go b/internal/app/utils.go index 84db25c8..8adef9b0 100644 --- a/internal/app/utils.go +++ b/internal/app/utils.go @@ -146,8 +146,10 @@ func readFile(filepath string) string { // recusively expanding the variable's value func getEnv(key string) string { value := os.Getenv(key) - for envVar.MatchString(value) { - value = os.ExpandEnv(value) + if !flags.noRecursiveEnvExpand { + for envVar.MatchString(value) { + value = os.ExpandEnv(value) + } } return value } @@ -160,13 +162,15 @@ func prepareEnv(envFiles []string) error { return fmt.Errorf("error loading env file: %w", err) } } - for _, e := range os.Environ() { - if !strings.Contains(e, "$") { - continue + if !flags.noRecursiveEnvExpand { + for _, e := range os.Environ() { + if !strings.Contains(e, "$") { + continue + } + e = os.Expand(e, getEnv) + pair := strings.SplitN(e, "=", 2) + os.Setenv(pair[0], pair[1]) } - e = os.Expand(e, getEnv) - pair := strings.SplitN(e, "=", 2) - os.Setenv(pair[0], pair[1]) } return nil } @@ -178,7 +182,7 @@ func substituteEnv(str string) string { if strings.Contains(str, "$") { // add $$ escaping for $ strings os.Setenv("HELMSMAN_DOLLAR", "$") - return os.ExpandEnv(strings.ReplaceAll(str, "$$", "${HELMSMAN_DOLLAR}")) + return os.Expand(strings.ReplaceAll(str, "$$", "${HELMSMAN_DOLLAR}"), getEnv) } return str }