diff --git a/nutanix/resource_nutanix_virtual_machine.go b/nutanix/resource_nutanix_virtual_machine.go index 6f7787a17..956a56c15 100644 --- a/nutanix/resource_nutanix_virtual_machine.go +++ b/nutanix/resource_nutanix_virtual_machine.go @@ -279,6 +279,11 @@ func resourceNutanixVirtualMachine() *schema.Resource { // RESOURCES ARGUMENTS + "use_hot_add": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, "num_vnuma_nodes": { Type: schema.TypeInt, Optional: true, @@ -918,6 +923,11 @@ func resourceNutanixVirtualMachineRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("error setting parent_reference for Virtual Machine %s: %s", d.Id(), err) } + //use_hot_add cannot be derived via API so get the value for 'use_hot_add'. + // if err := d.Set("use_hot_add", ); err != nil { + // return fmt.Errorf("error setting use_got_add for Virtual Machine %s: %s", d.Id(), err) + // } + diskAddress := make(map[string]interface{}) mac := "" b := make([]string, 0) @@ -1005,7 +1015,15 @@ func resourceNutanixVirtualMachineRead(d *schema.ResourceData, meta interface{}) func resourceNutanixVirtualMachineUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*Client).API setVMTimeout(meta) - var hotPlugChange = true + var hotPlugChange = d.Get("use_hot_add").(bool) + + // log.Printf("[HP] hotplugchange pre: %t", hotPlugChange) + + // if uha, uhaok := d.GetOk("use_hot_add"); uhaok { + // log.Printf("[HP] use_hot_add: %t", uha.(bool)) + // hotPlugChange = uha.(bool) + // } + log.Printf("[HP] hotplugchange post: %t", hotPlugChange) log.Printf("[Debug] Updating VM values %s", d.Id()) diff --git a/nutanix/resource_nutanix_virtual_machine_test.go b/nutanix/resource_nutanix_virtual_machine_test.go index a1f8eebf1..21d0cdd1f 100644 --- a/nutanix/resource_nutanix_virtual_machine_test.go +++ b/nutanix/resource_nutanix_virtual_machine_test.go @@ -345,6 +345,90 @@ func testAccCheckNutanixVirtualMachineDestroy(s *terraform.State) error { return nil } +func TestAccNutanixVirtualMachine_hotadd(t *testing.T) { + r := acctest.RandInt() + resourceName := "nutanix_virtual_machine.vm10" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNutanixVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNutanixVMConfigHotAdd(r), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "1024"), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "1"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "1"), + resource.TestCheckResourceAttr(resourceName, "use_hot_add", "true"), + ), + }, + { + Config: testAccNutanixVMConfigHotAddUpdate(r), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "2048"), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "1"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "1"), + resource.TestCheckResourceAttr(resourceName, "use_hot_add", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"disk_list"}, + }, + }, + }) +} + +func TestAccNutanixVirtualMachine_nohotadd(t *testing.T) { + r := acctest.RandInt() + resourceName := "nutanix_virtual_machine.vm10" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNutanixVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNutanixVMConfigNoHotAdd(r), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "1024"), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "1"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "1"), + resource.TestCheckResourceAttr(resourceName, "use_hot_add", "false"), + ), + }, + { + Config: testAccNutanixVMConfigNoHotAddUpdate(r), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "2048"), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "1"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "1"), + resource.TestCheckResourceAttr(resourceName, "use_hot_add", "false"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"disk_list", "use_hot_add"}, + }, + }, + }) +} + func testAccNutanixVMConfig(r int) string { return fmt.Sprintf(` data "nutanix_clusters" "clusters" {} @@ -830,3 +914,90 @@ func testAccNutanixVMConfigCloningVM(r int) string { } `, r) } +func testAccNutanixVMConfigHotAdd(r int) string { + return fmt.Sprintf(` + data "nutanix_clusters" "clusters" {} + + locals { + cluster1 = "${data.nutanix_clusters.clusters.entities.0.service_list.0 == "PRISM_CENTRAL" + ? data.nutanix_clusters.clusters.entities.1.metadata.uuid : data.nutanix_clusters.clusters.entities.0.metadata.uuid}" + } + + resource "nutanix_virtual_machine" "vm10" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 1024 + power_state_mechanism = "ACPI" + use_hot_add = true + } + `, r) +} + +func testAccNutanixVMConfigHotAddUpdate(r int) string { + return fmt.Sprintf(` + data "nutanix_clusters" "clusters" {} + + locals { + cluster1 = "${data.nutanix_clusters.clusters.entities.0.service_list.0 == "PRISM_CENTRAL" + ? data.nutanix_clusters.clusters.entities.1.metadata.uuid : data.nutanix_clusters.clusters.entities.0.metadata.uuid}" + } + + resource "nutanix_virtual_machine" "vm10" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 2048 + power_state_mechanism = "ACPI" + use_hot_add = true + } + `, r) +} + +func testAccNutanixVMConfigNoHotAdd(r int) string { + return fmt.Sprintf(` + data "nutanix_clusters" "clusters" {} + + locals { + cluster1 = "${data.nutanix_clusters.clusters.entities.0.service_list.0 == "PRISM_CENTRAL" + ? data.nutanix_clusters.clusters.entities.1.metadata.uuid : data.nutanix_clusters.clusters.entities.0.metadata.uuid}" + } + + resource "nutanix_virtual_machine" "vm10" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 1024 + power_state_mechanism = "ACPI" + use_hot_add = false + } + `, r) +} + +func testAccNutanixVMConfigNoHotAddUpdate(r int) string { + return fmt.Sprintf(` + data "nutanix_clusters" "clusters" {} + + locals { + cluster1 = "${data.nutanix_clusters.clusters.entities.0.service_list.0 == "PRISM_CENTRAL" + ? data.nutanix_clusters.clusters.entities.1.metadata.uuid : data.nutanix_clusters.clusters.entities.0.metadata.uuid}" + } + + resource "nutanix_virtual_machine" "vm10" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 2048 + power_state_mechanism = "ACPI" + use_hot_add = false + } + `, r) +} diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index 8d0afa3f5..af7acacf0 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -70,6 +70,7 @@ The following arguments are supported: * `power_state_mechanism`: - (Optional) Indicates the mechanism guiding the VM power state transition. Currently used for the transition to \"OFF\" state. Power state mechanism (ACPI/GUEST/HARD). * `vga_console_enabled`: - (Optional) Indicates whether VGA console should be enabled or not. * `disk_list` Disks attached to the VM. +* `use_hot_add`: - (Optional) Use Hot Add when modifying VM resources. Passing value false will result in VM reboots. Default value is true. ### Disk List