core: don't prompt for variables with defaults
In `helper/schema` we already makes a distinction between `Default` which is always applied and `InputDefault` which is displayed to the user for an empty field. But for variables we just have `Default` which is treated like `InputDefault`. This changes it to _not_ prompt the user for a value when the variable declaration includes a default. Treating this as a UX bugfix and the "don't prompt for variables w/ defaults set" behavior as the originally expected behavior we were failing to honor. Added an already-passing test to verify and cover the `helper/schema` behavior. Perhaps down the road we can add a `input_default` attribute to variables to allow similar behavior to `helper/schema` in variables, but for now just sticking with the fix. Fixes #2592
This commit is contained in:
parent
3dc055f18b
commit
5c38456b05
|
@ -2605,6 +2605,40 @@ func TestSchemaMap_Input(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSchemaMap_InputDefault(t *testing.T) {
|
||||||
|
emptyConfig := make(map[string]interface{})
|
||||||
|
c, err := config.NewRawConfig(emptyConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
rc := terraform.NewResourceConfig(c)
|
||||||
|
rc.Config = make(map[string]interface{})
|
||||||
|
|
||||||
|
input := new(terraform.MockUIInput)
|
||||||
|
input.InputFn = func(opts *terraform.InputOpts) (string, error) {
|
||||||
|
t.Fatalf("InputFn should not be called on: %#v", opts)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
schema := map[string]*Schema{
|
||||||
|
"availability_zone": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Default: "foo",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
actual, err := schemaMap(schema).Input(input, rc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := map[string]interface{}{}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(expected, actual.Config) {
|
||||||
|
t.Fatalf("got: %#v\nexpected: %#v", actual.Config, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSchemaMap_InternalValidate(t *testing.T) {
|
func TestSchemaMap_InternalValidate(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
In map[string]*Schema
|
In map[string]*Schema
|
||||||
|
|
|
@ -194,7 +194,7 @@ func (c *Context) Input(mode InputMode) error {
|
||||||
}
|
}
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, n := range names {
|
for _, n := range names {
|
||||||
// If we only care about unset variables, then if the variabel
|
// If we only care about unset variables, then if the variable
|
||||||
// is set, continue on.
|
// is set, continue on.
|
||||||
if mode&InputModeVarUnset != 0 {
|
if mode&InputModeVarUnset != 0 {
|
||||||
if _, ok := c.variables[n]; ok {
|
if _, ok := c.variables[n]; ok {
|
||||||
|
@ -214,9 +214,13 @@ func (c *Context) Input(mode InputMode) error {
|
||||||
panic(fmt.Sprintf("Unknown variable type: %#v", v.Type()))
|
panic(fmt.Sprintf("Unknown variable type: %#v", v.Type()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultString string
|
// If the variable is not already set, and the variable defines a
|
||||||
if v.Default != nil {
|
// default, use that for the value.
|
||||||
defaultString = v.Default.(string)
|
if _, ok := c.variables[n]; !ok {
|
||||||
|
if v.Default != nil {
|
||||||
|
c.variables[n] = v.Default.(string)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the user for a value for this variable
|
// Ask the user for a value for this variable
|
||||||
|
@ -226,7 +230,6 @@ func (c *Context) Input(mode InputMode) error {
|
||||||
value, err = c.uiInput.Input(&InputOpts{
|
value, err = c.uiInput.Input(&InputOpts{
|
||||||
Id: fmt.Sprintf("var.%s", n),
|
Id: fmt.Sprintf("var.%s", n),
|
||||||
Query: fmt.Sprintf("var.%s", n),
|
Query: fmt.Sprintf("var.%s", n),
|
||||||
Default: defaultString,
|
|
||||||
Description: v.Description,
|
Description: v.Description,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3572,6 +3572,52 @@ func TestContext2Input_varOnlyUnset(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Input_varWithDefault(t *testing.T) {
|
||||||
|
input := new(MockUIInput)
|
||||||
|
m := testModule(t, "input-var-default")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Module: m,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
Variables: map[string]string{},
|
||||||
|
UIInput: input,
|
||||||
|
})
|
||||||
|
|
||||||
|
input.InputFn = func(opts *InputOpts) (string, error) {
|
||||||
|
t.Fatalf(
|
||||||
|
"Input should never be called because variable has a default: %#v", opts)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ctx.Input(InputModeVar | InputModeVarUnset); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ctx.Plan(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
state, err := ctx.Apply()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualStr := strings.TrimSpace(state.String())
|
||||||
|
expectedStr := strings.TrimSpace(`
|
||||||
|
aws_instance.foo:
|
||||||
|
ID = foo
|
||||||
|
foo = 123
|
||||||
|
type = aws_instance
|
||||||
|
`)
|
||||||
|
if actualStr != expectedStr {
|
||||||
|
t.Fatalf("expected: \n%s\ngot: \n%s\n", expectedStr, actualStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContext2Apply(t *testing.T) {
|
func TestContext2Apply(t *testing.T) {
|
||||||
m := testModule(t, "apply-good")
|
m := testModule(t, "apply-good")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
variable "foo" {
|
||||||
|
default = 123
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "foo" {
|
||||||
|
foo = "${var.foo}"
|
||||||
|
}
|
Loading…
Reference in New Issue