diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index c6a5cfda6..d0c7c7c7c 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -6,12 +6,13 @@ The `config` plugin provides the following commands to manage your variables: ``` config (|--global) Pretty-print an app or global environment +config:bundle (|--global) [--merged] Bundle environment into tarfile +config:clear (|--global) Clears environment variables +config:export (|--global) [--envfile] Export a global or app environment config:get (|--global) KEY Display a global or app-specific config value +config:keys (|--global) [--merged] Show keys set in environment config:set [--encoded] [--no-restart] (|--global) KEY1=VALUE1 [KEY2=VALUE2 ...] Set one or more config vars config:unset [--no-restart] (|--global) KEY1 [KEY2 ...] Unset one or more config vars -config:export (|--global) [--envfile] Export a global or app environment -config:keys (|--global) [--merged] Show keys set in environment -config:bundle (|--global) [--merged] Bundle environment into tarfile ``` > For security reasons - and as per [docker recommendations](https://github.com/docker/docker/issues/13490) - Dockerfile-based deploys have variables available *only* during runtime, as noted in [this issue](https://github.com/dokku/dokku/issues/1860). diff --git a/plugins/config/config.go b/plugins/config/config.go index 23a74943a..4947492f3 100644 --- a/plugins/config/config.go +++ b/plugins/config/config.go @@ -92,6 +92,29 @@ func UnsetMany(appName string, keys []string, restart bool) (err error) { return } +//UnsetAll removes all config keys +func UnsetAll(appName string, restart bool) (err error) { + global := appName == "" + env, err := loadAppOrGlobalEnv(appName) + if err != nil { + return + } + var changed = false + for k := range env.Map() { + common.LogInfo1Quiet(fmt.Sprintf("Unsetting %s", k)) + env.Unset(k) + changed = true + } + if changed { + env.Write() + triggerUpdate(appName, "clear", []string{}) + } + if !global && restart && env.GetBoolDefault("DOKKU_APP_RESTORE", true) { + triggerRestart(appName) + } + return +} + func triggerRestart(appName string) { common.LogInfo1(fmt.Sprintf("Restarting app %s", appName)) if err := common.PlugnTrigger("app-restart", appName); err != nil { diff --git a/plugins/config/config_test.go b/plugins/config/config_test.go index 05f42faad..ff2502fd2 100644 --- a/plugins/config/config_test.go +++ b/plugins/config/config_test.go @@ -80,6 +80,22 @@ func TestConfigSetMany(t *testing.T) { Expect(SetMany(testAppName+"does_not_exist", vals, false)).ToNot(Succeed()) } +func TestConfigUnsetAll(t *testing.T) { + RegisterTestingT(t) + Expect(setupTestApp()).To(Succeed()) + defer teardownTestApp() + + expectValue(testAppName, "testKey", "TESTING") + expectValue("", "testKey", "GLOBAL_TESTING") + + Expect(UnsetAll(testAppName, false)).To(Succeed()) + expectNoValue(testAppName, "testKey") + expectNoValue(testAppName, "noKey") + expectNoValue(testAppName, "globalKey") + + Expect(UnsetAll(testAppName+"does-not-exist", false)).ToNot(Succeed()) +} + func TestConfigUnsetMany(t *testing.T) { RegisterTestingT(t) Expect(setupTestApp()).To(Succeed()) diff --git a/plugins/config/functions b/plugins/config/functions index 70688b7d7..7c260a2d9 100755 --- a/plugins/config/functions +++ b/plugins/config/functions @@ -46,6 +46,11 @@ config_get() { config_sub get "$@" } +config_clear() { + declare desc="clears config vars" + config_sub clear "$@" +} + config_set() { declare desc="set value of given config var" config_sub set "$@" diff --git a/plugins/config/src/commands/commands.go b/plugins/config/src/commands/commands.go index 5ce6f8906..766be2960 100644 --- a/plugins/config/src/commands/commands.go +++ b/plugins/config/src/commands/commands.go @@ -22,6 +22,7 @@ Additional commands:` helpContent = ` config (|--global), Pretty-print an app or global environment config:bundle (|--global) [--merged], Bundle environment into tarfile + config:clear (|--global), Clears environment variables config:export (|--global) [--envfile], Export a global or app environment config:get (|--global) KEY, Display a global or app-specific config value config:keys (|--global) [--merged], Show keys set in environment diff --git a/plugins/config/src/subcommands/clear/clear.go b/plugins/config/src/subcommands/clear/clear.go new file mode 100644 index 000000000..8fe985330 --- /dev/null +++ b/plugins/config/src/subcommands/clear/clear.go @@ -0,0 +1,17 @@ +package main + +import ( + "flag" + "os" + + "github.com/dokku/dokku/plugins/config" +) + +//clear all entries from the given environment +func main() { + args := flag.NewFlagSet("config:clear", flag.ExitOnError) + global := args.Bool("global", false, "--global: use the global environment") + noRestart := args.Bool("no-restart", false, "--no-restart: no restart") + args.Parse(os.Args[2:]) + config.CommandClear(args.Args(), *global, *noRestart) +} diff --git a/plugins/config/subcommands.go b/plugins/config/subcommands.go index c2cc061bb..0ae759be2 100644 --- a/plugins/config/subcommands.go +++ b/plugins/config/subcommands.go @@ -50,6 +50,15 @@ func CommandGet(args []string, global bool, quoted bool) { } } +//CommandClear implements config:clear +func CommandClear(args []string, global bool, noRestart bool) { + appName, _ := getCommonArgs(global, args) + err := UnsetAll(appName, !noRestart) + if err != nil { + common.LogFail(err.Error()) + } +} + //CommandUnset implements config:unset func CommandUnset(args []string, global bool, noRestart bool) { appName, keys := getCommonArgs(global, args)