Skip to content

Commit

Permalink
fix: add vm folder when querying for vm (#2118)
Browse files Browse the repository at this point in the history
- Added the VM folder in the search for VMs criteria in deploy from OVF scenario.
- Added an e2e test. Verified that when the VM folder is not strictly specified the OVF deploy is passing. The query is in the default VM folder.

Ref: #1524

Signed-off-by: Vasil Atanasov <[email protected]>
  • Loading branch information
vasilsatanasov authored Jan 23, 2024
1 parent c0e3f00 commit 8313d7c
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 2 deletions.
8 changes: 6 additions & 2 deletions vsphere/resource_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"log"
"net"
"os"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -1377,8 +1378,11 @@ func resourceVsphereMachineDeployOvfAndOva(d *schema.ResourceData, meta interfac
if err != nil {
return nil, fmt.Errorf("error while getting datacenter with id %s %s", dataCenterID, err)
}

vm, err := virtualmachine.FromPath(client, ovfHelper.Name, datacenterObj)
searchPath := ovfHelper.Name
if ovfHelper.Folder != nil && len(ovfHelper.Folder.InventoryPath) > 0 {
searchPath = filepath.Join(ovfHelper.Folder.InventoryPath, searchPath)
}
vm, err := virtualmachine.FromPath(client, searchPath, datacenterObj)
if err != nil {
return nil, fmt.Errorf("error while fetching the created vm, %s", err)
}
Expand Down
155 changes: 155 additions & 0 deletions vsphere/resource_vsphere_virtual_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2580,6 +2580,33 @@ func TestAccResourceVSphereVirtualMachine_createMemoryReservationLockedToMax(t *
})
}

func TestAccResourceVSphereVirtualMachine_deployOvfFromUrlMultipleVmsSameName(t *testing.T) {
ovfNameTpl := "terraform_test_vm_" + acctest.RandStringFromCharSet(4, acctest.CharSetAlphaNum)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccResourceVSphereVirtualMachinePreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: resource.ComposeTestCheckFunc(
testAccResourceVSphereVirtualMachineCheckExistsByName(false, "vm1"),
testAccResourceVSphereVirtualMachineCheckExistsByName(false, "vm2"),
),
Steps: []resource.TestStep{
{
Config: testAccResourceVSphereVirtualMachineDeployOvfFromURLMultipleVMsSameName(ovfNameTpl),
Check: resource.ComposeTestCheckFunc(
testAccResourceVSphereVirtualMachineCheckExistsByName(true, "vm1"),
testAccResourceVSphereVirtualMachineCheckExistsByName(true, "vm2"),
),
},
{
Config: testAccResourceVSphereVirtualMachineConfigBase(),
},
},
})
}

func testAccResourceVSphereVirtualMachinePreCheck(t *testing.T) {
// Note that TF_VAR_VSPHERE_USE_LINKED_CLONE is also a variable and its presence
// speeds up tests greatly, but it's not a necessary variable, so we don't
Expand Down Expand Up @@ -2659,6 +2686,25 @@ func testAccResourceVSphereVirtualMachineCheckExists(expected bool) resource.Tes
}
}

func testAccResourceVSphereVirtualMachineCheckExistsByName(expected bool, vmName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, err := testGetVirtualMachine(s, vmName)
if err != nil {
missingState, _ := regexp.MatchString("not found in state", err.Error())
missingVSphere, _ := regexp.MatchString("virtual machine with UUID \"[-a-f0-9]+\" not found", err.Error())
if missingState && !expected || missingVSphere && !expected {
// Expected missing
return nil
}
return err
}
if !expected {
return errors.New("expected vm to be missing")
}
return nil
}
}

func testAccResourceVSphereVirtualMachineCheckEagerlyScrub(diskIndex int, eagerlyScrubedValue bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
props, err := testGetVirtualMachineProperties(s, "vm")
Expand Down Expand Up @@ -7437,6 +7483,115 @@ resource "vsphere_virtual_machine" "vm" {
)
}

func testAccResourceVSphereVirtualMachineDeployOvfFromURLMultipleVMsSameName(vmName string) string {
return fmt.Sprintf(`
%s
variable "ovf_url" {
default = "%s"
}
data "vsphere_ovf_vm_template" "ovf" {
name = "%s"
resource_pool_id = data.vsphere_host.roothost1.resource_pool_id
datastore_id = vsphere_nas_datastore.ds1.id
host_system_id = data.vsphere_host.roothost1.id
remote_ovf_url = var.ovf_url
ovf_network_map = {
"Production_DVS - Mgmt": data.vsphere_network.network1.id
}
}
resource "vsphere_folder" "vm_folder_1" {
path = "vm-folder-11"
type = "vm"
datacenter_id = data.vsphere_datacenter.rootdc1.id
}
resource "vsphere_folder" "vm_folder_2" {
path = "vm-folder-12"
type = "vm"
datacenter_id = data.vsphere_datacenter.rootdc1.id
}
resource "vsphere_virtual_machine" "vm1" {
datacenter_id = data.vsphere_datacenter.rootdc1.id
folder = vsphere_folder.vm_folder_1.path
annotation = data.vsphere_ovf_vm_template.ovf.annotation
name = "ovf-multiple-name-1"
num_cpus = data.vsphere_ovf_vm_template.ovf.num_cpus
memory = data.vsphere_ovf_vm_template.ovf.memory
guest_id = data.vsphere_ovf_vm_template.ovf.guest_id
resource_pool_id = data.vsphere_ovf_vm_template.ovf.resource_pool_id
datastore_id = data.vsphere_ovf_vm_template.ovf.datastore_id
host_system_id = data.vsphere_ovf_vm_template.ovf.host_system_id
dynamic "network_interface" {
for_each = data.vsphere_ovf_vm_template.ovf.ovf_network_map
content {
network_id = network_interface.value
}
}
wait_for_guest_net_timeout = 0
ovf_deploy {
remote_ovf_url = var.ovf_url
ovf_network_map = data.vsphere_ovf_vm_template.ovf.ovf_network_map
}
lifecycle {
ignore_changes = [
ept_rvi_mode,
hv_mode
]
}
}
resource "vsphere_virtual_machine" "vm2" {
datacenter_id = data.vsphere_datacenter.rootdc1.id
folder = vsphere_folder.vm_folder_2.path
annotation = data.vsphere_ovf_vm_template.ovf.annotation
name = "ovf-multiple-name-2"
num_cpus = data.vsphere_ovf_vm_template.ovf.num_cpus
memory = data.vsphere_ovf_vm_template.ovf.memory
guest_id = data.vsphere_ovf_vm_template.ovf.guest_id
resource_pool_id = data.vsphere_ovf_vm_template.ovf.resource_pool_id
datastore_id = data.vsphere_ovf_vm_template.ovf.datastore_id
host_system_id = data.vsphere_ovf_vm_template.ovf.host_system_id
dynamic "network_interface" {
for_each = data.vsphere_ovf_vm_template.ovf.ovf_network_map
content {
network_id = network_interface.value
}
}
wait_for_guest_net_timeout = 0
ovf_deploy {
remote_ovf_url = var.ovf_url
ovf_network_map = data.vsphere_ovf_vm_template.ovf.ovf_network_map
}
lifecycle {
ignore_changes = [
ept_rvi_mode,
hv_mode
]
}
}
`,
testAccResourceVSphereVirtualMachineConfigBase(),
os.Getenv("TF_VAR_VSPHERE_TEST_OVF"),
vmName,
)
}

// Tests to skip until new features are developed.

// Needs storage policy resource
Expand Down

0 comments on commit 8313d7c

Please sign in to comment.