github.com/bfallik/terraform@v0.7.1-0.20160814101525-d3a4714efbf5/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_initTypeEager = ` 402 resource "vsphere_virtual_machine" "thickEagerZero" { 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_diskInitTypeEager(t *testing.T) { 421 var vm virtualMachine 422 basic_vars := setupTemplateBasicBodyVars() 423 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initTypeEager) 424 425 vmName := "vsphere_virtual_machine.thickEagerZero" 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_initTypeEager) 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_initTypeLazy = ` 453 resource "vsphere_virtual_machine" "lazy" { 454 name = "terraform-test" 455 ` + testAccTemplateBasicBody + ` 456 disk { 457 size = 1 458 iops = 500 459 controller_type = "scsi" 460 name = "one" 461 } 462 disk { 463 size = 1 464 controller_type = "ide" 465 type = "lazy" 466 name = "two" 467 } 468 } 469 ` 470 471 func TestAccVSphereVirtualMachine_diskInitTypeLazy(t *testing.T) { 472 var vm virtualMachine 473 basic_vars := setupTemplateBasicBodyVars() 474 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initTypeLazy) 475 476 vmName := "vsphere_virtual_machine.lazy" 477 478 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 479 TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "3"}.testCheckFuncBasic() 480 481 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_initTypeLazy) 482 log.Printf("[DEBUG] template config= %s", config) 483 484 resource.Test(t, resource.TestCase{ 485 PreCheck: func() { testAccPreCheck(t) }, 486 Providers: testAccProviders, 487 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 488 Steps: []resource.TestStep{ 489 resource.TestStep{ 490 Config: config, 491 Check: resource.ComposeTestCheckFunc( 492 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 493 // FIXME dynmically calculate the hashes 494 resource.TestCheckResourceAttr(vmName, "disk.692719290.type", "lazy"), 495 resource.TestCheckResourceAttr(vmName, "disk.692719290.controller_type", "ide"), 496 resource.TestCheckResourceAttr(vmName, "disk.531766495.controller_type", "scsi"), 497 ), 498 }, 499 }, 500 }) 501 } 502 503 const testAccCheckVSphereVirtualMachineConfig_dhcp = ` 504 resource "vsphere_virtual_machine" "bar" { 505 name = "terraform-test" 506 ` 507 508 func TestAccVSphereVirtualMachine_dhcp(t *testing.T) { 509 var vm virtualMachine 510 data := setupTemplateFuncDHCPData() 511 config := testAccCheckVSphereVirtualMachineConfig_dhcp + data.parseDHCPTemplateConfigWithTemplate(testAccCheckVSphereTemplate_dhcp) 512 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_dhcp+testAccCheckVSphereTemplate_dhcp) 513 log.Printf("[DEBUG] config= %s", config) 514 515 resource.Test(t, resource.TestCase{ 516 PreCheck: func() { testAccPreCheck(t) }, 517 Providers: testAccProviders, 518 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 519 Steps: []resource.TestStep{ 520 resource.TestStep{ 521 Config: config, 522 Check: resource.ComposeTestCheckFunc( 523 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 524 ), 525 }, 526 }, 527 }) 528 } 529 530 const testAccCheckVSphereVirtualMachineConfig_custom_configs = ` 531 resource "vsphere_virtual_machine" "car" { 532 name = "terraform-test-custom" 533 custom_configuration_parameters { 534 "foo" = "bar" 535 "car" = "ferrari" 536 "num" = 42 537 } 538 enable_disk_uuid = true 539 ` 540 541 func TestAccVSphereVirtualMachine_custom_configs(t *testing.T) { 542 543 var vm virtualMachine 544 data := setupTemplateFuncDHCPData() 545 config := testAccCheckVSphereVirtualMachineConfig_custom_configs + data.parseDHCPTemplateConfigWithTemplate(testAccCheckVSphereTemplate_dhcp) 546 vmName := "vsphere_virtual_machine.car" 547 res := "terraform-test-custom" 548 549 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 550 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: res}.testCheckFuncBasic() 551 552 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_custom_configs+testAccCheckVSphereTemplate_dhcp) 553 log.Printf("[DEBUG] config= %s", config) 554 555 resource.Test(t, resource.TestCase{ 556 PreCheck: func() { testAccPreCheck(t) }, 557 Providers: testAccProviders, 558 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 559 Steps: []resource.TestStep{ 560 resource.TestStep{ 561 Config: config, 562 Check: resource.ComposeTestCheckFunc( 563 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 564 testAccCheckVSphereVirtualMachineExistsHasCustomConfig(vmName, &vm), 565 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.foo", "bar"), 566 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.car", "ferrari"), 567 resource.TestCheckResourceAttr(vmName, "custom_configuration_parameters.num", "42"), 568 resource.TestCheckResourceAttr(vmName, "enable_disk_uuid", "true"), 569 ), 570 }, 571 }, 572 }) 573 } 574 575 const testAccCheckVSphereVirtualMachineConfig_createInFolder = ` 576 resource "vsphere_virtual_machine" "folder" { 577 name = "terraform-test-folder" 578 folder = "%s" 579 ` 580 581 func TestAccVSphereVirtualMachine_createInExistingFolder(t *testing.T) { 582 var vm virtualMachine 583 datacenter := os.Getenv("VSPHERE_DATACENTER") 584 585 folder := "tf_test_cpureateInExistingFolder" 586 587 data := setupTemplateFuncDHCPData() 588 config := fmt.Sprintf(testAccCheckVSphereVirtualMachineConfig_createInFolder, 589 folder, 590 ) + data.parseDHCPTemplateConfig() 591 592 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_createInFolder) 593 log.Printf("[DEBUG] template config= %s", config) 594 595 resource.Test(t, resource.TestCase{ 596 PreCheck: func() { testAccPreCheck(t) }, 597 Providers: testAccProviders, 598 CheckDestroy: resource.ComposeTestCheckFunc( 599 testAccCheckVSphereVirtualMachineDestroy, 600 removeVSphereFolder(datacenter, folder, ""), 601 ), 602 Steps: []resource.TestStep{ 603 resource.TestStep{ 604 PreConfig: func() { createVSphereFolder(datacenter, folder) }, 605 Config: config, 606 Check: resource.ComposeTestCheckFunc( 607 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.folder", vmResource: "terraform-test-folder"}.testCheckFuncBasic(), 608 ), 609 }, 610 }, 611 }) 612 } 613 614 const testAccCheckVSphereVirtualMachineConfig_createWithFolder = ` 615 resource "vsphere_folder" "with_folder" { 616 path = "%s" 617 %s 618 } 619 resource "vsphere_virtual_machine" "with_folder" { 620 name = "terraform-test-with-folder" 621 folder = "${vsphere_folder.with_folder.path}" 622 ` 623 624 func TestAccVSphereVirtualMachine_createWithFolder(t *testing.T) { 625 var vm virtualMachine 626 var folderLocationOpt string 627 var f folder 628 629 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 630 folderLocationOpt = fmt.Sprintf(" datacenter = \"%s\"\n", v) 631 } 632 633 folder := "tf_test_cpureateWithFolder" 634 635 data := setupTemplateFuncDHCPData() 636 vmName := "vsphere_virtual_machine.with_folder" 637 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 638 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: "terraform-test-with-folder"}.testCheckFuncBasic() 639 640 config := fmt.Sprintf(testAccCheckVSphereVirtualMachineConfig_createWithFolder, 641 folder, 642 folderLocationOpt, 643 ) + data.parseDHCPTemplateConfig() 644 645 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_createWithFolder+testAccCheckVSphereTemplate_dhcp) 646 log.Printf("[DEBUG] template config= %s", config) 647 648 resource.Test(t, resource.TestCase{ 649 PreCheck: func() { testAccPreCheck(t) }, 650 Providers: testAccProviders, 651 CheckDestroy: resource.ComposeTestCheckFunc( 652 testAccCheckVSphereVirtualMachineDestroy, 653 testAccCheckVSphereFolderDestroy, 654 ), 655 Steps: []resource.TestStep{ 656 resource.TestStep{ 657 Config: config, 658 Check: resource.ComposeTestCheckFunc( 659 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 660 testAccCheckVSphereFolderExists(vmName, &f), 661 resource.TestCheckResourceAttr(vmName, "folder", folder), 662 ), 663 }, 664 }, 665 }) 666 } 667 668 const testAccCheckVsphereVirtualMachineConfig_cdrom = ` 669 resource "vsphere_virtual_machine" "with_cdrom" { 670 name = "terraform-test-with-cdrom" 671 cdrom { 672 datastore = "%s" 673 path = "%s" 674 } 675 ` 676 677 func TestAccVSphereVirtualMachine_createWithCdrom(t *testing.T) { 678 var vm virtualMachine 679 680 // FIXME check that these exist 681 cdromDatastore := os.Getenv("VSPHERE_CDROM_DATASTORE") 682 cdromPath := os.Getenv("VSPHERE_CDROM_PATH") 683 vmName := "vsphere_virtual_machine.with_cdrom" 684 685 data := setupTemplateFuncDHCPData() 686 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 687 TestFuncData{vm: vm, label: data.label, vmName: vmName, vmResource: "terraform-test-with-cdrom"}.testCheckFuncBasic() 688 689 config := fmt.Sprintf( 690 testAccCheckVsphereVirtualMachineConfig_cdrom, 691 cdromDatastore, 692 cdromPath, 693 ) + data.parseDHCPTemplateConfig() 694 695 log.Printf("[DEBUG] template= %s", testAccCheckVsphereVirtualMachineConfig_cdrom) 696 log.Printf("[DEBUG] template config= %s", config) 697 698 resource.Test(t, resource.TestCase{ 699 PreCheck: func() { testAccPreCheck(t) }, 700 Providers: testAccProviders, 701 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 702 Steps: []resource.TestStep{ 703 resource.TestStep{ 704 Config: config, 705 Check: resource.ComposeTestCheckFunc( 706 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 707 //resource.TestCheckResourceAttr( 708 // "vsphere_virtual_machine.with_cdrom", "disk.4088143748.template", template), 709 resource.TestCheckResourceAttr(vmName, "cdrom.#", "1"), 710 resource.TestCheckResourceAttr(vmName, "cdrom.0.datastore", cdromDatastore), 711 resource.TestCheckResourceAttr(vmName, "cdrom.0.path", cdromPath), 712 ), 713 }, 714 }, 715 }) 716 } 717 718 const testAccCheckVSphereVirtualMachineConfig_withExistingVmdk = ` 719 resource "vsphere_virtual_machine" "with_existing_vmdk" { 720 name = "terraform-test-with-existing-vmdk" 721 %s 722 vcpu = 2 723 memory = 1024 724 network_interface { 725 label = "%s" 726 } 727 disk { 728 %s 729 vmdk = "%s" 730 bootable = true 731 } 732 disk { 733 size = 1 734 iops = 500 735 name = "one" 736 } 737 } 738 ` 739 740 func TestAccVSphereVirtualMachine_createWithExistingVmdk(t *testing.T) { 741 var vm virtualMachine 742 vmdk_path := os.Getenv("VSPHERE_VMDK_PATH") 743 744 data := setupTemplateFuncDHCPData() 745 config := fmt.Sprintf( 746 testAccCheckVSphereVirtualMachineConfig_withExistingVmdk, 747 data.locationOpt, 748 data.label, 749 data.datastoreOpt, 750 vmdk_path, 751 ) 752 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_withExistingVmdk) 753 log.Printf("[DEBUG] template config= %s", config) 754 755 resource.Test(t, resource.TestCase{ 756 PreCheck: func() { testAccPreCheck(t) }, 757 Providers: testAccProviders, 758 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 759 Steps: []resource.TestStep{ 760 resource.TestStep{ 761 Config: config, 762 Check: resource.ComposeTestCheckFunc( 763 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.with_existing_vmdk", 764 vmResource: "terraform-test-with-existing-vmdk", numDisks: "2"}.testCheckFuncBasic(), 765 //resource.TestCheckResourceAttr( 766 // "vsphere_virtual_machine.with_existing_vmdk", "disk.2393891804.vmdk", vmdk_path), 767 //resource.TestCheckResourceAttr( 768 // "vsphere_virtual_machine.with_existing_vmdk", "disk.2393891804.bootable", "true"), 769 ), 770 }, 771 }, 772 }) 773 } 774 775 const testAccCheckVSphereVirtualMachineConfig_updateMemory = ` 776 resource "vsphere_virtual_machine" "bar" { 777 name = "terraform-test" 778 %s 779 vcpu = 2 780 memory = %s 781 network_interface { 782 label = "%s" 783 } 784 disk { 785 %s 786 template = "%s" 787 } 788 } 789 ` 790 791 func TestAccVSphereVirtualMachine_updateMemory(t *testing.T) { 792 var vm virtualMachine 793 data := setupTemplateFuncDHCPData() 794 795 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_updateMemory) 796 797 config := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateMemory, "1024") 798 log.Printf("[DEBUG] template config= %s", config) 799 800 configUpdate := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateMemory, "2048") 801 log.Printf("[DEBUG] template configUpdate= %s", configUpdate) 802 803 resource.Test(t, resource.TestCase{ 804 PreCheck: func() { testAccPreCheck(t) }, 805 Providers: testAccProviders, 806 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 807 Steps: []resource.TestStep{ 808 resource.TestStep{ 809 Config: config, 810 Check: resource.ComposeTestCheckFunc( 811 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 812 ), 813 }, 814 resource.TestStep{ 815 Config: configUpdate, 816 Check: resource.ComposeTestCheckFunc( 817 TestFuncData{vm: vm, label: data.label, mem: "2048", vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 818 ), 819 }, 820 }, 821 }) 822 } 823 824 const testAccCheckVSphereVirtualMachineConfig_updateVcpu = ` 825 resource "vsphere_virtual_machine" "bar" { 826 name = "terraform-test" 827 %s 828 vcpu = %s 829 memory = 1024 830 network_interface { 831 label = "%s" 832 } 833 disk { 834 %s 835 template = "%s" 836 } 837 } 838 ` 839 840 func TestAccVSphereVirtualMachine_updateVcpu(t *testing.T) { 841 var vm virtualMachine 842 data := setupTemplateFuncDHCPData() 843 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_updateVcpu) 844 845 config := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateVcpu, "2") 846 log.Printf("[DEBUG] template config= %s", config) 847 848 configUpdate := data.testSprintfDHCPTemplateBodySecondArgDynamic(testAccCheckVSphereVirtualMachineConfig_updateVcpu, "4") 849 log.Printf("[DEBUG] template configUpdate= %s", configUpdate) 850 851 resource.Test(t, resource.TestCase{ 852 PreCheck: func() { testAccPreCheck(t) }, 853 Providers: testAccProviders, 854 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 855 Steps: []resource.TestStep{ 856 resource.TestStep{ 857 Config: config, 858 Check: resource.ComposeTestCheckFunc( 859 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar"}.testCheckFuncBasic(), 860 ), 861 }, 862 resource.TestStep{ 863 Config: configUpdate, 864 Check: resource.ComposeTestCheckFunc( 865 TestFuncData{vm: vm, label: data.label, vmName: "vsphere_virtual_machine.bar", numCPU: "4"}.testCheckFuncBasic(), 866 ), 867 }, 868 }, 869 }) 870 } 871 872 const testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6 = ` 873 resource "vsphere_virtual_machine" "ipv4ipv6" { 874 name = "terraform-test-ipv4-ipv6" 875 %s 876 vcpu = 2 877 memory = 1024 878 network_interface { 879 label = "%s" 880 ipv4_address = "%s" 881 ipv4_prefix_length = %s 882 ipv4_gateway = "%s" 883 ipv6_address = "%s" 884 ipv6_prefix_length = 64 885 ipv6_gateway = "%s" 886 } 887 disk { 888 %s 889 template = "%s" 890 iops = 500 891 } 892 disk { 893 size = 1 894 iops = 500 895 name = "one" 896 } 897 } 898 ` 899 900 func TestAccVSphereVirtualMachine_ipv4Andipv6(t *testing.T) { 901 var vm virtualMachine 902 data := setupTemplateBasicBodyVars() 903 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6) 904 905 vmName := "vsphere_virtual_machine.ipv4ipv6" 906 907 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 908 TestFuncData{vm: vm, label: data.label, vmName: vmName, numDisks: "2", vmResource: "terraform-test-ipv4-ipv6"}.testCheckFuncBasic() 909 910 // FIXME test for this or warn?? 911 ipv6Address := os.Getenv("VSPHERE_IPV6_ADDRESS") 912 ipv6Gateway := os.Getenv("VSPHERE_IPV6_GATEWAY") 913 914 config := fmt.Sprintf( 915 testAccCheckVSphereVirtualMachineConfig_ipv4Andipv6, 916 data.locationOpt, 917 data.label, 918 data.ipv4IpAddress, 919 data.ipv4Prefix, 920 data.ipv4Gateway, 921 ipv6Address, 922 ipv6Gateway, 923 data.datastoreOpt, 924 data.template, 925 ) 926 927 log.Printf("[DEBUG] template config= %s", config) 928 929 resource.Test(t, resource.TestCase{ 930 PreCheck: func() { testAccPreCheck(t) }, 931 Providers: testAccProviders, 932 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 933 Steps: []resource.TestStep{ 934 resource.TestStep{ 935 Config: config, 936 Check: resource.ComposeTestCheckFunc( 937 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 938 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv4_address", data.ipv4IpAddress), 939 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv4_gateway", data.ipv4Gateway), 940 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv6_address", ipv6Address), 941 resource.TestCheckResourceAttr(vmName, "network_interface.0.ipv6_gateway", ipv6Gateway), 942 ), 943 }, 944 }, 945 }) 946 } 947 948 const testAccCheckVSphereVirtualMachineConfig_updateAddDisks = ` 949 resource "vsphere_virtual_machine" "foo" { 950 name = "terraform-test" 951 ` + testAccTemplateBasicBody + ` 952 disk { 953 size = 1 954 iops = 500 955 name = "one" 956 } 957 disk { 958 size = 1 959 iops = 500 960 name = "two" 961 } 962 disk { 963 size = 1 964 iops = 500 965 name = "three" 966 } 967 } 968 ` 969 const testAccCheckVSphereVirtualMachineConfig_basic = ` 970 resource "vsphere_virtual_machine" "foo" { 971 name = "terraform-test" 972 ` + testAccTemplateBasicBody + ` 973 disk { 974 size = 1 975 iops = 500 976 name = "one" 977 } 978 } 979 ` 980 981 func TestAccVSphereVirtualMachine_updateDisks(t *testing.T) { 982 var vm virtualMachine 983 basic_vars := setupTemplateBasicBodyVars() 984 config_basic := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_basic) 985 986 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_basic) 987 log.Printf("[DEBUG] template config= %s", config_basic) 988 989 config_add := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_updateAddDisks) 990 991 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_basic) 992 log.Printf("[DEBUG] template config= %s", config_add) 993 994 config_del := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_really_basic) 995 996 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_really_basic) 997 log.Printf("[DEBUG] template config= %s", config_del) 998 999 resource.Test(t, resource.TestCase{ 1000 PreCheck: func() { testAccPreCheck(t) }, 1001 Providers: testAccProviders, 1002 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 1003 Steps: []resource.TestStep{ 1004 resource.TestStep{ 1005 Config: config_basic, 1006 Check: resource.ComposeTestCheckFunc( 1007 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "2"}.testCheckFuncBasic(), 1008 ), 1009 }, 1010 resource.TestStep{ 1011 Config: config_add, 1012 Check: resource.ComposeTestCheckFunc( 1013 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "4"}.testCheckFuncBasic(), 1014 ), 1015 }, 1016 resource.TestStep{ 1017 Config: config_del, 1018 Check: resource.ComposeTestCheckFunc( 1019 TestFuncData{vm: vm, label: basic_vars.label, numDisks: "1"}.testCheckFuncBasic(), 1020 ), 1021 }, 1022 }, 1023 }) 1024 } 1025 1026 const testAccCheckVSphereVirtualMachineConfig_mac_address = ` 1027 resource "vsphere_virtual_machine" "mac_address" { 1028 name = "terraform-mac-address" 1029 %s 1030 vcpu = 2 1031 memory = 1024 1032 network_interface { 1033 label = "%s" 1034 mac_address = "%s" 1035 } 1036 disk { 1037 %s 1038 template = "%s" 1039 } 1040 } 1041 ` 1042 1043 // VSPHERE_NETWORK_MAC_ADDRESS needs to be set to run TestAccVSphereVirtualMachine_mac_address 1044 // use a basic NIC MAC address like 6:5c:89:2b:a0:64 1045 func testMacPreCheck(t *testing.T) { 1046 1047 testBasicPreCheck(t) 1048 1049 // TODO should start do parse values to ensure they are correct 1050 // for instance 1051 // func ParseMAC(s string) (hw HardwareAddr, err error) 1052 if v := os.Getenv("VSPHERE_NETWORK_MAC_ADDRESS"); v == "" { 1053 t.Fatal("env variable VSPHERE_NETWORK_MAC_ADDRESS must be set for this acceptance test") 1054 } 1055 } 1056 1057 // test new mac address feature 1058 func TestAccVSphereVirtualMachine_mac_address(t *testing.T) { 1059 var vm virtualMachine 1060 data := setupTemplateFuncDHCPData() 1061 vmName := "vsphere_virtual_machine.mac_address" 1062 1063 macAddress := os.Getenv("VSPHERE_NETWORK_MAC_ADDRESS") 1064 1065 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_mac_address) 1066 config := fmt.Sprintf( 1067 testAccCheckVSphereVirtualMachineConfig_mac_address, 1068 data.locationOpt, 1069 data.label, 1070 macAddress, 1071 data.datastoreOpt, 1072 data.template, 1073 ) 1074 log.Printf("[DEBUG] template config= %s", config) 1075 1076 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 1077 TestFuncData{vm: vm, label: data.label, vmName: vmName, numDisks: "1", vmResource: "terraform-mac-address"}.testCheckFuncBasic() 1078 1079 resource.Test(t, resource.TestCase{ 1080 PreCheck: func() { testMacPreCheck(t) }, 1081 Providers: testAccProviders, 1082 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 1083 Steps: []resource.TestStep{ 1084 resource.TestStep{ 1085 Config: config, 1086 Check: resource.ComposeTestCheckFunc( 1087 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 1088 resource.TestCheckResourceAttr(vmName, "network_interface.0.mac_address", macAddress), 1089 ), 1090 }, 1091 }, 1092 }) 1093 } 1094 1095 func testAccCheckVSphereVirtualMachineDestroy(s *terraform.State) error { 1096 client := testAccProvider.Meta().(*govmomi.Client) 1097 finder := find.NewFinder(client.Client, true) 1098 1099 for _, rs := range s.RootModule().Resources { 1100 if rs.Type != "vsphere_virtual_machine" { 1101 continue 1102 } 1103 1104 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1105 if err != nil { 1106 return fmt.Errorf("error %s", err) 1107 } 1108 1109 dcFolders, err := dc.Folders(context.TODO()) 1110 if err != nil { 1111 return fmt.Errorf("error %s", err) 1112 } 1113 1114 folder := dcFolders.VmFolder 1115 if len(rs.Primary.Attributes["folder"]) > 0 { 1116 si := object.NewSearchIndex(client.Client) 1117 folderRef, err := si.FindByInventoryPath( 1118 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 1119 if err != nil { 1120 return err 1121 } else if folderRef != nil { 1122 folder = folderRef.(*object.Folder) 1123 } 1124 } 1125 1126 v, err := object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 1127 1128 if v != nil { 1129 return fmt.Errorf("Record still exists") 1130 } 1131 } 1132 1133 return nil 1134 } 1135 1136 func testAccCheckVSphereVirtualMachineExistsHasCustomConfig(n string, vm *virtualMachine) resource.TestCheckFunc { 1137 return func(s *terraform.State) error { 1138 1139 rs, ok := s.RootModule().Resources[n] 1140 if !ok { 1141 return fmt.Errorf("Not found: %s", n) 1142 } 1143 1144 if rs.Primary.ID == "" { 1145 return fmt.Errorf("No ID is set") 1146 } 1147 1148 client := testAccProvider.Meta().(*govmomi.Client) 1149 finder := find.NewFinder(client.Client, true) 1150 1151 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1152 if err != nil { 1153 return fmt.Errorf("error %s", err) 1154 } 1155 1156 dcFolders, err := dc.Folders(context.TODO()) 1157 if err != nil { 1158 return fmt.Errorf("error %s", err) 1159 } 1160 1161 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), dcFolders.VmFolder, rs.Primary.Attributes["name"]) 1162 if err != nil { 1163 return fmt.Errorf("error %s", err) 1164 } 1165 1166 finder = finder.SetDatacenter(dc) 1167 instance, err := finder.VirtualMachine(context.TODO(), rs.Primary.Attributes["name"]) 1168 if err != nil { 1169 return fmt.Errorf("error %s", err) 1170 } 1171 1172 var mvm mo.VirtualMachine 1173 1174 collector := property.DefaultCollector(client.Client) 1175 1176 if err := collector.RetrieveOne(context.TODO(), instance.Reference(), []string{"config.extraConfig"}, &mvm); err != nil { 1177 return fmt.Errorf("error %s", err) 1178 } 1179 1180 var configMap = make(map[string]types.AnyType) 1181 if mvm.Config != nil && mvm.Config.ExtraConfig != nil && len(mvm.Config.ExtraConfig) > 0 { 1182 for _, v := range mvm.Config.ExtraConfig { 1183 value := v.GetOptionValue() 1184 configMap[value.Key] = value.Value 1185 } 1186 } else { 1187 return fmt.Errorf("error no ExtraConfig") 1188 } 1189 1190 if configMap["foo"] == nil { 1191 return fmt.Errorf("error no ExtraConfig for 'foo'") 1192 } 1193 1194 if configMap["foo"] != "bar" { 1195 return fmt.Errorf("error ExtraConfig 'foo' != bar") 1196 } 1197 1198 if configMap["car"] == nil { 1199 return fmt.Errorf("error no ExtraConfig for 'car'") 1200 } 1201 1202 if configMap["car"] != "ferrari" { 1203 return fmt.Errorf("error ExtraConfig 'car' != ferrari") 1204 } 1205 1206 if configMap["num"] == nil { 1207 return fmt.Errorf("error no ExtraConfig for 'num'") 1208 } 1209 1210 // todo this should be an int, getting back a string 1211 if configMap["num"] != "42" { 1212 return fmt.Errorf("error ExtraConfig 'num' != 42") 1213 } 1214 *vm = virtualMachine{ 1215 name: rs.Primary.ID, 1216 } 1217 1218 return nil 1219 } 1220 } 1221 1222 func testAccCheckDebugExists() resource.TestCheckFunc { 1223 return func(s *terraform.State) error { 1224 if _, err := os.Stat(filepath.Join(os.Getenv("HOME"), ".govmomi")); os.IsNotExist(err) { 1225 return fmt.Errorf("Debug logs not found") 1226 } 1227 1228 return nil 1229 } 1230 1231 } 1232 func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resource.TestCheckFunc { 1233 return func(s *terraform.State) error { 1234 if n == "" { 1235 return fmt.Errorf("No vm name passed in") 1236 } 1237 if vm == nil { 1238 return fmt.Errorf("No vm obj passed in") 1239 } 1240 rs, ok := s.RootModule().Resources[n] 1241 if !ok { 1242 return fmt.Errorf("Not found: %s", n) 1243 } 1244 1245 if rs.Primary.ID == "" { 1246 return fmt.Errorf("No ID is set") 1247 } 1248 1249 client := testAccProvider.Meta().(*govmomi.Client) 1250 finder := find.NewFinder(client.Client, true) 1251 1252 dc, err := finder.Datacenter(context.TODO(), rs.Primary.Attributes["datacenter"]) 1253 if err != nil { 1254 return fmt.Errorf("error %s", err) 1255 } 1256 1257 dcFolders, err := dc.Folders(context.TODO()) 1258 if err != nil { 1259 return fmt.Errorf("error %s", err) 1260 } 1261 1262 folder := dcFolders.VmFolder 1263 if len(rs.Primary.Attributes["folder"]) > 0 { 1264 si := object.NewSearchIndex(client.Client) 1265 folderRef, err := si.FindByInventoryPath( 1266 context.TODO(), fmt.Sprintf("%v/vm/%v", rs.Primary.Attributes["datacenter"], rs.Primary.Attributes["folder"])) 1267 if err != nil { 1268 return err 1269 } else if folderRef != nil { 1270 folder = folderRef.(*object.Folder) 1271 } 1272 } 1273 1274 _, err = object.NewSearchIndex(client.Client).FindChild(context.TODO(), folder, rs.Primary.Attributes["name"]) 1275 1276 *vm = virtualMachine{ 1277 name: rs.Primary.ID, 1278 } 1279 1280 return nil 1281 } 1282 } 1283 1284 const testAccCheckVSphereVirtualMachineConfig_keepOnRemove = ` 1285 resource "vsphere_virtual_machine" "keep_disk" { 1286 name = "terraform-test" 1287 ` + testAccTemplateBasicBody + ` 1288 disk { 1289 size = 1 1290 iops = 500 1291 controller_type = "scsi" 1292 name = "one" 1293 keep_on_remove = true 1294 } 1295 } 1296 ` 1297 1298 func TestAccVSphereVirtualMachine_keepOnRemove(t *testing.T) { 1299 var vm virtualMachine 1300 basic_vars := setupTemplateBasicBodyVars() 1301 config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_keepOnRemove) 1302 var datastore string 1303 if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { 1304 datastore = v 1305 } 1306 var datacenter string 1307 if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { 1308 datacenter = v 1309 } 1310 1311 vmName := "vsphere_virtual_machine.keep_disk" 1312 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := 1313 TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "2"}.testCheckFuncBasic() 1314 1315 log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_keepOnRemove) 1316 log.Printf("[DEBUG] template config= %s", config) 1317 1318 resource.Test(t, resource.TestCase{ 1319 PreCheck: func() { testAccPreCheck(t) }, 1320 Providers: testAccProviders, 1321 CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, 1322 Steps: []resource.TestStep{ 1323 resource.TestStep{ 1324 Config: config, 1325 Check: resource.ComposeTestCheckFunc( 1326 test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, 1327 ), 1328 }, 1329 resource.TestStep{ 1330 Config: " ", 1331 Check: checkForDisk(datacenter, datastore, "terraform-test", "one.vmdk"), 1332 }, 1333 }, 1334 }) 1335 } 1336 1337 func checkForDisk(datacenter string, datastore string, vmName string, path string) resource.TestCheckFunc { 1338 return func(s *terraform.State) error { 1339 client := testAccProvider.Meta().(*govmomi.Client) 1340 finder := find.NewFinder(client.Client, true) 1341 1342 dc, err := getDatacenter(client, datacenter) 1343 if err != nil { 1344 return err 1345 } 1346 finder.SetDatacenter(dc) 1347 1348 ds, err := finder.Datastore(context.TODO(), datastore) 1349 if err != nil { 1350 log.Printf("[ERROR] checkForDisk - Couldn't find Datastore '%v': %v", datastore, err) 1351 return err 1352 } 1353 1354 diskPath := vmName + "/" + path 1355 1356 _, err = ds.Stat(context.TODO(), diskPath) 1357 if err != nil { 1358 log.Printf("[ERROR] checkForDisk - Couldn't stat file '%v': %v", diskPath, err) 1359 return err 1360 } 1361 1362 // Cleanup 1363 fileManager := object.NewFileManager(client.Client) 1364 task, err := fileManager.DeleteDatastoreFile(context.TODO(), ds.Path(vmName), dc) 1365 if err != nil { 1366 log.Printf("[ERROR] checkForDisk - Couldn't delete vm folder '%v': %v", vmName, err) 1367 return err 1368 } 1369 1370 _, err = task.WaitForResult(context.TODO(), nil) 1371 if err != nil { 1372 log.Printf("[ERROR] checForDisk - Failed while deleting vm folder '%v': %v", vmName, err) 1373 return err 1374 } 1375 1376 return nil 1377 } 1378 }