command/push: ask for only variables that are unset

This commit is contained in:
Mitchell Hashimoto 2015-03-06 15:03:33 -08:00
parent bf14143369
commit eebd7b8aa3
4 changed files with 83 additions and 0 deletions

View File

@ -170,6 +170,7 @@ func (m *Meta) InputMode() terraform.InputMode {
mode |= terraform.InputModeProvider
if len(m.variables) == 0 && m.autoKey == "" {
mode |= terraform.InputModeVar
mode |= terraform.InputModeVarUnset
}
return mode

View File

@ -84,6 +84,17 @@ func (c *PushCommand) Run(args []string) int {
return 1
}
// Get the variables we might already have
vars, err := c.client.Get("")
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error looking up prior pushed configuration: %s", err))
return 1
}
for k, v := range vars {
ctx.SetVariable(k, v)
}
// Ask for input
if err := ctx.Input(c.InputMode()); err != nil {
c.Ui.Error(fmt.Sprintf(
@ -155,6 +166,7 @@ func (c *PushCommand) Synopsis() string {
// pushClient is implementd internally to control where pushes go. This is
// either to Atlas or a mock for testing.
type pushClient interface {
Get(string) (map[string]string, error)
Upsert(*pushUpsertOptions) error
}
@ -166,11 +178,22 @@ type pushUpsertOptions struct {
type mockPushClient struct {
File string
GetCalled bool
GetName string
GetResult map[string]string
GetError error
UpsertCalled bool
UpsertOptions *pushUpsertOptions
UpsertError error
}
func (c *mockPushClient) Get(name string) (map[string]string, error) {
c.GetCalled = true
c.GetName = name
return c.GetResult, c.GetError
}
func (c *mockPushClient) Upsert(opts *pushUpsertOptions) error {
f, err := os.Create(c.File)
if err != nil {

View File

@ -117,6 +117,61 @@ func TestPush_input(t *testing.T) {
}
}
func TestPush_inputPartial(t *testing.T) {
tmp, cwd := testCwd(t)
defer testFixCwd(t, tmp, cwd)
// Create remote state file, this should be pulled
conf, srv := testRemoteState(t, testState(), 200)
defer srv.Close()
// Persist local remote state
s := terraform.NewState()
s.Serial = 5
s.Remote = conf
testStateFileRemote(t, s)
// Path where the archive will be "uploaded" to
archivePath := testTempFile(t)
defer os.Remove(archivePath)
client := &mockPushClient{
File: archivePath,
GetResult: map[string]string{"foo": "bar"},
}
ui := new(cli.MockUi)
c := &PushCommand{
Meta: Meta{
ContextOpts: testCtxConfig(testProvider()),
Ui: ui,
},
client: client,
}
// Disable test mode so input would be asked and setup the
// input reader/writers.
test = false
defer func() { test = true }()
defaultInputReader = bytes.NewBufferString("foo\n")
defaultInputWriter = new(bytes.Buffer)
args := []string{
testFixturePath("push-input-partial"),
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
}
variables := map[string]string{
"foo": "bar",
"bar": "foo",
}
if !reflect.DeepEqual(client.UpsertOptions.Variables, variables) {
t.Fatalf("bad: %#v", client.UpsertOptions)
}
}
func TestPush_noState(t *testing.T) {
tmp, cwd := testCwd(t)
defer testFixCwd(t, tmp, cwd)

View File

@ -0,0 +1,4 @@
variable "foo" {}
variable "bar" {}
resource "test_instance" "foo" {}