From 1248b147acf55d7f7eaa1a06b6fb89d760d1e334 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 1 Nov 2016 19:16:43 -0700 Subject: [PATCH] command/meta: always ask for unset variable input Fixes #7975 This changes the InputMode for the CLI to always be: InputModeProvider | InputModeVar | InputModeVarUnset Which means: * Ask for provider variables * Ask for user variables _that are not already set_ The change is the latter point. Before, we'd only ask for variables if zero were given. This forces the user to either have no variables set via the CLI, env vars, tfvars or ALL variables, but no in between. As reported in #7975, this isn't expected behavior. The new change makes is so that unset variables are always asked for. Users can retain the previous behavior by setting `-input=false`. This would ensure that variables set by external sources cover all cases. --- command/apply_test.go | 41 +++++++++++++++++++ command/meta.go | 6 +-- command/meta_test.go | 6 ++- .../test-fixtures/apply-input-partial/main.tf | 5 +++ terraform/context.go | 3 +- 5 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 command/test-fixtures/apply-input-partial/main.tf diff --git a/command/apply_test.go b/command/apply_test.go index 150c6d014a13..31f60fb55c78 100644 --- a/command/apply_test.go +++ b/command/apply_test.go @@ -407,6 +407,47 @@ func TestApply_input(t *testing.T) { } } +// When only a partial set of the variables are set, Terraform +// should still ask for the unset ones by default (with -input=true) +func TestApply_inputPartial(t *testing.T) { + // Disable test mode so input would be asked + test = false + defer func() { test = true }() + + // Set some default reader/writers for the inputs + defaultInputReader = bytes.NewBufferString("one\ntwo\n") + defaultInputWriter = new(bytes.Buffer) + + statePath := testTempFile(t) + + p := testProvider() + ui := new(cli.MockUi) + c := &ApplyCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-var", "foo=foovalue", + testFixturePath("apply-input-partial"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + expected := strings.TrimSpace(` + +Outputs: + +bar = one +foo = foovalue + `) + testStateOutput(t, statePath, expected) +} + func TestApply_noArgs(t *testing.T) { cwd, err := os.Getwd() if err != nil { diff --git a/command/meta.go b/command/meta.go index 92f25db1ea1e..541f96144b57 100644 --- a/command/meta.go +++ b/command/meta.go @@ -221,10 +221,8 @@ func (m *Meta) InputMode() terraform.InputMode { var mode terraform.InputMode mode |= terraform.InputModeProvider - if len(m.variables) == 0 { - mode |= terraform.InputModeVar - mode |= terraform.InputModeVarUnset - } + mode |= terraform.InputModeVar + mode |= terraform.InputModeVarUnset return mode } diff --git a/command/meta_test.go b/command/meta_test.go index 781c664dc3fd..5dde0f1ffcc4 100644 --- a/command/meta_test.go +++ b/command/meta_test.go @@ -175,7 +175,11 @@ func TestMetaInputMode_vars(t *testing.T) { t.Fatalf("err: %s", err) } - if m.InputMode()&terraform.InputModeVar != 0 { + if m.InputMode()&terraform.InputModeVar == 0 { + t.Fatalf("bad: %#v", m.InputMode()) + } + + if m.InputMode()&terraform.InputModeVarUnset == 0 { t.Fatalf("bad: %#v", m.InputMode()) } } diff --git a/command/test-fixtures/apply-input-partial/main.tf b/command/test-fixtures/apply-input-partial/main.tf new file mode 100644 index 000000000000..8c80dd09cb1c --- /dev/null +++ b/command/test-fixtures/apply-input-partial/main.tf @@ -0,0 +1,5 @@ +variable "foo" {} +variable "bar" {} + +output "foo" { value = "${var.foo}" } +output "bar" { value = "${var.bar}" } diff --git a/terraform/context.go b/terraform/context.go index 80bdf2d5096d..987469bb7d38 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -22,7 +22,8 @@ const ( // InputModeVar asks for all variables InputModeVar InputMode = 1 << iota - // InputModeVarUnset asks for variables which are not set yet + // InputModeVarUnset asks for variables which are not set yet. + // InputModeVar must be set for this to have an effect. InputModeVarUnset // InputModeProvider asks for provider variables