github.com/boyvanduuren/terraform@v0.7.0-rc2.0.20160805175930-de822d909c40/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go (about) 1 package vsphere 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "regexp" 8 "testing" 9 10 "path/filepath" 11 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/terraform" 14 "github.com/vmware/govmomi" 15 "github.com/vmware/govmomi/find" 16 "github.com/vmware/govmomi/object" 17 "github.com/vmware/govmomi/property" 18 "github.com/vmware/govmomi/vim25/mo" 19 "github.com/vmware/govmomi/vim25/types" 20 "golang.org/x/net/context" 21 ) 22 23 /////// 24 // Various ENV vars are used to setup these tests. Look for `os.Getenv` 25 /////// 26 27 // Base setup function to check that a template, and nic information is set 28 // TODO needs some TLC - determine exactly how we want to do this 29 func testBasicPreCheck(t *testing.T) { 30 31 testAccPreCheck(t) 32 33 if v := os.Getenv("VSPHERE_TEMPLATE"); v == "" { 34 t.Fatal("env variable VSPHERE_TEMPLATE must be set for acceptance tests") 35 } 36 37 if v := os.Getenv("VSPHERE_IPV4_GATEWAY"); v == "" { 38 t.Fatal("env variable VSPHERE_IPV4_GATEWAY must be set for acceptance tests") 39 } 40 41 if v := os.Getenv("VSPHERE_IPV4_ADDRESS"); v == "" { 42 t.Fatal("env variable VSPHERE_IPV4_ADDRESS must be set for acceptance tests") 43 } 44 45 if v := os.Getenv("VSPHERE_NETWORK_LABEL"); v == "" { 46 t.Fatal("env variable VSPHERE_NETWORK_LABEL must be set for acceptance tests") 47 } 48 } 49 50 //// 51 // Collects optional env vars used in the tests 52 //// 53 func setupBaseVars() (string, string) { 54 var locationOpt string 55 var datastoreOpt string 56 57 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 58 locationOpt += fmt.Sprintf(" datacenter = \"%s\"\n", v) 59 } 60 if v := os.Getenv("VSPHERE_CLUSTER"); v != "" { 61 locationOpt += fmt.Sprintf(" cluster = \"%s\"\n", v) 62 } 63 if v := os.Getenv("VSPHERE_RESOURCE_POOL"); v != "" { 64 locationOpt += fmt.Sprintf(" resource_pool = \"%s\"\n", v) 65 } 66 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 67 datastoreOpt = fmt.Sprintf(" datastore = \"%s\"\n", v) 68 } 69 70 return locationOpt, datastoreOpt 71 } 72 73 //// 74 // Structs and funcs used with DHCP data template 75 //// 76 type TestDHCPBodyData struct { 77 template string 78 locationOpt string 79 datastoreOpt string 80 label string 81 } 82 83 func (body TestDHCPBodyData) parseDHCPTemplateConfigWithTemplate(template string) string { 84 return fmt.Sprintf( 85 template, 86 body.locationOpt, 87 body.label, 88 body.datastoreOpt, 89 body.template, 90 ) 91 92 } 93 94 const testAccCheckVSphereTemplate_dhcp = ` 95 %s 96 vcpu = 2 97 memory = 1024 98 network_interface { 99 label = "%s" 100 } 101 disk { 102 %s 103 template = "%s" 104 } 105 } 106 ` 107 108 // replaces data in the above template 109 func (body TestDHCPBodyData) parseDHCPTemplateConfig() string { 110 return fmt.Sprintf( 111 testAccCheckVSphereTemplate_dhcp, 112 body.locationOpt, 113 body.label, 114 body.datastoreOpt, 115 body.template, 116 ) 117 } 118 119 func (body TestDHCPBodyData) testSprintfDHCPTemplateBodySecondArgDynamic(template string, arg string) string { 120 return fmt.Sprintf( 121 template, 122 body.locationOpt, 123 arg, 124 body.label, 125 body.datastoreOpt, 126 body.template, 127 ) 128 } 129 130 // returns variables that are used in DHCP tests 131 func setupTemplateFuncDHCPData() TestDHCPBodyData { 132 133 locationOpt, datastoreOpt := setupBaseVars() 134 data := TestDHCPBodyData{ 135 template: os.Getenv("VSPHERE_TEMPLATE"), 136 label: os.Getenv("VSPHERE_NETWORK_LABEL_DHCP"), 137 locationOpt: locationOpt, 138 datastoreOpt: datastoreOpt, 139 } 140 // log.Printf("[DEBUG] basic vars= %v", data) 141 return data 142 143 } 144 145 //// 146 // Structs and funcs used with static ip data templates 147 //// 148 type TemplateBasicBodyVars struct { 149 locationOpt string 150 label string 151 ipv4IpAddress string 152 ipv4Prefix string 153 ipv4Gateway string 154 datastoreOpt string 155 template string 156 } 157 158 // Takes a base template that has seven "%s" values in it, used by most fixed ip 159 // tests 160 func (body TemplateBasicBodyVars) testSprintfTemplateBody(template string) string { 161 162 return fmt.Sprintf( 163 template, 164 body.locationOpt, 165 body.label, 166 body.ipv4IpAddress, 167 body.ipv4Prefix, 168 body.ipv4Gateway, 169 body.datastoreOpt, 170 body.template, 171 ) 172 } 173 174 // setups variables used by fixed ip tests 175 func setupTemplateBasicBodyVars() TemplateBasicBodyVars { 176 177 locationOpt, datastoreOpt := setupBaseVars() 178 prefix := os.Getenv("VSPHERE_IPV4_PREFIX") 179 if prefix == "" { 180 prefix = "24" 181 } 182 data := TemplateBasicBodyVars{ 183 template: os.Getenv("VSPHERE_TEMPLATE"), 184 ipv4Gateway: os.Getenv("VSPHERE_IPV4_GATEWAY"), 185 label: os.Getenv("VSPHERE_NETWORK_LABEL"), 186 ipv4IpAddress: os.Getenv("VSPHERE_IPV4_ADDRESS"), 187 ipv4Prefix: prefix, 188 locationOpt: locationOpt, 189 datastoreOpt: datastoreOpt, 190 } 191 // log.Printf("[DEBUG] basic vars= %v", data) 192 return data 193 } 194 195 //// 196 // Basic data to create series of testing functions 197 //// 198 type TestFuncData struct { 199 vm virtualMachine 200 label string 201 vmName string 202 vmResource string 203 numDisks string 204 numCPU string 205 mem string 206 } 207 208 // returns TestCheckFunc's that are used in many of our tests 209 // mem defaults to 1024 210 // cpu defaults to 2 211 // disks defatuls to 1 212 // vmResource defaults to "terraform-test" 213 // vmName defaults to "vsphere_virtual_machine.foo 214 func (test TestFuncData) testCheckFuncBasic() ( 215 resource.TestCheckFunc, resource.TestCheckFunc, resource.TestCheckFunc, resource.TestCheckFunc, 216 resource.TestCheckFunc, resource.TestCheckFunc, resource.TestCheckFunc, resource.TestCheckFunc) { 217 // log.Printf("[DEBUG] data= %v", test) 218 mem := test.mem 219 if mem == "" { 220 mem = "1024" 221 } 222 cpu := test.numCPU 223 if cpu == "" { 224 cpu = "2" 225 } 226 disks := test.numDisks 227 if disks == "" { 228 disks = "1" 229 } 230 res := test.vmResource 231 if res == "" { 232 res = "terraform-test" 233 } 234 vmName := test.vmName 235 if vmName == "" { 236 vmName = "vsphere_virtual_machine.foo" 237 } 238 return testAccCheckVSphereVirtualMachineExists(vmName, &test.vm), 239 resource.TestCheckResourceAttr(vmName, "name", res), 240 resource.TestCheckResourceAttr(vmName, "vcpu", cpu), 241 resource.TestMatchResourceAttr(vmName, "uuid", regexp.MustCompile("[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}")), 242 resource.TestCheckResourceAttr(vmName, "memory", mem), 243 resource.TestCheckResourceAttr(vmName, "disk.#", disks), 244 resource.TestCheckResourceAttr(vmName, "network_interface.#", "1"), 245 resource.TestCheckResourceAttr(vmName, "network_interface.0.label", test.label) 246 } 247 248 const testAccCheckVSphereVirtualMachineConfig_really_basic = ` 249 resource "vsphere_virtual_machine" "foo" { 250 name = "terraform-test" 251 ` + testAccTemplateBasicBodyWithEnd 252 253 // WARNING this is one of the base templates. You change this and you will 254 // be impacting multiple tests 255 const testAccTemplateBasicBody = ` 256 %s 257 vcpu = 2 258 memory = 1024 259 network_interface { 260 label = "%s" 261 ipv4_address = "%s" 262 ipv4_prefix_length = %s 263 ipv4_gateway = "%s" 264 } 265 disk { 266 %s 267 template = "%s" 268 iops = 500 269 } 270 ` 271 const testAccTemplateBasicBodyWithEnd = testAccTemplateBasicBody + ` 272 }` 273 274 func TestAccVSphereVirtualMachine_basic(t *testing.T) { 275 var vm virtualMachine 276 basic_vars := setupTemplateBasicBodyVars() 277 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_really_basic) 278 279 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_really_basic) 280 log.Printf("[DEBUG] template config= %s", config) 281 282 resource.Test(t, resource.TestCase{ 283 PreCheck: func() { testBasicPreCheck(t) }, 284 Providers: testAccProviders, 285 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 286 Steps: []resource.TestStep{ 287 resource.TestStep{ 288 Config: config, 289 Check: resource.ComposeTestCheckFunc( 290 TestFuncData{vm: vm, label: basic_vars.label}.testCheckFuncBasic(), 291 ), 292 }, 293 }, 294 }) 295 } 296 297 const testAccCheckVSphereVirtualMachineConfig_debug = ` 298 provider "vsphere" { 299 client_debug = true 300 } 301 302 ` + testAccCheckVSphereVirtualMachineConfig_really_basic 303 304 func TestAccVSphereVirtualMachine_client_debug(t *testing.T) { 305 var vm virtualMachine 306 basic_vars := setupTemplateBasicBodyVars() 307 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_debug) 308 309 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_debug) 310 log.Printf("[DEBUG] template config= %s", config) 311 312 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 313 TestFuncData{vm: vm, label: basic_vars.label}.testCheckFuncBasic() 314 315 resource.Test(t, resource.TestCase{ 316 PreCheck: func() { testBasicPreCheck(t) }, 317 Providers: testAccProviders, 318 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 319 Steps: []resource.TestStep{ 320 resource.TestStep{ 321 Config: config, 322 Check: resource.ComposeTestCheckFunc( 323 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 324 testAccCheckDebugExists(), 325 ), 326 }, 327 }, 328 }) 329 } 330 331 const testAccCheckVSphereVirtualMachineConfig_diskSCSICapacity = ` 332 resource "vsphere_virtual_machine" "scsiCapacity" { 333 name = "terraform-test" 334 ` + testAccTemplateBasicBody + ` 335 disk { 336 size = 1 337 controller_type = "scsi-paravirtual" 338 name = "one" 339 } 340 disk { 341 size = 1 342 controller_type = "scsi-paravirtual" 343 name = "two" 344 } 345 disk { 346 size = 1 347 controller_type = "scsi-paravirtual" 348 name = "three" 349 } 350 disk { 351 size = 1 352 controller_type = "scsi-paravirtual" 353 name = "four" 354 } 355 disk { 356 size = 1 357 controller_type = "scsi-paravirtual" 358 name = "five" 359 } 360 disk { 361 size = 1 362 controller_type = "scsi-paravirtual" 363 name = "six" 364 } 365 disk { 366 size = 1 367 controller_type = "scsi-paravirtual" 368 name = "seven" 369 } 370 } 371 ` 372 373 func TestAccVSphereVirtualMachine_diskSCSICapacity(t *testing.T) { 374 var vm virtualMachine 375 basic_vars := setupTemplateBasicBodyVars() 376 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_diskSCSICapacity) 377 378 vmName := "vsphere_virtual_machine.scsiCapacity" 379 380 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 381 TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "8"}.testCheckFuncBasic() 382 383 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_diskSCSICapacity) 384 log.Printf("[DEBUG] template config= %s", config) 385 386 resource.Test(t, resource.TestCase{ 387 PreCheck: func() { testAccPreCheck(t) }, 388 Providers: testAccProviders, 389 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 390 Steps: []resource.TestStep{ 391 resource.TestStep{ 392 Config: config, 393 Check: resource.ComposeTestCheckFunc( 394 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 395 ), 396 }, 397 }, 398 }) 399 } 400 401 const testAccCheckVSphereVirtualMachineConfig_initType = ` 402 resource "vsphere_virtual_machine" "thin" { 403 name = "terraform-test" 404 ` + testAccTemplateBasicBody + ` 405 disk { 406 size = 1 407 iops = 500 408 controller_type = "scsi" 409 name = "one" 410 } 411 disk { 412 size = 1 413 controller_type = "ide" 414 type = "eager_zeroed" 415 name = "two" 416 } 417 } 418 ` 419 420 func TestAccVSphereVirtualMachine_diskInitType(t *testing.T) { 421 var vm virtualMachine 422 basic_vars := setupTemplateBasicBodyVars() 423 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initType) 424 425 vmName := "vsphere_virtual_machine.thin" 426 427 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 428 TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "3"}.testCheckFuncBasic() 429 430 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_initType) 431 log.Printf("[DEBUG] template config= %s", config) 432 433 resource.Test(t, resource.TestCase{ 434 PreCheck: func() { testAccPreCheck(t) }, 435 Providers: testAccProviders, 436 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 437 Steps: []resource.TestStep{ 438 resource.TestStep{ 439 Config: config, 440 Check: resource.ComposeTestCheckFunc( 441 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 442 // FIXME dynmically calculate the hashes 443 resource.TestCheckResourceAttr(vmName, "disk.294918912.type", "eager_zeroed"), 444 resource.TestCheckResourceAttr(vmName, "disk.294918912.controller_type", "ide"), 445 resource.TestCheckResourceAttr(vmName, "disk.1380467090.controller_type", "scsi"), 446 ), 447 }, 448 }, 449 }) 450 } 451 452 const testAccCheckVSphereVirtualMachineConfig_dhcp = ` 453 resource "vsphere_virtual_machine" "bar" { 454 name = "terraform-test" 455 ` 456 457 func TestAccVSphereVirtualMachine_dhcp(t *testing.T) { 458 var vm virtualMachine 459 data := setupTemplateFuncDHCPData() 460 config := testAccCheckVSphereVirtualMachineConfig_dhcp + data.parseDHCPTemplateConfigWithTemplate(testAccCheckVSphereTemplate_dhcp) 461 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_dhcp+testAccCheckVSphereTemplate_dhcp) 462 log.Printf("[DEBUG] config= %s", config) 463 464 resource.Test(t, resource.TestCase{ 465 PreCheck: func() { testAccPreCheck(t) }, 466 Providers: testAccProviders, 467 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 468 Steps: []resource.TestStep{ 469 resource.TestStep{ 470 Config: config, 471 Check: resource.ComposeTestCheckFunc( 472 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 473 ), 474 }, 475 }, 476 }) 477 } 478 479 const testAccCheckVSphereVirtualMachineConfig_custom_configs = ` 480 resource "vsphere_virtual_machine" "car" { 481 name = "terraform-test-custom" 482 custom_configuration_parameters { 483 "foo" = "bar" 484 "car" = "ferrari" 485 "num" = 42 486 } 487 enable_disk_uuid = true 488 ` 489 490 func TestAccVSphereVirtualMachine_custom_configs(t *testing.T) { 491 492 var vm virtualMachine 493 data := setupTemplateFuncDHCPData() 494 config := testAccCheckVSphereVirtualMachineConfig_custom_configs + data.parseDHCPTemplateConfigWithTemplate(testAccCheckVSphereTemplate_dhcp) 495 vmName := "vsphere_virtual_machine.car" 496 res := "terraform-test-custom" 497 498 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 499 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: res}.testCheckFuncBasic() 500 501 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_custom_configs+testAccCheckVSphereTemplate_dhcp) 502 log.Printf("[DEBUG] config= %s", config) 503 504 resource.Test(t, resource.TestCase{ 505 PreCheck: func() { testAccPreCheck(t) }, 506 Providers: testAccProviders, 507 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 508 Steps: []resource.TestStep{ 509 resource.TestStep{ 510 Config: config, 511 Check: resource.ComposeTestCheckFunc( 512 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 513 testAccCheckVSphereVirtualMachineExistsHasCustomConfig(vmName, &vm), 514 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.foo", "bar"), 515 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.car", "ferrari"), 516 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.num", "42"), 517 resource.TestCheckResourceAttr(vmName, "enable_disk_uuid", "true"), 518 ), 519 }, 520 }, 521 }) 522 } 523 524 const testAccCheckVSphereVirtualMachineConfig_createInFolder = ` 525 resource "vsphere_virtual_machine" "folder" { 526 name = "terraform-test-folder" 527 folder = "%s" 528 ` 529 530 func TestAccVSphereVirtualMachine_createInExistingFolder(t *testing.T) { 531 var vm virtualMachine 532 datacenter := os.Getenv("VSPHERE_DATACENTER") 533 534 folder := "tf_test_cpureateInExistingFolder" 535 536 data := setupTemplateFuncDHCPData() 537 config := fmt.Sprintf(testAccCheckVSphereVirtualMachineConfig_createInFolder, 538 folder, 539 ) + data.parseDHCPTemplateConfig() 540 541 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_createInFolder) 542 log.Printf("[DEBUG] template config= %s", config) 543 544 resource.Test(t, resource.TestCase{ 545 PreCheck: func() { testAccPreCheck(t) }, 546 Providers: testAccProviders, 547 CheckDestroy: resource.ComposeTestCheckFunc( 548 testAccCheckVSphereVirtualMachineDestroy, 549 removeVSphereFolder(datacenter, folder, ""), 550 ), 551 Steps: []resource.TestStep{ 552 resource.TestStep{ 553 PreConfig: func() { createVSphereFolder(datacenter, folder) }, 554 Config: config, 555 Check: resource.ComposeTestCheckFunc( 556 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.folder", vmResource: "terraform-test-folder"}.testCheckFuncBasic(), 557 ), 558 }, 559 }, 560 }) 561 } 562 563 const testAccCheckVSphereVirtualMachineConfig_createWithFolder = ` 564 resource "vsphere_folder" "with_folder" { 565 path = "%s" 566 %s 567 } 568 resource "vsphere_virtual_machine" "with_folder" { 569 name = "terraform-test-with-folder" 570 folder = "${vsphere_folder.with_folder.path}" 571 ` 572 573 func TestAccVSphereVirtualMachine_createWithFolder(t *testing.T) { 574 var vm virtualMachine 575 var folderLocationOpt string 576 var f folder 577 578 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 579 folderLocationOpt = fmt.Sprintf(" datacenter = \"%s\"\n", v) 580 } 581 582 folder := "tf_test_cpureateWithFolder" 583 584 data := setupTemplateFuncDHCPData() 585 vmName := "vsphere_virtual_machine.with_folder" 586 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 587 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: "terraform-test-with-folder"}.testCheckFuncBasic() 588 589 config := fmt.Sprintf(testAccCheckVSphereVirtualMachineConfig_createWithFolder, 590 folder, 591 folderLocationOpt, 592 ) + data.parseDHCPTemplateConfig() 593 594 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_createWithFolder+testAccCheckVSphereTemplate_dhcp) 595 log.Printf("[DEBUG] template config= %s", config) 596 597 resource.Test(t, resource.TestCase{ 598 PreCheck: func() { testAccPreCheck(t) }, 599 Providers: testAccProviders, 600 CheckDestroy: resource.ComposeTestCheckFunc( 601 testAccCheckVSphereVirtualMachineDestroy, 602 testAccCheckVSphereFolderDestroy, 603 ), 604 Steps: []resource.TestStep{ 605 resource.TestStep{ 606 Config: config, 607 Check: resource.ComposeTestCheckFunc( 608 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 609 testAccCheckVSphereFolderExists(vmName, &f), 610 resource.TestCheckResourceAttr(vmName, "folder", folder), 611 ), 612 }, 613 }, 614 }) 615 } 616 617 const testAccCheckVsphereVirtualMachineConfig_cdrom = ` 618 resource "vsphere_virtual_machine" "with_cdrom" { 619 name = "terraform-test-with-cdrom" 620 cdrom { 621 datastore = "%s" 622 path = "%s" 623 } 624 ` 625 626 func TestAccVSphereVirtualMachine_createWithCdrom(t *testing.T) { 627 var vm virtualMachine 628 629 // FIXME check that these exist 630 cdromDatastore := os.Getenv("VSPHERE_CDROM_DATASTORE") 631 cdromPath := os.Getenv("VSPHERE_CDROM_PATH") 632 vmName := "vsphere_virtual_machine.with_cdrom" 633 634 data := setupTemplateFuncDHCPData() 635 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 636 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: "terraform-test-with-cdrom"}.testCheckFuncBasic() 637 638 config := fmt.Sprintf( 639 testAccCheckVsphereVirtualMachineConfig_cdrom, 640 cdromDatastore, 641 cdromPath, 642 ) + data.parseDHCPTemplateConfig() 643 644 log.Printf("[DEBUG] template= %s", testAccCheckVsphereVirtualMachineConfig_cdrom) 645 log.Printf("[DEBUG] template config= %s", config) 646 647 resource.Test(t, resource.TestCase{ 648 PreCheck: func() { testAccPreCheck(t) }, 649 Providers: testAccProviders, 650 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 651 Steps: []resource.TestStep{ 652 resource.TestStep{ 653 Config: config, 654 Check: resource.ComposeTestCheckFunc( 655 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 656 //resource.TestCheckResourceAttr( 657 // "vsphere_virtual_machine.with_cdrom", "disk.4088143748.template", template), 658 resource.TestCheckResourceAttr(vmName, "cdrom.#", "1"), 659 resource.TestCheckResourceAttr(vmName, "cdrom.0.datastore", cdromDatastore), 660 resource.TestCheckResourceAttr(vmName, "cdrom.0.path", cdromPath), 661 ), 662 }, 663 }, 664 }) 665 } 666 667 const testAccCheckVSphereVirtualMachineConfig_withExistingVmdk = ` 668 resource "vsphere_virtual_machine" "with_existing_vmdk" { 669 name = "terraform-test-with-existing-vmdk" 670 %s 671 vcpu = 2 672 memory = 1024 673 network_interface { 674 label = "%s" 675 } 676 disk { 677 %s 678 vmdk = "%s" 679 bootable = true 680 } 681 disk { 682 size = 1 683 iops = 500 684 name = "one" 685 } 686 } 687 ` 688 689 func TestAccVSphereVirtualMachine_createWithExistingVmdk(t *testing.T) { 690 var vm virtualMachine 691 vmdk_path := os.Getenv("VSPHERE_VMDK_PATH") 692 693 data := setupTemplateFuncDHCPData() 694 config := fmt.Sprintf( 695 testAccCheckVSphereVirtualMachineConfig_withExistingVmdk, 696 data.locationOpt, 697 data.label, 698 data.datastoreOpt, 699 vmdk_path, 700 ) 701 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_withExistingVmdk) 702 log.Printf("[DEBUG] template config= %s", config) 703 704 resource.Test(t, resource.TestCase{ 705 PreCheck: func() { testAccPreCheck(t) }, 706 Providers: testAccProviders, 707 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 708 Steps: []resource.TestStep{ 709 resource.TestStep{ 710 Config: config, 711 Check: resource.ComposeTestCheckFunc( 712 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.with_existing_vmdk", 713 vmResource: "terraform-test-with-existing-vmdk", numDisks: "2"}.testCheckFuncBasic(), 714 //resource.TestCheckResourceAttr( 715 // "vsphere_virtual_machine.with_existing_vmdk", "disk.2393891804.vmdk", vmdk_path), 716 //resource.TestCheckResourceAttr( 717 // "vsphere_virtual_machine.with_existing_vmdk", "disk.2393891804.bootable", "true"), 718 ), 719 }, 720 }, 721 }) 722 } 723 724 const testAccCheckVSphereVirtualMachineConfig_updateMemory = ` 725 resource "vsphere_virtual_machine" "bar" { 726 name = "terraform-test" 727 %s 728 vcpu = 2 729 memory = %s 730 network_interface { 731 label = "%s" 732 } 733 disk { 734 %s 735 template = "%s" 736 } 737 } 738 ` 739 740 func TestAccVSphereVirtualMachine_updateMemory(t *testing.T) { 741 var vm virtualMachine 742 data := setupTemplateFuncDHCPData() 743 744 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_updateMemory) 745 746 config := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateMemory, "1024") 747 log.Printf("[DEBUG] template config= %s", config) 748 749 configUpdate := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateMemory, "2048") 750 log.Printf("[DEBUG] template configUpdate= %s", configUpdate) 751 752 resource.Test(t, resource.TestCase{ 753 PreCheck: func() { testAccPreCheck(t) }, 754 Providers: testAccProviders, 755 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 756 Steps: []resource.TestStep{ 757 resource.TestStep{ 758 Config: config, 759 Check: resource.ComposeTestCheckFunc( 760 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 761 ), 762 }, 763 resource.TestStep{ 764 Config: configUpdate, 765 Check: resource.ComposeTestCheckFunc( 766 TestFuncData{vm: vm, label: data.label, mem: "2048", vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 767 ), 768 }, 769 }, 770 }) 771 } 772 773 const testAccCheckVSphereVirtualMachineConfig_updateVcpu = ` 774 resource "vsphere_virtual_machine" "bar" { 775 name = "terraform-test" 776 %s 777 vcpu = %s 778 memory = 1024 779 network_interface { 780 label = "%s" 781 } 782 disk { 783 %s 784 template = "%s" 785 } 786 } 787 ` 788 789 func TestAccVSphereVirtualMachine_updateVcpu(t *testing.T) { 790 var vm virtualMachine 791 data := setupTemplateFuncDHCPData() 792 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_updateVcpu) 793 794 config := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateVcpu, "2") 795 log.Printf("[DEBUG] template config= %s", config) 796 797 configUpdate := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateVcpu, "4") 798 log.Printf("[DEBUG] template configUpdate= %s", configUpdate) 799 800 resource.Test(t, resource.TestCase{ 801 PreCheck: func() { testAccPreCheck(t) }, 802 Providers: testAccProviders, 803 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 804 Steps: []resource.TestStep{ 805 resource.TestStep{ 806 Config: config, 807 Check: resource.ComposeTestCheckFunc( 808 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 809 ), 810 }, 811 resource.TestStep{ 812 Config: configUpdate, 813 Check: resource.ComposeTestCheckFunc( 814 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar", numCPU: "4"}.testCheckFuncBasic(), 815 ), 816 }, 817 }, 818 }) 819 } 820 821 const testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6 = ` 822 resource "vsphere_virtual_machine" "ipv4ipv6" { 823 name = "terraform-test-ipv4-ipv6" 824 %s 825 vcpu = 2 826 memory = 1024 827 network_interface { 828 label = "%s" 829 ipv4_address = "%s" 830 ipv4_prefix_length = %s 831 ipv4_gateway = "%s" 832 ipv6_address = "%s" 833 ipv6_prefix_length = 64 834 ipv6_gateway = "%s" 835 } 836 disk { 837 %s 838 template = "%s" 839 iops = 500 840 } 841 disk { 842 size = 1 843 iops = 500 844 name = "one" 845 } 846 } 847 ` 848 849 func TestAccVSphereVirtualMachine_ipv4Andipv6(t *testing.T) { 850 var vm virtualMachine 851 data := setupTemplateBasicBodyVars() 852 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6) 853 854 vmName := "vsphere_virtual_machine.ipv4ipv6" 855 856 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 857 TestFuncData{vm: vm, label: data.label, vmName: vmName, numDisks: "2", vmResource: "terraform-test-ipv4-ipv6"}.testCheckFuncBasic() 858 859 // FIXME test for this or warn?? 860 ipv6Address := os.Getenv("VSPHERE_IPV6_ADDRESS") 861 ipv6Gateway := os.Getenv("VSPHERE_IPV6_GATEWAY") 862 863 config := fmt.Sprintf( 864 testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6, 865 data.locationOpt, 866 data.label, 867 data.ipv4IpAddress, 868 data.ipv4Prefix, 869 data.ipv4Gateway, 870 ipv6Address, 871 ipv6Gateway, 872 data.datastoreOpt, 873 data.template, 874 ) 875 876 log.Printf("[DEBUG] template config= %s", config) 877 878 resource.Test(t, resource.TestCase{ 879 PreCheck: func() { testAccPreCheck(t) }, 880 Providers: testAccProviders, 881 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 882 Steps: []resource.TestStep{ 883 resource.TestStep{ 884 Config: config, 885 Check: resource.ComposeTestCheckFunc( 886 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 887 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv4_address", data.ipv4IpAddress), 888 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv4_gateway", data.ipv4Gateway), 889 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv6_address", ipv6Address), 890 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv6_gateway", ipv6Gateway), 891 ), 892 }, 893 }, 894 }) 895 } 896 897 const testAccCheckVSphereVirtualMachineConfig_updateAddDisks = ` 898 resource "vsphere_virtual_machine" "foo" { 899 name = "terraform-test" 900 ` + testAccTemplateBasicBody + ` 901 disk { 902 size = 1 903 iops = 500 904 name = "one" 905 } 906 disk { 907 size = 1 908 iops = 500 909 name = "two" 910 } 911 disk { 912 size = 1 913 iops = 500 914 name = "three" 915 } 916 } 917 ` 918 const testAccCheckVSphereVirtualMachineConfig_basic = ` 919 resource "vsphere_virtual_machine" "foo" { 920 name = "terraform-test" 921 ` + testAccTemplateBasicBody + ` 922 disk { 923 size = 1 924 iops = 500 925 name = "one" 926 } 927 } 928 ` 929 930 func TestAccVSphereVirtualMachine_updateDisks(t *testing.T) { 931 var vm virtualMachine 932 basic_vars := setupTemplateBasicBodyVars() 933 config_basic := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_basic) 934 935 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_basic) 936 log.Printf("[DEBUG] template config= %s", config_basic) 937 938 config_add := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_updateAddDisks) 939 940 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_basic) 941 log.Printf("[DEBUG] template config= %s", config_add) 942 943 config_del := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_really_basic) 944 945 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_really_basic) 946 log.Printf("[DEBUG] template config= %s", config_del) 947 948 resource.Test(t, resource.TestCase{ 949 PreCheck: func() { testAccPreCheck(t) }, 950 Providers: testAccProviders, 951 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 952 Steps: []resource.TestStep{ 953 resource.TestStep{ 954 Config: config_basic, 955 Check: resource.ComposeTestCheckFunc( 956 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "2"}.testCheckFuncBasic(), 957 ), 958 }, 959 resource.TestStep{ 960 Config: config_add, 961 Check: resource.ComposeTestCheckFunc( 962 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "4"}.testCheckFuncBasic(), 963 ), 964 }, 965 resource.TestStep{ 966 Config: config_del, 967 Check: resource.ComposeTestCheckFunc( 968 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "1"}.testCheckFuncBasic(), 969 ), 970 }, 971 }, 972 }) 973 } 974 975 const testAccCheckVSphereVirtualMachineConfig_mac_address = ` 976 resource "vsphere_virtual_machine" "mac_address" { 977 name = "terraform-mac-address" 978 %s 979 vcpu = 2 980 memory = 1024 981 network_interface { 982 label = "%s" 983 mac_address = "%s" 984 } 985 disk { 986 %s 987 template = "%s" 988 } 989 } 990 ` 991 992 // VSPHERE_NETWORK_MAC_ADDRESS needs to be set to run TestAccVSphereVirtualMachine_mac_address 993 // use a basic NIC MAC address like 6:5c:89:2b:a0:64 994 func testMacPreCheck(t *testing.T) { 995 996 testBasicPreCheck(t) 997 998 // TODO should start do parse values to ensure they are correct 999 // for instance 1000 // func ParseMAC(s string) (hw HardwareAddr, err error) 1001 if v := os.Getenv("VSPHERE_NETWORK_MAC_ADDRESS"); v == "" { 1002 t.Fatal("env variable VSPHERE_NETWORK_MAC_ADDRESS must be set for this acceptance test") 1003 } 1004 } 1005 1006 // test new mac address feature 1007 func TestAccVSphereVirtualMachine_mac_address(t *testing.T) { 1008 var vm virtualMachine 1009 data := setupTemplateFuncDHCPData() 1010 vmName := "vsphere_virtual_machine.mac_address" 1011 1012 macAddress := os.Getenv("VSPHERE_NETWORK_MAC_ADDRESS") 1013 1014 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_mac_address) 1015 config := fmt.Sprintf( 1016 testAccCheckVSphereVirtualMachineConfig_mac_address, 1017 data.locationOpt, 1018 data.label, 1019 macAddress, 1020 data.datastoreOpt, 1021 data.template, 1022 ) 1023 log.Printf("[DEBUG] template config= %s", config) 1024 1025 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 1026 TestFuncData{vm: vm, label: data.label, vmName: vmName, numDisks: "1", vmResource: "terraform-mac-address"}.testCheckFuncBasic() 1027 1028 resource.Test(t, resource.TestCase{ 1029 PreCheck: func() { testMacPreCheck(t) }, 1030 Providers: testAccProviders, 1031 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 1032 Steps: []resource.TestStep{ 1033 resource.TestStep{ 1034 Config: config, 1035 Check: resource.ComposeTestCheckFunc( 1036 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 1037 resource.TestCheckResourceAttr(vmName, "network_interface.0.mac_address", macAddress), 1038 ), 1039 }, 1040 }, 1041 }) 1042 } 1043 1044 func testAccCheckVSphereVirtualMachineDestroy(s *terraform.State) error { 1045 client := testAccProvider.Meta().(*govmomi.Client) 1046 finder := find.NewFinder(client.Client, true) 1047 1048 for _, rs := range s.RootModule().Resources { 1049 if rs.Type != "vsphere_virtual_machine" { 1050 continue 1051 } 1052 1053 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1054 if err != nil { 1055 return fmt.Errorf("error %s", err) 1056 } 1057 1058 dcFolders, err := dc.Folders(context.TODO()) 1059 if err != nil { 1060 return fmt.Errorf("error %s", err) 1061 } 1062 1063 folder := dcFolders.VmFolder 1064 if len(rs.Primary.Attributes["folder"]) > 0 { 1065 si := object.NewSearchIndex(client.Client) 1066 folderRef, err := si.FindByInventoryPath( 1067 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 1068 if err != nil { 1069 return err 1070 } else if folderRef != nil { 1071 folder = folderRef.(*object.Folder) 1072 } 1073 } 1074 1075 v, err := object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 1076 1077 if v != nil { 1078 return fmt.Errorf("Record still exists") 1079 } 1080 } 1081 1082 return nil 1083 } 1084 1085 func testAccCheckVSphereVirtualMachineExistsHasCustomConfig(n string, vm *virtualMachine) resource.TestCheckFunc { 1086 return func(s *terraform.State) error { 1087 1088 rs, ok := s.RootModule().Resources[n] 1089 if !ok { 1090 return fmt.Errorf("Not found: %s", n) 1091 } 1092 1093 if rs.Primary.ID == "" { 1094 return fmt.Errorf("No ID is set") 1095 } 1096 1097 client := testAccProvider.Meta().(*govmomi.Client) 1098 finder := find.NewFinder(client.Client, true) 1099 1100 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1101 if err != nil { 1102 return fmt.Errorf("error %s", err) 1103 } 1104 1105 dcFolders, err := dc.Folders(context.TODO()) 1106 if err != nil { 1107 return fmt.Errorf("error %s", err) 1108 } 1109 1110 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), dcFolders.VmFolder, rs.Primary.Attributes["name"]) 1111 if err != nil { 1112 return fmt.Errorf("error %s", err) 1113 } 1114 1115 finder = finder.SetDatacenter(dc) 1116 instance, err := finder.VirtualMachine(context.TODO(), rs.Primary.Attributes["name"]) 1117 if err != nil { 1118 return fmt.Errorf("error %s", err) 1119 } 1120 1121 var mvm mo.VirtualMachine 1122 1123 collector := property.DefaultCollector(client.Client) 1124 1125 if err := collector.RetrieveOne(context.TODO(), instance.Reference(), []string{"config.extraConfig"}, &mvm); err != nil { 1126 return fmt.Errorf("error %s", err) 1127 } 1128 1129 var configMap = make(map[string]types.AnyType) 1130 if mvm.Config != nil && mvm.Config.ExtraConfig != nil && len(mvm.Config.ExtraConfig) > 0 { 1131 for _, v := range mvm.Config.ExtraConfig { 1132 value := v.GetOptionValue() 1133 configMap[value.Key] = value.Value 1134 } 1135 } else { 1136 return fmt.Errorf("error no ExtraConfig") 1137 } 1138 1139 if configMap["foo"] == nil { 1140 return fmt.Errorf("error no ExtraConfig for 'foo'") 1141 } 1142 1143 if configMap["foo"] != "bar" { 1144 return fmt.Errorf("error ExtraConfig 'foo' != bar") 1145 } 1146 1147 if configMap["car"] == nil { 1148 return fmt.Errorf("error no ExtraConfig for 'car'") 1149 } 1150 1151 if configMap["car"] != "ferrari" { 1152 return fmt.Errorf("error ExtraConfig 'car' != ferrari") 1153 } 1154 1155 if configMap["num"] == nil { 1156 return fmt.Errorf("error no ExtraConfig for 'num'") 1157 } 1158 1159 // todo this should be an int, getting back a string 1160 if configMap["num"] != "42" { 1161 return fmt.Errorf("error ExtraConfig 'num' != 42") 1162 } 1163 *vm = virtualMachine{ 1164 name: rs.Primary.ID, 1165 } 1166 1167 return nil 1168 } 1169 } 1170 1171 func testAccCheckDebugExists() resource.TestCheckFunc { 1172 return func(s *terraform.State) error { 1173 if _, err := os.Stat(filepath.Join(os.Getenv("HOME"), ".govmomi")); os.IsNotExist(err) { 1174 return fmt.Errorf("Debug logs not found") 1175 } 1176 1177 return nil 1178 } 1179 1180 } 1181 func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resource.TestCheckFunc { 1182 return func(s *terraform.State) error { 1183 if n == "" { 1184 return fmt.Errorf("No vm name passed in") 1185 } 1186 if vm == nil { 1187 return fmt.Errorf("No vm obj passed in") 1188 } 1189 rs, ok := s.RootModule().Resources[n] 1190 if !ok { 1191 return fmt.Errorf("Not found: %s", n) 1192 } 1193 1194 if rs.Primary.ID == "" { 1195 return fmt.Errorf("No ID is set") 1196 } 1197 1198 client := testAccProvider.Meta().(*govmomi.Client) 1199 finder := find.NewFinder(client.Client, true) 1200 1201 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1202 if err != nil { 1203 return fmt.Errorf("error %s", err) 1204 } 1205 1206 dcFolders, err := dc.Folders(context.TODO()) 1207 if err != nil { 1208 return fmt.Errorf("error %s", err) 1209 } 1210 1211 folder := dcFolders.VmFolder 1212 if len(rs.Primary.Attributes["folder"]) > 0 { 1213 si := object.NewSearchIndex(client.Client) 1214 folderRef, err := si.FindByInventoryPath( 1215 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 1216 if err != nil { 1217 return err 1218 } else if folderRef != nil { 1219 folder = folderRef.(*object.Folder) 1220 } 1221 } 1222 1223 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 1224 1225 *vm = virtualMachine{ 1226 name: rs.Primary.ID, 1227 } 1228 1229 return nil 1230 } 1231 } 1232 1233 const testAccCheckVSphereVirtualMachineConfig_keepOnRemove = ` 1234 resource "vsphere_virtual_machine" "keep_disk" { 1235 name = "terraform-test" 1236 ` + testAccTemplateBasicBody + ` 1237 disk { 1238 size = 1 1239 iops = 500 1240 controller_type = "scsi" 1241 name = "one" 1242 keep_on_remove = true 1243 } 1244 } 1245 ` 1246 1247 func TestAccVSphereVirtualMachine_keepOnRemove(t *testing.T) { 1248 var vm virtualMachine 1249 basic_vars := setupTemplateBasicBodyVars() 1250 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_keepOnRemove) 1251 var datastore string 1252 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 1253 datastore = v 1254 } 1255 var datacenter string 1256 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 1257 datacenter = v 1258 } 1259 1260 vmName := "vsphere_virtual_machine.keep_disk" 1261 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 1262 TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "2"}.testCheckFuncBasic() 1263 1264 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_keepOnRemove) 1265 log.Printf("[DEBUG] template config= %s", config) 1266 1267 resource.Test(t, resource.TestCase{ 1268 PreCheck: func() { testAccPreCheck(t) }, 1269 Providers: testAccProviders, 1270 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 1271 Steps: []resource.TestStep{ 1272 resource.TestStep{ 1273 Config: config, 1274 Check: resource.ComposeTestCheckFunc( 1275 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 1276 ), 1277 }, 1278 resource.TestStep{ 1279 Config: " ", 1280 Check: checkForDisk(datacenter, datastore, "terraform-test", "one.vmdk"), 1281 }, 1282 }, 1283 }) 1284 } 1285 1286 func checkForDisk(datacenter string, datastore string, vmName string, path string) resource.TestCheckFunc { 1287 return func(s *terraform.State) error { 1288 client := testAccProvider.Meta().(*govmomi.Client) 1289 finder := find.NewFinder(client.Client, true) 1290 1291 dc, err := getDatacenter(client, datacenter) 1292 if err != nil { 1293 return err 1294 } 1295 finder.SetDatacenter(dc) 1296 1297 ds, err := finder.Datastore(context.TODO(), datastore) 1298 if err != nil { 1299 log.Printf("[ERROR] checkForDisk - Couldn't find Datastore '%v': %v", datastore, err) 1300 return err 1301 } 1302 1303 diskPath := vmName + "/" + path 1304 1305 _, err = ds.Stat(context.TODO(), diskPath) 1306 if err != nil { 1307 log.Printf("[ERROR] checkForDisk - Couldn't stat file '%v': %v", diskPath, err) 1308 return err 1309 } 1310 1311 // Cleanup 1312 fileManager := object.NewFileManager(client.Client) 1313 task, err := fileManager.DeleteDatastoreFile(context.TODO(), ds.Path(vmName), dc) 1314 if err != nil { 1315 log.Printf("[ERROR] checkForDisk - Couldn't delete vm folder '%v': %v", vmName, err) 1316 return err 1317 } 1318 1319 _, err = task.WaitForResult(context.TODO(), nil) 1320 if err != nil { 1321 log.Printf("[ERROR] checForDisk - Failed while deleting vm folder '%v': %v", vmName, err) 1322 return err 1323 } 1324 1325 return nil 1326 } 1327 }