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 }