github.com/shvar/terraform@v0.6.9-0.20151215234924-3365cd2231df/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go (about) 1 package vsphere 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/terraform" 10 "github.com/vmware/govmomi" 11 "github.com/vmware/govmomi/find" 12 "github.com/vmware/govmomi/object" 13 "github.com/vmware/govmomi/property" 14 "github.com/vmware/govmomi/vim25/mo" 15 "github.com/vmware/govmomi/vim25/types" 16 "golang.org/x/net/context" 17 ) 18 19 func TestAccVSphereVirtualMachine_basic(t *testing.T) { 20 var vm virtualMachine 21 var locationOpt string 22 var datastoreOpt string 23 24 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 25 locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v) 26 } 27 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 28 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 29 } 30 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 31 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 32 } 33 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 34 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 35 } 36 template := os.Getenv("VSPHERE_TEMPLATE") 37 gateway := os.Getenv("VSPHERE_NETWORK_GATEWAY") 38 label := os.Getenv("VSPHERE_NETWORK_LABEL") 39 ip_address := os.Getenv("VSPHERE_NETWORK_IP_ADDRESS") 40 41 resource.Test(t, resource.TestCase{ 42 PreCheck: func() { testAccPreCheck(t) }, 43 Providers: testAccProviders, 44 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 45 Steps: []resource.TestStep{ 46 resource.TestStep{ 47 Config: fmt.Sprintf( 48 testAccCheckVSphereVirtualMachineConfig_basic, 49 locationOpt, 50 gateway, 51 label, 52 ip_address, 53 datastoreOpt, 54 template, 55 ), 56 Check: resource.ComposeTestCheckFunc( 57 testAccCheckVSphereVirtualMachineExists("vsphere_virtual_machine.foo", &vm), 58 resource.TestCheckResourceAttr( 59 "vsphere_virtual_machine.foo", "name", "terraform-test"), 60 resource.TestCheckResourceAttr( 61 "vsphere_virtual_machine.foo", "vcpu", "2"), 62 resource.TestCheckResourceAttr( 63 "vsphere_virtual_machine.foo", "memory", "4096"), 64 resource.TestCheckResourceAttr( 65 "vsphere_virtual_machine.foo", "disk.#", "2"), 66 resource.TestCheckResourceAttr( 67 "vsphere_virtual_machine.foo", "disk.0.template", template), 68 resource.TestCheckResourceAttr( 69 "vsphere_virtual_machine.foo", "network_interface.#", "1"), 70 resource.TestCheckResourceAttr( 71 "vsphere_virtual_machine.foo", "network_interface.0.label", label), 72 ), 73 }, 74 }, 75 }) 76 } 77 78 func TestAccVSphereVirtualMachine_dhcp(t *testing.T) { 79 var vm virtualMachine 80 var locationOpt string 81 var datastoreOpt string 82 83 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 84 locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v) 85 } 86 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 87 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 88 } 89 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 90 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 91 } 92 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 93 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 94 } 95 template := os.Getenv("VSPHERE_TEMPLATE") 96 label := os.Getenv("VSPHERE_NETWORK_LABEL_DHCP") 97 98 resource.Test(t, resource.TestCase{ 99 PreCheck: func() { testAccPreCheck(t) }, 100 Providers: testAccProviders, 101 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 102 Steps: []resource.TestStep{ 103 resource.TestStep{ 104 Config: fmt.Sprintf( 105 testAccCheckVSphereVirtualMachineConfig_dhcp, 106 locationOpt, 107 label, 108 datastoreOpt, 109 template, 110 ), 111 Check: resource.ComposeTestCheckFunc( 112 testAccCheckVSphereVirtualMachineExists("vsphere_virtual_machine.bar", &vm), 113 resource.TestCheckResourceAttr( 114 "vsphere_virtual_machine.bar", "name", "terraform-test"), 115 resource.TestCheckResourceAttr( 116 "vsphere_virtual_machine.bar", "vcpu", "2"), 117 resource.TestCheckResourceAttr( 118 "vsphere_virtual_machine.bar", "memory", "4096"), 119 resource.TestCheckResourceAttr( 120 "vsphere_virtual_machine.bar", "disk.#", "1"), 121 resource.TestCheckResourceAttr( 122 "vsphere_virtual_machine.bar", "disk.0.template", template), 123 resource.TestCheckResourceAttr( 124 "vsphere_virtual_machine.bar", "network_interface.#", "1"), 125 resource.TestCheckResourceAttr( 126 "vsphere_virtual_machine.bar", "network_interface.0.label", label), 127 ), 128 }, 129 }, 130 }) 131 } 132 133 func TestAccVSphereVirtualMachine_custom_configs(t *testing.T) { 134 var vm virtualMachine 135 var locationOpt string 136 var datastoreOpt string 137 138 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 139 locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v) 140 } 141 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 142 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 143 } 144 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 145 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 146 } 147 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 148 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 149 } 150 template := os.Getenv("VSPHERE_TEMPLATE") 151 label := os.Getenv("VSPHERE_NETWORK_LABEL_DHCP") 152 153 resource.Test(t, resource.TestCase{ 154 PreCheck: func() { testAccPreCheck(t) }, 155 Providers: testAccProviders, 156 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 157 Steps: []resource.TestStep{ 158 resource.TestStep{ 159 Config: fmt.Sprintf( 160 testAccCheckVSphereVirtualMachineConfig_custom_configs, 161 locationOpt, 162 label, 163 datastoreOpt, 164 template, 165 ), 166 Check: resource.ComposeTestCheckFunc( 167 testAccCheckVSphereVirtualMachineExistsHasCustomConfig("vsphere_virtual_machine.car", &vm), 168 resource.TestCheckResourceAttr( 169 "vsphere_virtual_machine.car", "name", "terraform-test-custom"), 170 resource.TestCheckResourceAttr( 171 "vsphere_virtual_machine.car", "vcpu", "2"), 172 resource.TestCheckResourceAttr( 173 "vsphere_virtual_machine.car", "memory", "4096"), 174 resource.TestCheckResourceAttr( 175 "vsphere_virtual_machine.car", "disk.#", "1"), 176 resource.TestCheckResourceAttr( 177 "vsphere_virtual_machine.car", "disk.0.template", template), 178 resource.TestCheckResourceAttr( 179 "vsphere_virtual_machine.car", "network_interface.#", "1"), 180 resource.TestCheckResourceAttr( 181 "vsphere_virtual_machine.car", "custom_configuration_parameters.foo", "bar"), 182 resource.TestCheckResourceAttr( 183 "vsphere_virtual_machine.car", "custom_configuration_parameters.car", "ferrari"), 184 resource.TestCheckResourceAttr( 185 "vsphere_virtual_machine.car", "custom_configuration_parameters.num", "42"), 186 resource.TestCheckResourceAttr( 187 "vsphere_virtual_machine.car", "network_interface.0.label", label), 188 ), 189 }, 190 }, 191 }) 192 } 193 194 func TestAccVSphereVirtualMachine_createInExistingFolder(t *testing.T) { 195 var vm virtualMachine 196 var locationOpt string 197 var datastoreOpt string 198 var datacenter string 199 200 folder := "tf_test_createInExistingFolder" 201 202 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 203 locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v) 204 datacenter = v 205 } 206 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 207 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 208 } 209 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 210 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 211 } 212 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 213 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 214 } 215 template := os.Getenv("VSPHERE_TEMPLATE") 216 label := os.Getenv("VSPHERE_NETWORK_LABEL_DHCP") 217 218 resource.Test(t, resource.TestCase{ 219 PreCheck: func() { testAccPreCheck(t) }, 220 Providers: testAccProviders, 221 CheckDestroy: resource.ComposeTestCheckFunc( 222 testAccCheckVSphereVirtualMachineDestroy, 223 removeVSphereFolder(datacenter, folder, ""), 224 ), 225 Steps: []resource.TestStep{ 226 resource.TestStep{ 227 PreConfig: func() { createVSphereFolder(datacenter, folder) }, 228 Config: fmt.Sprintf( 229 testAccCheckVSphereVirtualMachineConfig_createInFolder, 230 folder, 231 locationOpt, 232 label, 233 datastoreOpt, 234 template, 235 ), 236 Check: resource.ComposeTestCheckFunc( 237 testAccCheckVSphereVirtualMachineExists("vsphere_virtual_machine.folder", &vm), 238 resource.TestCheckResourceAttr( 239 "vsphere_virtual_machine.folder", "name", "terraform-test-folder"), 240 resource.TestCheckResourceAttr( 241 "vsphere_virtual_machine.folder", "folder", folder), 242 resource.TestCheckResourceAttr( 243 "vsphere_virtual_machine.folder", "vcpu", "2"), 244 resource.TestCheckResourceAttr( 245 "vsphere_virtual_machine.folder", "memory", "4096"), 246 resource.TestCheckResourceAttr( 247 "vsphere_virtual_machine.folder", "disk.#", "1"), 248 resource.TestCheckResourceAttr( 249 "vsphere_virtual_machine.folder", "disk.0.template", template), 250 resource.TestCheckResourceAttr( 251 "vsphere_virtual_machine.folder", "network_interface.#", "1"), 252 resource.TestCheckResourceAttr( 253 "vsphere_virtual_machine.folder", "network_interface.0.label", label), 254 ), 255 }, 256 }, 257 }) 258 } 259 260 func TestAccVSphereVirtualMachine_createWithFolder(t *testing.T) { 261 var vm virtualMachine 262 var f folder 263 var locationOpt string 264 var folderLocationOpt string 265 var datastoreOpt string 266 267 folder := "tf_test_createWithFolder" 268 269 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 270 folderLocationOpt = fmt.Sprintf(" datacenter = \"%s\"\n", v) 271 locationOpt += folderLocationOpt 272 } 273 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 274 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 275 } 276 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 277 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 278 } 279 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 280 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 281 } 282 template := os.Getenv("VSPHERE_TEMPLATE") 283 label := os.Getenv("VSPHERE_NETWORK_LABEL_DHCP") 284 285 resource.Test(t, resource.TestCase{ 286 PreCheck: func() { testAccPreCheck(t) }, 287 Providers: testAccProviders, 288 CheckDestroy: resource.ComposeTestCheckFunc( 289 testAccCheckVSphereVirtualMachineDestroy, 290 testAccCheckVSphereFolderDestroy, 291 ), 292 Steps: []resource.TestStep{ 293 resource.TestStep{ 294 Config: fmt.Sprintf( 295 testAccCheckVSphereVirtualMachineConfig_createWithFolder, 296 folder, 297 folderLocationOpt, 298 locationOpt, 299 label, 300 datastoreOpt, 301 template, 302 ), 303 Check: resource.ComposeTestCheckFunc( 304 testAccCheckVSphereVirtualMachineExists("vsphere_virtual_machine.with_folder", &vm), 305 testAccCheckVSphereFolderExists("vsphere_folder.with_folder", &f), 306 resource.TestCheckResourceAttr( 307 "vsphere_virtual_machine.with_folder", "name", "terraform-test-with-folder"), 308 // resource.TestCheckResourceAttr( 309 // "vsphere_virtual_machine.with_folder", "folder", folder), 310 resource.TestCheckResourceAttr( 311 "vsphere_virtual_machine.with_folder", "vcpu", "2"), 312 resource.TestCheckResourceAttr( 313 "vsphere_virtual_machine.with_folder", "memory", "4096"), 314 resource.TestCheckResourceAttr( 315 "vsphere_virtual_machine.with_folder", "disk.#", "1"), 316 resource.TestCheckResourceAttr( 317 "vsphere_virtual_machine.with_folder", "disk.0.template", template), 318 resource.TestCheckResourceAttr( 319 "vsphere_virtual_machine.with_folder", "network_interface.#", "1"), 320 resource.TestCheckResourceAttr( 321 "vsphere_virtual_machine.with_folder", "network_interface.0.label", label), 322 ), 323 }, 324 }, 325 }) 326 } 327 328 func testAccCheckVSphereVirtualMachineDestroy(s *terraform.State) error { 329 client := testAccProvider.Meta().(*govmomi.Client) 330 finder := find.NewFinder(client.Client, true) 331 332 for _, rs := range s.RootModule().Resources { 333 if rs.Type != "vsphere_virtual_machine" { 334 continue 335 } 336 337 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 338 if err != nil { 339 return fmt.Errorf("error %s", err) 340 } 341 342 dcFolders, err := dc.Folders(context.TODO()) 343 if err != nil { 344 return fmt.Errorf("error %s", err) 345 } 346 347 348 folder := dcFolders.VmFolder 349 if len(rs.Primary.Attributes["folder"]) > 0 { 350 si := object.NewSearchIndex(client.Client) 351 folderRef, err := si.FindByInventoryPath( 352 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 353 if err != nil { 354 return err 355 } else if folderRef != nil { 356 folder = folderRef.(*object.Folder) 357 } 358 } 359 360 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 361 362 if err == nil { 363 return fmt.Errorf("Record still exists") 364 } 365 } 366 367 return nil 368 } 369 370 func testAccCheckVSphereVirtualMachineExistsHasCustomConfig(n string, vm *virtualMachine) resource.TestCheckFunc { 371 return func(s *terraform.State) error { 372 373 374 rs, ok := s.RootModule().Resources[n] 375 if !ok { 376 return fmt.Errorf("Not found: %s", n) 377 } 378 379 if rs.Primary.ID == "" { 380 return fmt.Errorf("No ID is set") 381 } 382 383 client := testAccProvider.Meta().(*govmomi.Client) 384 finder := find.NewFinder(client.Client, true) 385 386 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 387 if err != nil { 388 return fmt.Errorf("error %s", err) 389 } 390 391 dcFolders, err := dc.Folders(context.TODO()) 392 if err != nil { 393 return fmt.Errorf("error %s", err) 394 } 395 396 397 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), dcFolders.VmFolder, rs.Primary.Attributes["name"]) 398 if err != nil { 399 return fmt.Errorf("error %s", err) 400 } 401 402 finder = finder.SetDatacenter(dc) 403 instance, err := finder.VirtualMachine(context.TODO(), rs.Primary.Attributes["name"]) 404 if err != nil { 405 return fmt.Errorf("error %s", err) 406 } 407 408 var mvm mo.VirtualMachine 409 410 collector := property.DefaultCollector(client.Client) 411 412 if err := collector.RetrieveOne(context.TODO(), instance.Reference(), []string{"config.extraConfig"}, &mvm); err != nil { 413 return fmt.Errorf("error %s", err) 414 } 415 416 var configMap = make(map[string]types.AnyType) 417 if mvm.Config != nil && mvm.Config.ExtraConfig != nil && len(mvm.Config.ExtraConfig) > 0 { 418 for _, v := range mvm.Config.ExtraConfig { 419 value := v.GetOptionValue() 420 configMap[value.Key] = value.Value 421 } 422 } else { 423 return fmt.Errorf("error no ExtraConfig") 424 } 425 426 if configMap["foo"] == nil { 427 return fmt.Errorf("error no ExtraConfig for 'foo'") 428 } 429 430 if configMap["foo"] != "bar" { 431 return fmt.Errorf("error ExtraConfig 'foo' != bar") 432 } 433 434 if configMap["car"] == nil { 435 return fmt.Errorf("error no ExtraConfig for 'car'") 436 } 437 438 if configMap["car"] != "ferrari" { 439 return fmt.Errorf("error ExtraConfig 'car' != ferrari") 440 } 441 442 if configMap["num"] == nil { 443 return fmt.Errorf("error no ExtraConfig for 'num'") 444 } 445 446 // todo this should be an int, getting back a string 447 if configMap["num"] != "42" { 448 return fmt.Errorf("error ExtraConfig 'num' != 42") 449 } 450 *vm = virtualMachine{ 451 name: rs.Primary.ID, 452 } 453 454 return nil 455 } 456 } 457 458 func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resource.TestCheckFunc { 459 return func(s *terraform.State) error { 460 rs, ok := s.RootModule().Resources[n] 461 if !ok { 462 return fmt.Errorf("Not found: %s", n) 463 } 464 465 if rs.Primary.ID == "" { 466 return fmt.Errorf("No ID is set") 467 } 468 469 client := testAccProvider.Meta().(*govmomi.Client) 470 finder := find.NewFinder(client.Client, true) 471 472 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 473 if err != nil { 474 return fmt.Errorf("error %s", err) 475 } 476 477 dcFolders, err := dc.Folders(context.TODO()) 478 if err != nil { 479 return fmt.Errorf("error %s", err) 480 } 481 482 folder := dcFolders.VmFolder 483 if len(rs.Primary.Attributes["folder"]) > 0 { 484 si := object.NewSearchIndex(client.Client) 485 folderRef, err := si.FindByInventoryPath( 486 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 487 if err != nil { 488 return err 489 } else if folderRef != nil { 490 folder = folderRef.(*object.Folder) 491 } 492 } 493 494 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 495 496 497 *vm = virtualMachine{ 498 name: rs.Primary.ID, 499 } 500 501 return nil 502 } 503 } 504 505 const testAccCheckVSphereVirtualMachineConfig_basic = ` 506 resource "vsphere_virtual_machine" "foo" { 507 name = "terraform-test" 508 %s 509 vcpu = 2 510 memory = 4096 511 gateway = "%s" 512 network_interface { 513 label = "%s" 514 ipv4_address = "%s" 515 ipv4_prefix_length = 24 516 } 517 disk { 518 %s 519 template = "%s" 520 iops = 500 521 } 522 disk { 523 size = 1 524 iops = 500 525 } 526 } 527 ` 528 const testAccCheckVSphereVirtualMachineConfig_dhcp = ` 529 resource "vsphere_virtual_machine" "bar" { 530 name = "terraform-test" 531 %s 532 vcpu = 2 533 memory = 4096 534 network_interface { 535 label = "%s" 536 } 537 disk { 538 %s 539 template = "%s" 540 } 541 } 542 ` 543 544 const testAccCheckVSphereVirtualMachineConfig_custom_configs = ` 545 resource "vsphere_virtual_machine" "car" { 546 name = "terraform-test-custom" 547 %s 548 vcpu = 2 549 memory = 4096 550 network_interface { 551 label = "%s" 552 } 553 custom_configuration_parameters { 554 "foo" = "bar" 555 "car" = "ferrari" 556 "num" = 42 557 } 558 disk { 559 %s 560 template = "%s" 561 } 562 } 563 ` 564 565 const testAccCheckVSphereVirtualMachineConfig_createInFolder = ` 566 resource "vsphere_virtual_machine" "folder" { 567 name = "terraform-test-folder" 568 folder = "%s" 569 %s 570 vcpu = 2 571 memory = 4096 572 network_interface { 573 label = "%s" 574 } 575 disk { 576 %s 577 template = "%s" 578 } 579 } 580 ` 581 582 const testAccCheckVSphereVirtualMachineConfig_createWithFolder = ` 583 resource "vsphere_folder" "with_folder" { 584 path = "%s" 585 %s 586 } 587 resource "vsphere_virtual_machine" "with_folder" { 588 name = "terraform-test-with-folder" 589 folder = "${vsphere_folder.with_folder.path}" 590 %s 591 vcpu = 2 592 memory = 4096 593 network_interface { 594 label = "%s" 595 } 596 disk { 597 %s 598 template = "%s" 599 } 600 } 601 `