Merge pull request #13105 from hashicorp/jbardin/command-env

disallow env names that aren't url-safe
This commit is contained in:
James Bardin 2017-03-27 18:53:44 -04:00 committed by GitHub
commit f172b4a023
5 changed files with 68 additions and 1 deletions

View File

@ -1,6 +1,9 @@
package command package command
import "strings" import (
"net/url"
"strings"
)
// EnvCommand is a Command Implementation that manipulates local state // EnvCommand is a Command Implementation that manipulates local state
// environments. // environments.
@ -39,6 +42,13 @@ func (c *EnvCommand) Synopsis() string {
return "Environment management" return "Environment management"
} }
// validEnvName returns true is this name is valid to use as an environment name.
// Since most named states are accessed via a filesystem path or URL, check if
// escaping the name would be required.
func validEnvName(name string) bool {
return name == url.PathEscape(name)
}
const ( const (
envNotSupported = `Backend does not support environments` envNotSupported = `Backend does not support environments`
@ -81,5 +91,10 @@ Environment %[1]q is your active environment!
You cannot delete the currently active environment. Please switch You cannot delete the currently active environment. Please switch
to another environment and try again. to another environment and try again.
`
envInvalidName = `
The environment name %q is not allowed. The name must contain only URL safe
characters, and no path separators.
` `
) )

View File

@ -103,6 +103,44 @@ func TestEnv_createAndList(t *testing.T) {
} }
} }
// Don't allow names that aren't URL safe
func TestEnv_createInvalid(t *testing.T) {
// Create a temporary working directory that is empty
td := tempDir(t)
os.MkdirAll(td, 0755)
defer os.RemoveAll(td)
defer testChdir(t, td)()
newCmd := &EnvNewCommand{}
envs := []string{"test_a*", "test_b/foo", "../../../test_c", "好_d"}
// create multiple envs
for _, env := range envs {
ui := new(cli.MockUi)
newCmd.Meta = Meta{Ui: ui}
if code := newCmd.Run([]string{env}); code == 0 {
t.Fatalf("expected failure: \n%s", ui.OutputWriter)
}
}
// list envs to make sure none were created
listCmd := &EnvListCommand{}
ui := new(cli.MockUi)
listCmd.Meta = Meta{Ui: ui}
if code := listCmd.Run(nil); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
}
actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "* default"
if actual != expected {
t.Fatalf("\nexpected: %q\nactual: %q", expected, actual)
}
}
func TestEnv_createWithState(t *testing.T) { func TestEnv_createWithState(t *testing.T) {
td := tempDir(t) td := tempDir(t)
os.MkdirAll(td, 0755) os.MkdirAll(td, 0755)

View File

@ -32,6 +32,11 @@ func (c *EnvDeleteCommand) Run(args []string) int {
delEnv := args[0] delEnv := args[0]
if !validEnvName(delEnv) {
c.Ui.Error(fmt.Sprintf(envInvalidName, delEnv))
return 1
}
configPath, err := ModulePath(args[1:]) configPath, err := ModulePath(args[1:])
if err != nil { if err != nil {
c.Ui.Error(err.Error()) c.Ui.Error(err.Error())

View File

@ -35,6 +35,11 @@ func (c *EnvNewCommand) Run(args []string) int {
newEnv := args[0] newEnv := args[0]
if !validEnvName(newEnv) {
c.Ui.Error(fmt.Sprintf(envInvalidName, newEnv))
return 1
}
configPath, err := ModulePath(args[1:]) configPath, err := ModulePath(args[1:])
if err != nil { if err != nil {
c.Ui.Error(err.Error()) c.Ui.Error(err.Error())

View File

@ -39,6 +39,10 @@ func (c *EnvSelectCommand) Run(args []string) int {
} }
name := args[0] name := args[0]
if !validEnvName(name) {
c.Ui.Error(fmt.Sprintf(envInvalidName, name))
return 1
}
states, err := b.States() states, err := b.States()
if err != nil { if err != nil {