github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/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 folder := dcFolders.VmFolder 348 if len(rs.Primary.Attributes["folder"]) > 0 { 349 si := object.NewSearchIndex(client.Client) 350 folderRef, err := si.FindByInventoryPath( 351 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 352 if err != nil { 353 return err 354 } else if folderRef != nil { 355 folder = folderRef.(*object.Folder) 356 } 357 } 358 359 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 360 361 if err == nil { 362 return fmt.Errorf("Record still exists") 363 } 364 } 365 366 return nil 367 } 368 369 func testAccCheckVSphereVirtualMachineExistsHasCustomConfig(n string, vm *virtualMachine) resource.TestCheckFunc { 370 return func(s *terraform.State) error { 371 372 rs, ok := s.RootModule().Resources[n] 373 if !ok { 374 return fmt.Errorf("Not found: %s", n) 375 } 376 377 if rs.Primary.ID == "" { 378 return fmt.Errorf("No ID is set") 379 } 380 381 client := testAccProvider.Meta().(*govmomi.Client) 382 finder := find.NewFinder(client.Client, true) 383 384 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 385 if err != nil { 386 return fmt.Errorf("error %s", err) 387 } 388 389 dcFolders, err := dc.Folders(context.TODO()) 390 if err != nil { 391 return fmt.Errorf("error %s", err) 392 } 393 394 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), dcFolders.VmFolder, rs.Primary.Attributes["name"]) 395 if err != nil { 396 return fmt.Errorf("error %s", err) 397 } 398 399 finder = finder.SetDatacenter(dc) 400 instance, err := finder.VirtualMachine(context.TODO(), rs.Primary.Attributes["name"]) 401 if err != nil { 402 return fmt.Errorf("error %s", err) 403 } 404 405 var mvm mo.VirtualMachine 406 407 collector := property.DefaultCollector(client.Client) 408 409 if err := collector.RetrieveOne(context.TODO(), instance.Reference(), []string{"config.extraConfig"}, &mvm); err != nil { 410 return fmt.Errorf("error %s", err) 411 } 412 413 var configMap = make(map[string]types.AnyType) 414 if mvm.Config != nil && mvm.Config.ExtraConfig != nil && len(mvm.Config.ExtraConfig) > 0 { 415 for _, v := range mvm.Config.ExtraConfig { 416 value := v.GetOptionValue() 417 configMap[value.Key] = value.Value 418 } 419 } else { 420 return fmt.Errorf("error no ExtraConfig") 421 } 422 423 if configMap["foo"] == nil { 424 return fmt.Errorf("error no ExtraConfig for 'foo'") 425 } 426 427 if configMap["foo"] != "bar" { 428 return fmt.Errorf("error ExtraConfig 'foo' != bar") 429 } 430 431 if configMap["car"] == nil { 432 return fmt.Errorf("error no ExtraConfig for 'car'") 433 } 434 435 if configMap["car"] != "ferrari" { 436 return fmt.Errorf("error ExtraConfig 'car' != ferrari") 437 } 438 439 if configMap["num"] == nil { 440 return fmt.Errorf("error no ExtraConfig for 'num'") 441 } 442 443 // todo this should be an int, getting back a string 444 if configMap["num"] != "42" { 445 return fmt.Errorf("error ExtraConfig 'num' != 42") 446 } 447 *vm = virtualMachine{ 448 name: rs.Primary.ID, 449 } 450 451 return nil 452 } 453 } 454 455 func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resource.TestCheckFunc { 456 return func(s *terraform.State) error { 457 rs, ok := s.RootModule().Resources[n] 458 if !ok { 459 return fmt.Errorf("Not found: %s", n) 460 } 461 462 if rs.Primary.ID == "" { 463 return fmt.Errorf("No ID is set") 464 } 465 466 client := testAccProvider.Meta().(*govmomi.Client) 467 finder := find.NewFinder(client.Client, true) 468 469 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 470 if err != nil { 471 return fmt.Errorf("error %s", err) 472 } 473 474 dcFolders, err := dc.Folders(context.TODO()) 475 if err != nil { 476 return fmt.Errorf("error %s", err) 477 } 478 479 folder := dcFolders.VmFolder 480 if len(rs.Primary.Attributes["folder"]) > 0 { 481 si := object.NewSearchIndex(client.Client) 482 folderRef, err := si.FindByInventoryPath( 483 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 484 if err != nil { 485 return err 486 } else if folderRef != nil { 487 folder = folderRef.(*object.Folder) 488 } 489 } 490 491 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 492 493 *vm = virtualMachine{ 494 name: rs.Primary.ID, 495 } 496 497 return nil 498 } 499 } 500 501 const testAccCheckVSphereVirtualMachineConfig_basic = ` 502 resource "vsphere_virtual_machine" "foo" { 503 name = "terraform-test" 504 %s 505 vcpu = 2 506 memory = 4096 507 gateway = "%s" 508 network_interface { 509 label = "%s" 510 ipv4_address = "%s" 511 ipv4_prefix_length = 24 512 } 513 disk { 514 %s 515 template = "%s" 516 iops = 500 517 } 518 disk { 519 size = 1 520 iops = 500 521 } 522 } 523 ` 524 const testAccCheckVSphereVirtualMachineConfig_dhcp = ` 525 resource "vsphere_virtual_machine" "bar" { 526 name = "terraform-test" 527 %s 528 vcpu = 2 529 memory = 4096 530 network_interface { 531 label = "%s" 532 } 533 disk { 534 %s 535 template = "%s" 536 } 537 } 538 ` 539 540 const testAccCheckVSphereVirtualMachineConfig_custom_configs = ` 541 resource "vsphere_virtual_machine" "car" { 542 name = "terraform-test-custom" 543 %s 544 vcpu = 2 545 memory = 4096 546 network_interface { 547 label = "%s" 548 } 549 custom_configuration_parameters { 550 "foo" = "bar" 551 "car" = "ferrari" 552 "num" = 42 553 } 554 disk { 555 %s 556 template = "%s" 557 } 558 } 559 ` 560 561 const testAccCheckVSphereVirtualMachineConfig_createInFolder = ` 562 resource "vsphere_virtual_machine" "folder" { 563 name = "terraform-test-folder" 564 folder = "%s" 565 %s 566 vcpu = 2 567 memory = 4096 568 network_interface { 569 label = "%s" 570 } 571 disk { 572 %s 573 template = "%s" 574 } 575 } 576 ` 577 578 const testAccCheckVSphereVirtualMachineConfig_createWithFolder = ` 579 resource "vsphere_folder" "with_folder" { 580 path = "%s" 581 %s 582 } 583 resource "vsphere_virtual_machine" "with_folder" { 584 name = "terraform-test-with-folder" 585 folder = "${vsphere_folder.with_folder.path}" 586 %s 587 vcpu = 2 588 memory = 4096 589 network_interface { 590 label = "%s" 591 } 592 disk { 593 %s 594 template = "%s" 595 } 596 } 597 `