Skip to content

Commit

Permalink
Add folder field for d/vsphere_virtual_machine
Browse files Browse the repository at this point in the history
Added `folder` field to  `d/vsphere_virtual_machine` to mitigate the 80
characters limitation of the `name` field.

Added e2e test

Updated documentation

Fixes #1262

Signed-off-by: Vasil Atanasov <[email protected]>
  • Loading branch information
vasilsatanasov committed Jan 23, 2024
1 parent 9c7a3b5 commit 52eeaf2
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
17 changes: 16 additions & 1 deletion vsphere/data_source_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package vsphere

import (
"fmt"
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/folder"
"log"
"path"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand All @@ -23,6 +25,13 @@ func dataSourceVSphereVirtualMachine() *schema.Resource {
Description: "The managed object ID of the datacenter the virtual machine is in. This is not required when using ESXi directly, or if there is only one datacenter in your infrastructure.",
Optional: true,
},
"folder": {
Type: schema.TypeString,
Optional: true,
Description: "The name of the folder the virtual machine is in. Allows distinguishing virtual machines with the same name in different folder paths",
StateFunc: folder.NormalizePath,
ConflictsWith: []string{"uuid", "moid"},
},
"scsi_controller_scan_count": {
Type: schema.TypeInt,
Description: "The number of SCSI controllers to scan for disk sizes and controller types on.",
Expand Down Expand Up @@ -183,6 +192,7 @@ func dataSourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{
uuid := d.Get("uuid").(string)
moid := d.Get("moid").(string)
name := d.Get("name").(string)
folderName := d.Get("folder").(string)
var vm *object.VirtualMachine
var err error

Expand All @@ -202,7 +212,12 @@ func dataSourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{
}
log.Printf("[DEBUG] Datacenter for VM/template search: %s", dc.InventoryPath)
}
vm, err = virtualmachine.FromPath(client, name, dc)

searchPath := name
if len(folderName) > 0 {
searchPath = path.Join(folderName, name)
}
vm, err = virtualmachine.FromPath(client, searchPath, dc)
}

if err != nil {
Expand Down
88 changes: 88 additions & 0 deletions vsphere/data_source_vsphere_virtual_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,48 @@ func TestAccDataSourceVSphereVirtualMachine_moid(t *testing.T) {
})
}

func TestAccDataSourceVSphereVirtualMachine_nameAndFolder(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() {
RunSweepers()
testAccPreCheck(t)
testAccDataSourceVSphereVirtualMachinePreCheck(t)
},
Providers: testAccProviders,
Steps: []resource.TestStep{{
Config: testAccDataSourceVirtualMachineFolder(),
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"data.vsphere_virtual_machine.vm1",
"id",
regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$")),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "guest_id"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "scsi_type"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "memory"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "num_cpus"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "num_cores_per_socket"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "firmware"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "hardware_version"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.#"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.0.size"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.0.eagerly_scrub"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.0.thin_provisioned"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.0.unit_number"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "disks.0.label"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interface_types.#"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.#"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.adapter_type"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.bandwidth_limit"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.bandwidth_reservation"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.bandwidth_share_level"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.bandwidth_share_count"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.mac_address"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "network_interfaces.0.network_id"),
resource.TestCheckResourceAttrSet("data.vsphere_virtual_machine.vm1", "firmware")),
}},
})
}

func testAccDataSourceVSphereVirtualMachinePreCheck(t *testing.T) {
if os.Getenv("TF_VAR_VSPHERE_DATACENTER") == "" {
t.Skip("set TF_VAR_VSPHERE_DATACENTER to run vsphere_virtual_machine data source acceptance tests")
Expand Down Expand Up @@ -284,3 +326,49 @@ data "vsphere_virtual_machine" "template" {
os.Getenv("TF_VAR_VSPHERE_TEMPLATE"),
)
}

func testAccDataSourceVirtualMachineFolder() string {
return fmt.Sprintf(`
%s
resource "vsphere_folder" "new_vm_folder" {
path = "new-vm-folder"
datacenter_id = data.vsphere_datacenter.rootdc1.id
type = "vm"
}
resource "vsphere_virtual_machine" "vm" {
name = "foo"
resource_pool_id = data.vsphere_compute_cluster.rootcompute_cluster1.resource_pool_id
folder = vsphere_folder.new_vm_folder.path
datastore_id = data.vsphere_datastore.rootds1.id
num_cpus = 1
memory = 1024
guest_id = "other3xLinux64Guest"
network_interface {
network_id = data.vsphere_network.network1.id
}
disk {
label = "disk0"
size = 10
}
wait_for_guest_ip_timeout = 0
wait_for_guest_net_timeout = 0
}
data vsphere_virtual_machine "vm1" {
name = vsphere_virtual_machine.vm.name
datacenter_id = data.vsphere_datacenter.rootdc1.id
folder = vsphere_folder.new_vm_folder.path
}
`, testhelper.CombineConfigs(
testhelper.ConfigDataRootDC1(),
testhelper.ConfigDataRootPortGroup1(),
testhelper.ConfigDataRootComputeCluster1(),
testhelper.ConfigDataRootDS1(),
))

}
1 change: 1 addition & 0 deletions website/docs/d/virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ The following arguments are supported:
is not performed.
* `uuid` - (Optional) Specify this field for a UUID lookup, `name` and `datacenter_id`
are not required if this is specified.
* `folder` - (Optional) The name of the virtual machine folder where the virtual machine is located. The `name` argument is limited to 80 characters. If the `name` argument includes the full path to the virtual machine and exceeds the 80 characters limit, the `folder` folder argument can be used.
* `datacenter_id` - (Optional) The [managed object reference
ID][docs-about-morefs] of the datacenter the virtual machine is located in.
This can be omitted if the search path used in `name` is an absolute path.
Expand Down

0 comments on commit 52eeaf2

Please sign in to comment.