github.com/ricardclau/terraform@v0.6.17-0.20160519222547-283e3ae6b5a9/command/untaint_test.go (about)

     1  package command
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/terraform"
     9  	"github.com/mitchellh/cli"
    10  )
    11  
    12  func TestUntaint(t *testing.T) {
    13  	state := &terraform.State{
    14  		Modules: []*terraform.ModuleState{
    15  			&terraform.ModuleState{
    16  				Path: []string{"root"},
    17  				Resources: map[string]*terraform.ResourceState{
    18  					"test_instance.foo": &terraform.ResourceState{
    19  						Type: "test_instance",
    20  						Tainted: []*terraform.InstanceState{
    21  							&terraform.InstanceState{ID: "bar"},
    22  						},
    23  					},
    24  				},
    25  			},
    26  		},
    27  	}
    28  	statePath := testStateFile(t, state)
    29  
    30  	ui := new(cli.MockUi)
    31  	c := &UntaintCommand{
    32  		Meta: Meta{
    33  			Ui: ui,
    34  		},
    35  	}
    36  
    37  	args := []string{
    38  		"-state", statePath,
    39  		"test_instance.foo",
    40  	}
    41  	if code := c.Run(args); code != 0 {
    42  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
    43  	}
    44  
    45  	expected := strings.TrimSpace(`
    46  test_instance.foo:
    47    ID = bar
    48  	`)
    49  	testStateOutput(t, statePath, expected)
    50  }
    51  
    52  func TestUntaint_indexRequired(t *testing.T) {
    53  	state := &terraform.State{
    54  		Modules: []*terraform.ModuleState{
    55  			&terraform.ModuleState{
    56  				Path: []string{"root"},
    57  				Resources: map[string]*terraform.ResourceState{
    58  					"test_instance.foo": &terraform.ResourceState{
    59  						Type: "test_instance",
    60  						Tainted: []*terraform.InstanceState{
    61  							&terraform.InstanceState{ID: "bar"},
    62  							&terraform.InstanceState{ID: "bar2"},
    63  						},
    64  					},
    65  				},
    66  			},
    67  		},
    68  	}
    69  	statePath := testStateFile(t, state)
    70  
    71  	ui := new(cli.MockUi)
    72  	c := &UntaintCommand{
    73  		Meta: Meta{
    74  			Ui: ui,
    75  		},
    76  	}
    77  
    78  	args := []string{
    79  		"-state", statePath,
    80  		"test_instance.foo",
    81  	}
    82  	if code := c.Run(args); code == 0 {
    83  		t.Fatalf("Expected non-zero exit. Output:\n\n%s", ui.OutputWriter.String())
    84  	}
    85  
    86  	// Nothing should have gotten untainted
    87  	expected := strings.TrimSpace(`
    88  test_instance.foo: (2 tainted)
    89    ID = <not created>
    90    Tainted ID 1 = bar
    91    Tainted ID 2 = bar2
    92  	`)
    93  	testStateOutput(t, statePath, expected)
    94  
    95  	// Should have gotten an error message mentioning index
    96  	errOut := ui.ErrorWriter.String()
    97  	errContains := "please specify an index"
    98  	if !strings.Contains(errOut, errContains) {
    99  		t.Fatalf("Expected err output: %s, to contain: %s", errOut, errContains)
   100  	}
   101  }
   102  
   103  func TestUntaint_indexSpecified(t *testing.T) {
   104  	state := &terraform.State{
   105  		Modules: []*terraform.ModuleState{
   106  			&terraform.ModuleState{
   107  				Path: []string{"root"},
   108  				Resources: map[string]*terraform.ResourceState{
   109  					"test_instance.foo": &terraform.ResourceState{
   110  						Type: "test_instance",
   111  						Tainted: []*terraform.InstanceState{
   112  							&terraform.InstanceState{ID: "bar"},
   113  							&terraform.InstanceState{ID: "bar2"},
   114  						},
   115  					},
   116  				},
   117  			},
   118  		},
   119  	}
   120  	statePath := testStateFile(t, state)
   121  
   122  	ui := new(cli.MockUi)
   123  	c := &UntaintCommand{
   124  		Meta: Meta{
   125  			Ui: ui,
   126  		},
   127  	}
   128  
   129  	args := []string{
   130  		"-state", statePath,
   131  		"-index", "1",
   132  		"test_instance.foo",
   133  	}
   134  	if code := c.Run(args); code != 0 {
   135  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   136  	}
   137  
   138  	// Nothing should have gotten untainted
   139  	expected := strings.TrimSpace(`
   140  test_instance.foo: (1 tainted)
   141    ID = bar2
   142    Tainted ID 1 = bar
   143  	`)
   144  	testStateOutput(t, statePath, expected)
   145  }
   146  
   147  func TestUntaint_backup(t *testing.T) {
   148  	// Get a temp cwd
   149  	tmp, cwd := testCwd(t)
   150  	defer testFixCwd(t, tmp, cwd)
   151  
   152  	// Write the temp state
   153  	state := &terraform.State{
   154  		Modules: []*terraform.ModuleState{
   155  			&terraform.ModuleState{
   156  				Path: []string{"root"},
   157  				Resources: map[string]*terraform.ResourceState{
   158  					"test_instance.foo": &terraform.ResourceState{
   159  						Type: "test_instance",
   160  						Tainted: []*terraform.InstanceState{
   161  							&terraform.InstanceState{ID: "bar"},
   162  						},
   163  					},
   164  				},
   165  			},
   166  		},
   167  	}
   168  	path := testStateFileDefault(t, state)
   169  
   170  	ui := new(cli.MockUi)
   171  	c := &UntaintCommand{
   172  		Meta: Meta{
   173  			Ui: ui,
   174  		},
   175  	}
   176  
   177  	args := []string{
   178  		"test_instance.foo",
   179  	}
   180  	if code := c.Run(args); code != 0 {
   181  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   182  	}
   183  
   184  	// Backup is still tainted
   185  	testStateOutput(t, path+".backup", strings.TrimSpace(`
   186  test_instance.foo: (1 tainted)
   187    ID = <not created>
   188    Tainted ID 1 = bar
   189  	`))
   190  
   191  	// State is untainted
   192  	testStateOutput(t, path, strings.TrimSpace(`
   193  test_instance.foo:
   194    ID = bar
   195  	`))
   196  }
   197  
   198  func TestUntaint_backupDisable(t *testing.T) {
   199  	// Get a temp cwd
   200  	tmp, cwd := testCwd(t)
   201  	defer testFixCwd(t, tmp, cwd)
   202  
   203  	// Write the temp state
   204  	state := &terraform.State{
   205  		Modules: []*terraform.ModuleState{
   206  			&terraform.ModuleState{
   207  				Path: []string{"root"},
   208  				Resources: map[string]*terraform.ResourceState{
   209  					"test_instance.foo": &terraform.ResourceState{
   210  						Type: "test_instance",
   211  						Tainted: []*terraform.InstanceState{
   212  							&terraform.InstanceState{ID: "bar"},
   213  						},
   214  					},
   215  				},
   216  			},
   217  		},
   218  	}
   219  	path := testStateFileDefault(t, state)
   220  
   221  	ui := new(cli.MockUi)
   222  	c := &UntaintCommand{
   223  		Meta: Meta{
   224  			Ui: ui,
   225  		},
   226  	}
   227  
   228  	args := []string{
   229  		"-backup", "-",
   230  		"test_instance.foo",
   231  	}
   232  	if code := c.Run(args); code != 0 {
   233  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   234  	}
   235  
   236  	if _, err := os.Stat(path + ".backup"); err == nil {
   237  		t.Fatal("backup path should not exist")
   238  	}
   239  
   240  	testStateOutput(t, path, strings.TrimSpace(`
   241  test_instance.foo:
   242    ID = bar
   243  	`))
   244  }
   245  
   246  func TestUntaint_badState(t *testing.T) {
   247  	ui := new(cli.MockUi)
   248  	c := &UntaintCommand{
   249  		Meta: Meta{
   250  			Ui: ui,
   251  		},
   252  	}
   253  
   254  	args := []string{
   255  		"-state", "i-should-not-exist-ever",
   256  		"foo",
   257  	}
   258  	if code := c.Run(args); code != 1 {
   259  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   260  	}
   261  }
   262  
   263  func TestUntaint_defaultState(t *testing.T) {
   264  	// Get a temp cwd
   265  	tmp, cwd := testCwd(t)
   266  	defer testFixCwd(t, tmp, cwd)
   267  
   268  	// Write the temp state
   269  	state := &terraform.State{
   270  		Modules: []*terraform.ModuleState{
   271  			&terraform.ModuleState{
   272  				Path: []string{"root"},
   273  				Resources: map[string]*terraform.ResourceState{
   274  					"test_instance.foo": &terraform.ResourceState{
   275  						Type: "test_instance",
   276  						Tainted: []*terraform.InstanceState{
   277  							&terraform.InstanceState{ID: "bar"},
   278  						},
   279  					},
   280  				},
   281  			},
   282  		},
   283  	}
   284  	path := testStateFileDefault(t, state)
   285  
   286  	ui := new(cli.MockUi)
   287  	c := &UntaintCommand{
   288  		Meta: Meta{
   289  			Ui: ui,
   290  		},
   291  	}
   292  
   293  	args := []string{
   294  		"test_instance.foo",
   295  	}
   296  	if code := c.Run(args); code != 0 {
   297  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   298  	}
   299  
   300  	testStateOutput(t, path, strings.TrimSpace(`
   301  test_instance.foo:
   302    ID = bar
   303  	`))
   304  }
   305  
   306  func TestUntaint_missing(t *testing.T) {
   307  	state := &terraform.State{
   308  		Modules: []*terraform.ModuleState{
   309  			&terraform.ModuleState{
   310  				Path: []string{"root"},
   311  				Resources: map[string]*terraform.ResourceState{
   312  					"test_instance.foo": &terraform.ResourceState{
   313  						Type: "test_instance",
   314  						Tainted: []*terraform.InstanceState{
   315  							&terraform.InstanceState{ID: "bar"},
   316  						},
   317  					},
   318  				},
   319  			},
   320  		},
   321  	}
   322  	statePath := testStateFile(t, state)
   323  
   324  	ui := new(cli.MockUi)
   325  	c := &UntaintCommand{
   326  		Meta: Meta{
   327  			Ui: ui,
   328  		},
   329  	}
   330  
   331  	args := []string{
   332  		"-state", statePath,
   333  		"test_instance.bar",
   334  	}
   335  	if code := c.Run(args); code == 0 {
   336  		t.Fatalf("bad: %d\n\n%s", code, ui.OutputWriter.String())
   337  	}
   338  }
   339  
   340  func TestUntaint_missingAllow(t *testing.T) {
   341  	state := &terraform.State{
   342  		Modules: []*terraform.ModuleState{
   343  			&terraform.ModuleState{
   344  				Path: []string{"root"},
   345  				Resources: map[string]*terraform.ResourceState{
   346  					"test_instance.foo": &terraform.ResourceState{
   347  						Type: "test_instance",
   348  						Tainted: []*terraform.InstanceState{
   349  							&terraform.InstanceState{ID: "bar"},
   350  						},
   351  					},
   352  				},
   353  			},
   354  		},
   355  	}
   356  	statePath := testStateFile(t, state)
   357  
   358  	ui := new(cli.MockUi)
   359  	c := &UntaintCommand{
   360  		Meta: Meta{
   361  			Ui: ui,
   362  		},
   363  	}
   364  
   365  	args := []string{
   366  		"-allow-missing",
   367  		"-state", statePath,
   368  		"test_instance.bar",
   369  	}
   370  	if code := c.Run(args); code != 0 {
   371  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   372  	}
   373  }
   374  
   375  func TestUntaint_stateOut(t *testing.T) {
   376  	// Get a temp cwd
   377  	tmp, cwd := testCwd(t)
   378  	defer testFixCwd(t, tmp, cwd)
   379  
   380  	// Write the temp state
   381  	state := &terraform.State{
   382  		Modules: []*terraform.ModuleState{
   383  			&terraform.ModuleState{
   384  				Path: []string{"root"},
   385  				Resources: map[string]*terraform.ResourceState{
   386  					"test_instance.foo": &terraform.ResourceState{
   387  						Type: "test_instance",
   388  						Tainted: []*terraform.InstanceState{
   389  							&terraform.InstanceState{ID: "bar"},
   390  						},
   391  					},
   392  				},
   393  			},
   394  		},
   395  	}
   396  	path := testStateFileDefault(t, state)
   397  
   398  	ui := new(cli.MockUi)
   399  	c := &UntaintCommand{
   400  		Meta: Meta{
   401  			Ui: ui,
   402  		},
   403  	}
   404  
   405  	args := []string{
   406  		"-state-out", "foo",
   407  		"test_instance.foo",
   408  	}
   409  	if code := c.Run(args); code != 0 {
   410  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   411  	}
   412  
   413  	testStateOutput(t, path, strings.TrimSpace(`
   414  test_instance.foo: (1 tainted)
   415    ID = <not created>
   416    Tainted ID 1 = bar
   417  	`))
   418  	testStateOutput(t, "foo", strings.TrimSpace(`
   419  test_instance.foo:
   420    ID = bar
   421  	`))
   422  }
   423  
   424  func TestUntaint_module(t *testing.T) {
   425  	state := &terraform.State{
   426  		Modules: []*terraform.ModuleState{
   427  			&terraform.ModuleState{
   428  				Path: []string{"root"},
   429  				Resources: map[string]*terraform.ResourceState{
   430  					"test_instance.foo": &terraform.ResourceState{
   431  						Type: "test_instance",
   432  						Tainted: []*terraform.InstanceState{
   433  							&terraform.InstanceState{ID: "bar"},
   434  						},
   435  					},
   436  				},
   437  			},
   438  			&terraform.ModuleState{
   439  				Path: []string{"root", "child"},
   440  				Resources: map[string]*terraform.ResourceState{
   441  					"test_instance.blah": &terraform.ResourceState{
   442  						Type: "test_instance",
   443  						Tainted: []*terraform.InstanceState{
   444  							&terraform.InstanceState{ID: "bar"},
   445  						},
   446  					},
   447  				},
   448  			},
   449  		},
   450  	}
   451  	statePath := testStateFile(t, state)
   452  
   453  	ui := new(cli.MockUi)
   454  	c := &UntaintCommand{
   455  		Meta: Meta{
   456  			Ui: ui,
   457  		},
   458  	}
   459  
   460  	args := []string{
   461  		"-module=child",
   462  		"-state", statePath,
   463  		"test_instance.blah",
   464  	}
   465  	if code := c.Run(args); code != 0 {
   466  		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
   467  	}
   468  
   469  	testStateOutput(t, statePath, strings.TrimSpace(`
   470  test_instance.foo: (1 tainted)
   471    ID = <not created>
   472    Tainted ID 1 = bar
   473  
   474  module.child:
   475    test_instance.blah:
   476      ID = bar
   477  	`))
   478  }