Skip to content

Commit

Permalink
Support passing list of secrets to --preserve-env flag
Browse files Browse the repository at this point in the history
  • Loading branch information
Piccirello committed Jun 12, 2023
1 parent 9a65cf0 commit a310645
Show file tree
Hide file tree
Showing 3 changed files with 48 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
}
25 changes: 25 additions & 0 deletions tests/e2e/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,29 @@ beforeEach
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 a310645

Please sign in to comment.