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