Skip to content

Commit

Permalink
Merge pull request #401 from DopplerHQ/tom/preserve-env
Browse files Browse the repository at this point in the history
Support passing list of secrets to --preserve-env flag
  • Loading branch information
Piccirello authored Jun 12, 2023
2 parents 700a25c + a310645 commit 7f32efc
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
18 changes: 14 additions & 4 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ doppler run --mount secrets.json -- cat secrets.json`,
fallbackReadonly := utils.GetBoolFlag(cmd, "fallback-readonly")
fallbackOnly := utils.GetBoolFlag(cmd, "fallback-only")
exitOnWriteFailure := !utils.GetBoolFlag(cmd, "no-exit-on-write-failure")
preserveEnv := utils.GetBoolFlag(cmd, "preserve-env")
preserveEnv := cmd.Flag("preserve-env").Value.String()
forwardSignals := utils.GetBoolFlag(cmd, "forward-signals")
localConfig := configuration.LocalConfig(cmd)
dynamicSecretsTTL := utils.GetDurationFlag(cmd, "dynamic-ttl")
Expand Down Expand Up @@ -181,7 +181,7 @@ doppler run --mount secrets.json -- cat secrets.json`,
utils.HandleError(fmt.Errorf("Invalid mount format. Valid formats are %s", models.SecretsMountFormats))
}

if preserveEnv {
if preserveEnv != "false" {
if shouldMountFile {
utils.LogWarning("--preserve-env has no effect when used with --mount")
} else {
Expand Down Expand Up @@ -265,13 +265,19 @@ doppler run --mount secrets.json -- cat secrets.json`,
}
}

if preserveEnv {
if preserveEnv != "false" {
secretsToPreserve := strings.Split(preserveEnv, ",")

// use doppler secrets
for name, value := range dopplerSecrets {
secrets[name] = value
}
// then use existing env vars
for name, value := range existingEnvKeys {
if preserveEnv != "true" && !utils.Contains(secretsToPreserve, name) {
continue
}

if _, found := secrets[name]; found == true {
utils.LogDebug(fmt.Sprintf("Ignoring Doppler secret %s", name))
}
Expand Down Expand Up @@ -688,7 +694,11 @@ func init() {
runCmd.Flags().StringP("config", "c", "", "config (e.g. dev)")
runCmd.RegisterFlagCompletionFunc("config", configNamesValidArgs)
runCmd.Flags().String("command", "", "command to execute (e.g. \"echo hi\")")
runCmd.Flags().Bool("preserve-env", false, "ignore any Doppler secrets that are already defined in the environment. this has potential security implications, use at your own risk.")
// note: requires using "--preserve-env=VALUE", doesn't work with "--preserve-env VALUE"
runCmd.Flags().String("preserve-env", "false", "a comma separated list of secrets for which the existing value from the environment, if any, should take precedence of the Doppler secret value. value must be specified with an equals sign (e.g. --preserve-env=\"FOO,BAR\"). specify \"true\" to give precedence to all existing environment values, however this has potential security implications and should be used at your own risk.")
// we must specify a default when no value is passed as this flag used to be a boolean
// https://github.com/spf13/pflag#setting-no-option-default-values-for-flags
runCmd.Flags().Lookup("preserve-env").NoOptDefVal = "true"
runCmd.Flags().String("name-transformer", "", fmt.Sprintf("(BETA) output name transformer. one of %v", validEnvCompatNameTransformersList))
runCmd.RegisterFlagCompletionFunc("name-transformer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return models.SecretsEnvCompatNameTransformerTypes, cobra.ShellCompDirectiveDefault
Expand Down
9 changes: 9 additions & 0 deletions pkg/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,12 @@ func RedactAuthToken(token string) string {

return "[REDACTED]"
}

func Contains[T comparable](s []T, e T) bool {
for _, v := range s {
if v == e {
return true
}
}
return false
}
51 changes: 51 additions & 0 deletions tests/e2e/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,55 @@ beforeEach
# verify flags specified after '--' are passed to subcommand
"$DOPPLER_BINARY" run -- true --config invalidconfig || error "ERROR: flags specified after '--' are improperly handled"

### --preserve-env flag

beforeEach

# verify not specifying preserve-env flag results in ignoring existing env vars
value="$(TEST="foo" "$DOPPLER_BINARY" run -- printenv TEST)"
[[ "$value" == "abc" ]] || error "ERROR: existing env vars not ignored when omitting preserve-env flag"

beforeEach

# verify preserve-env flag value of 'false' results in ignoring existing env vars
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env=false -- printenv TEST)"
[[ "$value" == "abc" ]] || error "ERROR: existing env vars not ignored when preserve-env flag passed value of \"false\""

beforeEach

# verify preserve-env flag without value preserves all existing env vars
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env -- printenv TEST)"
[[ "$value" == "foo" ]] || error "ERROR: existing env vars not honored when preserve-env flag specified without value"

beforeEach

# verify preserve-env flag value of 'true' preserves all existing env vars
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env=true -- printenv TEST)"
[[ "$value" == "foo" ]] || error "ERROR: existing env vars not honored when preserve-env flag passed value of \"true\""

beforeEach

# verify preserve-env flag honors secret name
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env="TEST" -- printenv TEST)"
[[ "$value" == "foo" ]] || error "ERROR: existing env var not honored when preserve-env flag passed secret name"

beforeEach

# verify preserve-env flag only overrides specified secrets
# TEST should be read from env but FOO should be read from Doppler
value="$(TEST="foo" FOO="123" "$DOPPLER_BINARY" run --preserve-env="TEST" --command "printenv TEST && printenv FOO")"
[[ "$value" == "$(echo -e "foo\nbar")" ]] || error "ERROR: env vars not honored when preserve-env flag passed one secret name"

beforeEach

# verify preserve-env flag honors list of secret names
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env="INVALID,TEST" -- printenv TEST)"
[[ "$value" == "foo" ]] || error "ERROR: existing env var not honored when preserve-env flag passed list of secret names"

beforeEach

# verify preserve-env flag ignores nonexistent secrets
value="$(TEST="foo" "$DOPPLER_BINARY" run --preserve-env="INVALID" -- printenv TEST)"
[[ "$value" == "abc" ]] || error "ERROR: existing env var not ignored when preserve-env flag passed list of nonexistent secret names"

afterAll

0 comments on commit 7f32efc

Please sign in to comment.