From eba8414ef60c26f915e7d03ec04e34b49cd68311 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Thu, 19 May 2022 13:49:03 +0530 Subject: [PATCH 1/8] adding vm clone resource --- client/v3/v3_service.go | 15 + client/v3/v3_structs.go | 25 +- nutanix/provider.go | 1 + .../resource_nutanix_virtual_machine_clone.go | 399 ++++++++++++++++++ 4 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 nutanix/resource_nutanix_virtual_machine_clone.go diff --git a/client/v3/v3_service.go b/client/v3/v3_service.go index 5ee59ea91..094108908 100644 --- a/client/v3/v3_service.go +++ b/client/v3/v3_service.go @@ -23,6 +23,7 @@ type Service interface { GetVM(uuid string) (*VMIntentResponse, error) ListVM(getEntitiesRequest *DSMetadata) (*VMListIntentResponse, error) UpdateVM(uuid string, body *VMIntentInput) (*VMIntentResponse, error) + CloneVM(uuid string, body *VMCloneInput) (*VMCloneResponse, error) CreateSubnet(createRequest *SubnetIntentInput) (*SubnetIntentResponse, error) DeleteSubnet(uuid string) (*DeleteResponse, error) GetSubnet(uuid string) (*SubnetIntentResponse, error) @@ -2428,3 +2429,17 @@ func (op Operations) UpdateAddressGroup(uuid string, body *AddressGroupInput) er return op.client.Do(ctx, req, nil) } + +func (op Operations) CloneVM(uuid string, body *VMCloneInput) (*VMCloneResponse, error) { + ctx := context.TODO() + + path := fmt.Sprintf("/vms/%s/clone", uuid) + req, err := op.client.NewRequest(ctx, http.MethodPost, path, body) + vmIntentResponse := new(VMCloneResponse) + + if err != nil { + return nil, err + } + + return vmIntentResponse, op.client.Do(ctx, req, vmIntentResponse) +} diff --git a/client/v3/v3_structs.go b/client/v3/v3_structs.go index b6f8753fc..a6e279df4 100644 --- a/client/v3/v3_structs.go +++ b/client/v3/v3_structs.go @@ -1668,9 +1668,11 @@ type Metadata struct { // Applied on Prism Central only. Indicate whether force to translate the spec of the fanout request to fit the target cluster API schema. ShouldForceTranslate *bool `json:"should_force_translate,omitempty" mapstructure:"should_force_translate,omitempty"` + // Logical entity version of the VM from which to clone the new VM. + EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` + //TODO: add if necessary //CategoriesMapping map[string][]string `json:"categories_mapping,omitempty" mapstructure:"categories_mapping,omitempty"` - //EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` //UseCategoriesMapping *bool `json:"use_categories_mapping,omitempty" mapstructure:"use_categories_mapping,omitempty"` } @@ -2600,3 +2602,24 @@ type AddressGroupListResponse struct { Metadata *ListMetadataOutput `json:"metadata,omitempty"` Entities []*AddressGroupListEntry `json:"entities,omitempty"` } + +type OverrideSpec struct { + Name *string `json:"name,omitempty"` + NumSockets *int `json:"num_sockets,omitempty"` + NumVcpusPerSocket *int `json:"num_vcpus_per_socket,omitempty"` + NumThreadsPerCore *int `json:"num_threads_per_core,omitempty"` + MemorySizeMib *int `json:"memory_size_mib,omitempty"` + NicList []*VMNic `json:"nic_list,omitempty"` + BootConfig *VMBootConfig `json:"boot_config,omitempty"` + GuestCustomization *GuestCustomization `json:"guest_customization,omitempty"` +} + +type VMCloneInput struct { + Metadata *Metadata `json:"metadata,omitempty"` + OverrideSpec *OverrideSpec `json:"override_spec,omitempty"` +} + +type VMCloneResponse struct { + TaskUUID *string `json:"task_uuid,omitempty"` + CloneVMUUID *string `json:"clone_vm_uuid,omitempty"` +} diff --git a/nutanix/provider.go b/nutanix/provider.go index 7cad6cbdb..b7386ee49 100644 --- a/nutanix/provider.go +++ b/nutanix/provider.go @@ -183,6 +183,7 @@ func Provider() *schema.Provider { "nutanix_foundation_image": resourceNutanixFoundationImage(), "nutanix_foundation_central_image_cluster": resourceNutanixFCImageCluster(), "nutanix_foundation_central_api_keys": resourceNutanixFCAPIKeys(), + "nutanix_vm_clone": resourceNutanixVirtualMachineClone(), }, ConfigureContextFunc: providerConfigure, } diff --git a/nutanix/resource_nutanix_virtual_machine_clone.go b/nutanix/resource_nutanix_virtual_machine_clone.go new file mode 100644 index 000000000..b63d8c990 --- /dev/null +++ b/nutanix/resource_nutanix_virtual_machine_clone.go @@ -0,0 +1,399 @@ +package nutanix + +import ( + "context" + "log" + "reflect" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + v3 "github.com/terraform-providers/terraform-provider-nutanix/client/v3" + "github.com/terraform-providers/terraform-provider-nutanix/utils" +) + +func resourceNutanixVirtualMachineClone() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceNutanixVirtualMachineCloneCreate, + UpdateContext: resourceNutanixVirtualMachineCloneUpdate, + ReadContext: resourceNutanixVirtualMachineCloneRead, + DeleteContext: resourceNutanixVirtualMachineCloneDelete, + Schema: map[string]*schema.Schema{ + "vm_uuid": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "num_sockets": { + Type: schema.TypeInt, + Optional: true, + }, + "num_vcpus_per_socket": { + Type: schema.TypeInt, + Optional: true, + }, + "num_threads_per_core": { + Type: schema.TypeInt, + Optional: true, + }, + "memory_size_mib": { + Type: schema.TypeInt, + Optional: true, + }, + "nic_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_type": { + Type: schema.TypeString, + Optional: true, + }, + "uuid": { + Type: schema.TypeString, + Optional: true, + }, + "model": { + Type: schema.TypeString, + Optional: true, + }, + "network_function_nic_type": { + Type: schema.TypeString, + Optional: true, + }, + "mac_address": { + Type: schema.TypeString, + Optional: true, + }, + "ip_endpoint_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Optional: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "network_function_chain_reference": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "num_queues": { + Type: schema.TypeInt, + Optional: true, + }, + "subnet_uuid": { + Type: schema.TypeString, + Optional: true, + }, + "subnet_name": { + Type: schema.TypeString, + Optional: true, + }, + "is_connected": { + Type: schema.TypeString, + Optional: true, + Default: "true", + }, + }, + }, + }, + + "boot_device_order_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "boot_device_disk_address": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_device_mac_address": { + Type: schema.TypeString, + Optional: true, + }, + "boot_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"UEFI", "LEGACY", "SECURE_BOOT"}, false), + }, + "guest_customization_cloud_init_user_data": { + Type: schema.TypeString, + Optional: true, + }, + "guest_customization_cloud_init_meta_data": { + Type: schema.TypeString, + Optional: true, + }, + "guest_customization_cloud_init_custom_key_values": { + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "guest_customization_is_overridable": { + Type: schema.TypeBool, + Optional: true, + }, + "guest_customization_sysprep": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "guest_customization_sysprep_custom_key_values": { + Type: schema.TypeMap, + Optional: true, + }, + "metadata": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "task_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "clone_vm_uuid": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*Client).API + + var id string + vm_uuid, nok := d.GetOk("vm_uuid") + if nok { + id = *utils.StringPtr(vm_uuid.(string)) + } + spec := &v3.VMCloneInput{} + + spec.Metadata = getMetadataCloneAttributes(d) + spec.OverrideSpec = expandOverrideSpec(d) + + // Make request to the API + resp, err := conn.V3.CloneVM(id, spec) + if err != nil { + return diag.FromErr(err) + } + taskUUID := *resp.TaskUUID + + // Wait for the VM to be available + stateConf := &resource.StateChangeConf{ + Pending: []string{"QUEUED", "RUNNING"}, + Target: []string{"SUCCEEDED"}, + Refresh: taskStateRefreshFunc(conn, taskUUID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: vmDelay, + MinTimeout: vmMinTimeout, + } + + task_info, errWaitTask := stateConf.WaitForStateContext(ctx) + if errWaitTask != nil { + return diag.Errorf("error waiting for task (%s) to create: %s", taskUUID, errWaitTask) + } + + // Get the cloned VM UUID + var cloneVmUUID string + task_details, ok := task_info.(*v3.TasksResponse) + if ok { + cloneVmUUID = *task_details.EntityReferenceList[0].UUID + } + + // State Changed to Power ON + if err := changePowerState(ctx, conn, cloneVmUUID, "ON"); err != nil { + return diag.Errorf("internal error: cannot turn ON the VM with UUID(%s): %s", cloneVmUUID, err) + } + + // Wait for IP available + waitIPConf := &resource.StateChangeConf{ + Pending: []string{WAITING}, + Target: []string{"AVAILABLE"}, + Refresh: waitForIPRefreshFunc(conn, cloneVmUUID), + Timeout: vmTimeout, + Delay: vmDelay, + MinTimeout: vmMinTimeout, + } + + vmIntentResponse, err := waitIPConf.WaitForStateContext(ctx) + if err != nil { + log.Printf("[WARN] could not get the IP for VM(%s): %s", cloneVmUUID, err) + } else { + vm := vmIntentResponse.(*v3.VMIntentResponse) + + if len(vm.Status.Resources.NicList) > 0 && len(vm.Status.Resources.NicList[0].IPEndpointList) != 0 { + d.SetConnInfo(map[string]string{ + "type": "ssh", + "host": *vm.Status.Resources.NicList[0].IPEndpointList[0].IP, + }) + } + } + + d.SetId(cloneVmUUID) + return nil + //return resourceNutanixVirtualMachineCloneRead(ctx, d, meta) +} + +func resourceNutanixVirtualMachineCloneUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return nil +} + +func resourceNutanixVirtualMachineCloneRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return nil +} + +func resourceNutanixVirtualMachineCloneDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return nil +} + +func getMetadataCloneAttributes(d *schema.ResourceData) (out *v3.Metadata) { + + resourceData, ok := d.GetOk("metadata") + if !ok { + return nil + } + + meta := resourceData.([]interface{})[0].(map[string]interface{}) + + if name, ok := meta["uuid"]; ok { + out.UUID = utils.StringPtr(name.(string)) + } + + if name, ok := meta["entity_version"]; ok { + out.EntityVersion = utils.StringPtr(name.(string)) + } + return out +} + +func expandOverrideSpec(d *schema.ResourceData) *v3.OverrideSpec { + res := &v3.OverrideSpec{} + + if name, ok := d.GetOk("name"); ok { + res.Name = utils.StringPtr(name.(string)) + } + + if numSockets, sok := d.GetOk("num_sockets"); sok { + res.NumSockets = utils.IntPtr(numSockets.(int)) + } + + if vcpuSock, vok := d.GetOk("num_vcpus_per_socket"); vok { + res.NumVcpusPerSocket = utils.IntPtr(vcpuSock.(int)) + } + + if numThreads, ok := d.GetOk("num_threads_per_core"); ok { + res.NumThreadsPerCore = utils.IntPtr(numThreads.(int)) + } + + if memorySize, mok := d.GetOk("memory_size_mib"); mok { + res.MemorySizeMib = utils.IntPtr(memorySize.(int)) + } + + if _, nok := d.GetOk("nic_list"); nok { + res.NicList = expandNicList(d) + } + + guestCustom := &v3.GuestCustomization{} + cloudInit := &v3.GuestCustomizationCloudInit{} + + if v, ok := d.GetOk("guest_customization_cloud_init_user_data"); ok { + cloudInit.UserData = utils.StringPtr(v.(string)) + } + + if v, ok := d.GetOk("guest_customization_cloud_init_meta_data"); ok { + cloudInit.MetaData = utils.StringPtr(v.(string)) + } + + if v, ok := d.GetOk("guest_customization_cloud_init_custom_key_values"); ok { + cloudInit.CustomKeyValues = utils.ConvertMapString(v.(map[string]interface{})) + } + + if !reflect.DeepEqual(*cloudInit, (v3.GuestCustomizationCloudInit{})) { + guestCustom.CloudInit = cloudInit + } + + if v, ok := d.GetOk("guest_customization_is_overridable"); ok { + guestCustom.IsOverridable = utils.BoolPtr(v.(bool)) + } + if v, ok := d.GetOk("guest_customization_sysprep"); ok { + guestCustom.Sysprep = &v3.GuestCustomizationSysprep{} + spi := v.(map[string]interface{}) + if v2, ok2 := spi["install_type"]; ok2 { + guestCustom.Sysprep.InstallType = utils.StringPtr(v2.(string)) + } + if v2, ok2 := spi["unattend_xml"]; ok2 { + guestCustom.Sysprep.UnattendXML = utils.StringPtr(v2.(string)) + } + } + + if v, ok := d.GetOk("guest_customization_sysprep_custom_key_values"); ok { + if guestCustom.Sysprep == nil { + guestCustom.Sysprep = &v3.GuestCustomizationSysprep{} + } + guestCustom.Sysprep.CustomKeyValues = v.(map[string]string) + } + + if !reflect.DeepEqual(*guestCustom, (v3.GuestCustomization{})) { + res.GuestCustomization = guestCustom + } + bootConfig := &v3.VMBootConfig{} + + if v, ok := d.GetOk("boot_device_order_list"); ok { + bootConfig.BootDeviceOrderList = expandStringList(v.([]interface{})) + res.BootConfig = bootConfig + } + + bd := &v3.VMBootDevice{} + da := &v3.DiskAddress{} + if v, ok := d.GetOk("boot_device_disk_address"); ok { + dai := v.(map[string]interface{}) + + if value3, ok3 := dai["device_index"]; ok3 { + if i, err := strconv.ParseInt(value3.(string), 10, 64); err == nil { + da.DeviceIndex = utils.Int64Ptr(i) + } + } + if value3, ok3 := dai["adapter_type"]; ok3 { + da.AdapterType = utils.StringPtr(value3.(string)) + } + bd.DiskAddress = da + bootConfig.BootDevice = bd + res.BootConfig = bootConfig + } + + if bdmac, ok := d.GetOk("boot_device_mac_address"); ok { + bd.MacAddress = utils.StringPtr(bdmac.(string)) + res.BootConfig.BootDevice = bd + } + + if bootType, ok := d.GetOk("boot_type"); ok { + bootConfig.BootType = utils.StringPtr(bootType.(string)) + res.BootConfig = bootConfig + } + return res +} From 7ca340e6ce23513ac59c9fafecf53c718ff48d2b Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 20 May 2022 10:02:38 +0530 Subject: [PATCH 2/8] fix lint error --- .../resource_nutanix_virtual_machine_clone.go | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/nutanix/resource_nutanix_virtual_machine_clone.go b/nutanix/resource_nutanix_virtual_machine_clone.go index b63d8c990..c3fcdd88b 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone.go +++ b/nutanix/resource_nutanix_virtual_machine_clone.go @@ -188,9 +188,9 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res conn := meta.(*Client).API var id string - vm_uuid, nok := d.GetOk("vm_uuid") + vmUUID, nok := d.GetOk("vm_uuid") if nok { - id = *utils.StringPtr(vm_uuid.(string)) + id = *utils.StringPtr(vmUUID.(string)) } spec := &v3.VMCloneInput{} @@ -214,36 +214,36 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res MinTimeout: vmMinTimeout, } - task_info, errWaitTask := stateConf.WaitForStateContext(ctx) + taskInfo, errWaitTask := stateConf.WaitForStateContext(ctx) if errWaitTask != nil { return diag.Errorf("error waiting for task (%s) to create: %s", taskUUID, errWaitTask) } // Get the cloned VM UUID - var cloneVmUUID string - task_details, ok := task_info.(*v3.TasksResponse) + var cloneVMUUID string + taskDetails, ok := taskInfo.(*v3.TasksResponse) if ok { - cloneVmUUID = *task_details.EntityReferenceList[0].UUID + cloneVMUUID = *taskDetails.EntityReferenceList[0].UUID } // State Changed to Power ON - if err := changePowerState(ctx, conn, cloneVmUUID, "ON"); err != nil { - return diag.Errorf("internal error: cannot turn ON the VM with UUID(%s): %s", cloneVmUUID, err) + if er := changePowerState(ctx, conn, cloneVMUUID, "ON"); er != nil { + return diag.Errorf("internal error: cannot turn ON the VM with UUID(%s): %s", cloneVMUUID, err) } // Wait for IP available waitIPConf := &resource.StateChangeConf{ Pending: []string{WAITING}, Target: []string{"AVAILABLE"}, - Refresh: waitForIPRefreshFunc(conn, cloneVmUUID), + Refresh: waitForIPRefreshFunc(conn, cloneVMUUID), Timeout: vmTimeout, Delay: vmDelay, MinTimeout: vmMinTimeout, } - vmIntentResponse, err := waitIPConf.WaitForStateContext(ctx) - if err != nil { - log.Printf("[WARN] could not get the IP for VM(%s): %s", cloneVmUUID, err) + vmIntentResponse, ero := waitIPConf.WaitForStateContext(ctx) + if ero != nil { + log.Printf("[WARN] could not get the IP for VM(%s): %s", cloneVMUUID, err) } else { vm := vmIntentResponse.(*v3.VMIntentResponse) @@ -255,7 +255,7 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res } } - d.SetId(cloneVmUUID) + d.SetId(cloneVMUUID) return nil //return resourceNutanixVirtualMachineCloneRead(ctx, d, meta) } @@ -273,7 +273,6 @@ func resourceNutanixVirtualMachineCloneDelete(ctx context.Context, d *schema.Res } func getMetadataCloneAttributes(d *schema.ResourceData) (out *v3.Metadata) { - resourceData, ok := d.GetOk("metadata") if !ok { return nil From 570a1606dfffde6266e76ad741703923ec849bff Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 23 May 2022 12:58:47 +0530 Subject: [PATCH 3/8] Adding ReadContext --- nutanix/provider.go | 2 +- .../resource_nutanix_virtual_machine_clone.go | 398 +++++++++++++++++- 2 files changed, 395 insertions(+), 5 deletions(-) diff --git a/nutanix/provider.go b/nutanix/provider.go index b7386ee49..6dfed190d 100644 --- a/nutanix/provider.go +++ b/nutanix/provider.go @@ -183,7 +183,7 @@ func Provider() *schema.Provider { "nutanix_foundation_image": resourceNutanixFoundationImage(), "nutanix_foundation_central_image_cluster": resourceNutanixFCImageCluster(), "nutanix_foundation_central_api_keys": resourceNutanixFCAPIKeys(), - "nutanix_vm_clone": resourceNutanixVirtualMachineClone(), + "nutanix_virtual_machine_clone": resourceNutanixVirtualMachineClone(), }, ConfigureContextFunc: providerConfigure, } diff --git a/nutanix/resource_nutanix_virtual_machine_clone.go b/nutanix/resource_nutanix_virtual_machine_clone.go index c3fcdd88b..25676bcfb 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone.go +++ b/nutanix/resource_nutanix_virtual_machine_clone.go @@ -28,26 +28,32 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { "name": { Type: schema.TypeString, Optional: true, + Computed: true, }, "num_sockets": { Type: schema.TypeInt, Optional: true, + Computed: true, }, "num_vcpus_per_socket": { Type: schema.TypeInt, Optional: true, + Computed: true, }, "num_threads_per_core": { Type: schema.TypeInt, Optional: true, + Computed: true, }, "memory_size_mib": { Type: schema.TypeInt, Optional: true, + Computed: true, }, "nic_list": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "nic_type": { @@ -117,11 +123,13 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { "boot_device_order_list": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "boot_device_disk_address": { Type: schema.TypeMap, Optional: true, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -129,19 +137,23 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { "boot_device_mac_address": { Type: schema.TypeString, Optional: true, + Computed: true, }, "boot_type": { Type: schema.TypeString, Optional: true, + Computed: true, ValidateFunc: validation.StringInSlice([]string{"UEFI", "LEGACY", "SECURE_BOOT"}, false), }, "guest_customization_cloud_init_user_data": { Type: schema.TypeString, Optional: true, + Computed: true, }, "guest_customization_cloud_init_meta_data": { Type: schema.TypeString, Optional: true, + Computed: true, }, "guest_customization_cloud_init_custom_key_values": { Type: schema.TypeMap, @@ -149,14 +161,17 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { Type: schema.TypeString, }, Optional: true, + Computed: true, }, "guest_customization_is_overridable": { Type: schema.TypeBool, Optional: true, + Computed: true, }, "guest_customization_sysprep": { Type: schema.TypeMap, Optional: true, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -164,10 +179,12 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { "guest_customization_sysprep_custom_key_values": { Type: schema.TypeMap, Optional: true, + Computed: true, }, "metadata": { Type: schema.TypeMap, Optional: true, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -176,10 +193,383 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "clone_vm_uuid": { + // Computed Resource Argument + "cloud_init_cdrom_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "categories": categoriesSchema(), + "project_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "owner_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "api_version": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "availability_zone_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cluster_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "cluster_name": { + Type: schema.TypeString, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, + }, + "host_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "hypervisor_type": { + Type: schema.TypeString, + Computed: true, + }, + "nic_list_status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_type": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "floating_ip": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "network_function_nic_type": { + Type: schema.TypeString, + Computed: true, + }, + "mac_address": { + Type: schema.TypeString, + Computed: true, + }, + "ip_endpoint_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "network_function_chain_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "num_queues": { + Type: schema.TypeInt, + Computed: true, + }, + "subnet_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_name": { + Type: schema.TypeString, + Computed: true, + }, + "is_connected": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + // RESOURCES ARGUMENTS + + "enable_cpu_passthrough": { + Type: schema.TypeBool, + Computed: true, + }, + "is_vcpu_hard_pinned": { + Type: schema.TypeBool, + Computed: true, + }, + "use_hot_add": { + Type: schema.TypeBool, + Computed: true, + }, + "num_vnuma_nodes": { + Type: schema.TypeInt, + Computed: true, + }, + "guest_os_id": { + Type: schema.TypeString, + Computed: true, + }, + "power_state": { + Type: schema.TypeString, + Computed: true, + }, + "nutanix_guest_tools": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ngt_credentials": { + Type: schema.TypeMap, + Computed: true, + }, + "ngt_enabled_capability_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "gpu_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "frame_buffer_size_mib": { + Type: schema.TypeInt, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "pci_address": { + Type: schema.TypeString, + Computed: true, + }, + "fraction": { + Type: schema.TypeInt, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "num_virtual_display_heads": { + Type: schema.TypeInt, + Computed: true, + }, + "guest_driver_version": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "parent_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "machine_type": { + Type: schema.TypeString, + Computed: true, + }, + "hardware_clock_timezone": { Type: schema.TypeString, Computed: true, }, + "should_fail_on_script_failure": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_script_exec": { + Type: schema.TypeBool, + Computed: true, + }, + "power_state_mechanism": { + Type: schema.TypeString, + Computed: true, + }, + "vga_console_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "disk_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uuid": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "disk_size_bytes": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "disk_size_mib": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "storage_config": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "flash_mode": { + Type: schema.TypeString, + Optional: true, + }, + "storage_container_reference": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "kind": { + Type: schema.TypeString, + Optional: true, + Default: "storage_container", + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "device_properties": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_type": { + Type: schema.TypeString, + Optional: true, + Default: "DISK", + }, + "disk_address": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "data_source_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "volume_group_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "serial_port_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "index": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "is_connected": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + }, + }, }, } } @@ -256,8 +646,8 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res } d.SetId(cloneVMUUID) - return nil - //return resourceNutanixVirtualMachineCloneRead(ctx, d, meta) + //return nil + return resourceNutanixVirtualMachineCloneRead(ctx, d, meta) } func resourceNutanixVirtualMachineCloneUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -265,7 +655,7 @@ func resourceNutanixVirtualMachineCloneUpdate(ctx context.Context, d *schema.Res } func resourceNutanixVirtualMachineCloneRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - return nil + return resourceNutanixVirtualMachineRead(ctx, d, meta) } func resourceNutanixVirtualMachineCloneDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { From b2e7b467ce0514db865d4097c647c9f5d550528c Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 23 May 2022 16:57:56 +0530 Subject: [PATCH 4/8] testcases for vm clone --- ...urce_nutanix_virtual_machine_clone_test.go | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 nutanix/resource_nutanix_virtual_machine_clone_test.go diff --git a/nutanix/resource_nutanix_virtual_machine_clone_test.go b/nutanix/resource_nutanix_virtual_machine_clone_test.go new file mode 100644 index 000000000..e42cd585b --- /dev/null +++ b/nutanix/resource_nutanix_virtual_machine_clone_test.go @@ -0,0 +1,119 @@ +package nutanix + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccNutanixVirtualMachineClone_basic(t *testing.T) { + r := acctest.RandInt() + vmName := acctest.RandomWithPrefix("test-clone-vm") + resourceName := "nutanix_virtual_machine_clone.vm2" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNutanixVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNutanixVMCloneConfig(r, vmName), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "186"), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "1"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "2"), + resource.TestCheckResourceAttr(resourceName, "name", vmName), + ), + }, + }, + }) +} + +func TestAccNutanixVirtualMachineClone_WithBootDeviceOrderChange(t *testing.T) { + r := acctest.RandInt() + vmName := acctest.RandomWithPrefix("test-clone-vm") + resourceName := "nutanix_virtual_machine_clone.vm2" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNutanixVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNutanixVMCloneConfigWithBootOrder(r, vmName), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "num_sockets", "2"), + resource.TestCheckResourceAttr(resourceName, "num_vcpus_per_socket", "2"), + resource.TestCheckResourceAttr(resourceName, "name", vmName), + resource.TestCheckResourceAttr(resourceName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceName, "memory_size_mib", "186"), + resource.TestCheckResourceAttr(resourceName, "boot_device_order_list.0", "DISK"), + resource.TestCheckResourceAttr(resourceName, "boot_device_order_list.1", "NETWORK"), + resource.TestCheckResourceAttr(resourceName, "boot_device_order_list.2", "CDROM"), + ), + }, + }, + }) +} + +func testAccNutanixVMCloneConfig(r int, name string) 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" "vm1" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + boot_device_order_list = ["DISK", "CDROM"] + boot_type = "LEGACY" + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 186 + } + + resource "nutanix_virtual_machine_clone" "vm2"{ + vm_uuid = nutanix_virtual_machine.vm1.id + name = "%s" + num_vcpus_per_socket = 2 + } + `, r, name) +} + +func testAccNutanixVMCloneConfigWithBootOrder(r int, name string) 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" "vm1" { + name = "test-dou-%d" + cluster_uuid = "${local.cluster1}" + + boot_device_order_list = ["DISK", "CDROM", "NETWORK"] + boot_type = "LEGACY" + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 186 + } + resource "nutanix_virtual_machine_clone" "vm2"{ + vm_uuid = nutanix_virtual_machine.vm1.id + name = "%s" + num_vcpus_per_socket = 2 + num_sockets = 2 + boot_device_order_list = ["DISK","NETWORK","CDROM"] + } + `, r, name) +} From ae223776da95d74e54631f36877c253a9a961a72 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Wed, 25 May 2022 10:22:25 +0530 Subject: [PATCH 5/8] adding tcs --- .../resource_nutanix_virtual_machine_clone.go | 7 +- ...urce_nutanix_virtual_machine_clone_test.go | 69 +++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/nutanix/resource_nutanix_virtual_machine_clone.go b/nutanix/resource_nutanix_virtual_machine_clone.go index 25676bcfb..e1931f4bd 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone.go +++ b/nutanix/resource_nutanix_virtual_machine_clone.go @@ -193,7 +193,9 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { Type: schema.TypeString, Computed: true, }, - // Computed Resource Argument + + // COMPUTED RESOURCE ARGUMENTS + "cloud_init_cdrom_uuid": { Type: schema.TypeString, Computed: true, @@ -322,9 +324,6 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { }, }, }, - - // RESOURCES ARGUMENTS - "enable_cpu_passthrough": { Type: schema.TypeBool, Computed: true, diff --git a/nutanix/resource_nutanix_virtual_machine_clone_test.go b/nutanix/resource_nutanix_virtual_machine_clone_test.go index e42cd585b..1b6dc1e97 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone_test.go +++ b/nutanix/resource_nutanix_virtual_machine_clone_test.go @@ -61,6 +61,33 @@ func TestAccNutanixVirtualMachineClone_WithBootDeviceOrderChange(t *testing.T) { }) } +func TestAccNutanixVirtualMachineClone_WithBootType(t *testing.T) { + r := acctest.RandInt() + vmName := acctest.RandomWithPrefix("test-clone-vm") + resourceCloneName := "nutanix_virtual_machine_clone.vm2" + resource.Test(t, resource.TestCase{ + PreventPostDestroyRefresh: true, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNutanixVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNutanixVMCloneConfigWithBootType(r, vmName), + Check: resource.ComposeTestCheckFunc( + testAccCheckNutanixVirtualMachineExists(resourceCloneName), + resource.TestCheckResourceAttr(resourceCloneName, "num_sockets", "2"), + resource.TestCheckResourceAttr(resourceCloneName, "num_vcpus_per_socket", "2"), + resource.TestCheckResourceAttr(resourceCloneName, "name", vmName), + resource.TestCheckResourceAttr(resourceCloneName, "hardware_clock_timezone", "UTC"), + resource.TestCheckResourceAttr(resourceCloneName, "power_state", "ON"), + resource.TestCheckResourceAttr(resourceCloneName, "memory_size_mib", "1024"), + resource.TestCheckResourceAttr(resourceCloneName, "boot_type", "UEFI"), + ), + }, + }, + }) +} + func testAccNutanixVMCloneConfig(r int, name string) string { return fmt.Sprintf(` data "nutanix_clusters" "clusters" {} @@ -117,3 +144,45 @@ func testAccNutanixVMCloneConfigWithBootOrder(r int, name string) string { } `, r, name) } + +func testAccNutanixVMCloneConfigWithBootType(r int, name string) 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" "vm1" { + name = "test-dou-%[1]d" + cluster_uuid = "${local.cluster1}" + boot_type = "LEGACY" + boot_device_order_list = ["DISK", "CDROM"] + num_vcpus_per_socket = 1 + num_sockets = 1 + memory_size_mib = 186 + disk_list { + device_properties { + device_type = "CDROM" + disk_address = { + device_index = 0 + adapter_type = "IDE" + } + } + } + } + + resource "nutanix_virtual_machine_clone" "vm2"{ + vm_uuid = nutanix_virtual_machine.vm1.id + name = "%[2]s" + num_vcpus_per_socket = 2 + num_sockets = 2 + memory_size_mib = 1024 + boot_type = "UEFI" + + + } + `, r, name) +} From 67c0e964b6f1fc00f8cf305e792a8d9b0a36739e Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 27 May 2022 16:59:43 +0530 Subject: [PATCH 6/8] add common function for spec --- client/v3/v3_structs.go | 4 +- nutanix/resource_nutanix_virtual_machine.go | 1187 +++++++++-------- .../resource_nutanix_virtual_machine_clone.go | 563 +------- 3 files changed, 614 insertions(+), 1140 deletions(-) diff --git a/client/v3/v3_structs.go b/client/v3/v3_structs.go index a6e279df4..e6b1985a0 100644 --- a/client/v3/v3_structs.go +++ b/client/v3/v3_structs.go @@ -1668,11 +1668,9 @@ type Metadata struct { // Applied on Prism Central only. Indicate whether force to translate the spec of the fanout request to fit the target cluster API schema. ShouldForceTranslate *bool `json:"should_force_translate,omitempty" mapstructure:"should_force_translate,omitempty"` - // Logical entity version of the VM from which to clone the new VM. - EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` - //TODO: add if necessary //CategoriesMapping map[string][]string `json:"categories_mapping,omitempty" mapstructure:"categories_mapping,omitempty"` + // EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` //UseCategoriesMapping *bool `json:"use_categories_mapping,omitempty" mapstructure:"use_categories_mapping,omitempty"` } diff --git a/nutanix/resource_nutanix_virtual_machine.go b/nutanix/resource_nutanix_virtual_machine.go index c0edf290a..7ffcaa374 100644 --- a/nutanix/resource_nutanix_virtual_machine.go +++ b/nutanix/resource_nutanix_virtual_machine.go @@ -52,585 +52,7 @@ func resourceNutanixVirtualMachine() *schema.Resource { Version: 0, }, }, - Schema: map[string]*schema.Schema{ - "cloud_init_cdrom_uuid": { - Type: schema.TypeString, - Computed: true, - Optional: true, - }, - "metadata": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "categories": categoriesSchema(), - "project_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "owner_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "api_version": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - }, - "description": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "availability_zone_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "cluster_uuid": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile( - "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"), - "please see http://developer.nutanix.com/reference/prism_central/v3/api/models/cluster-reference"), - }, - "cluster_name": { - Type: schema.TypeString, - Computed: true, - }, - "state": { - Type: schema.TypeString, - Computed: true, - }, - "host_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "hypervisor_type": { - Type: schema.TypeString, - Computed: true, - }, - "nic_list_status": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "nic_type": { - Type: schema.TypeString, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "floating_ip": { - Type: schema.TypeString, - Computed: true, - }, - "model": { - Type: schema.TypeString, - Computed: true, - }, - "network_function_nic_type": { - Type: schema.TypeString, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Computed: true, - }, - "ip_endpoint_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "network_function_chain_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "num_queues": { - Type: schema.TypeInt, - Computed: true, - }, - "subnet_uuid": { - Type: schema.TypeString, - Computed: true, - }, - "subnet_name": { - Type: schema.TypeString, - Computed: true, - }, - "is_connected": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - - // RESOURCES ARGUMENTS - - "enable_cpu_passthrough": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "is_vcpu_hard_pinned": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "use_hot_add": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "num_vnuma_nodes": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "nic_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "nic_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "model": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "network_function_nic_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "ip_endpoint_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - }, - }, - }, - "network_function_chain_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "num_queues": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "subnet_uuid": { - Type: schema.TypeString, - Optional: true, - }, - "subnet_name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "is_connected": { - Type: schema.TypeString, - Optional: true, - Default: "true", - }, - }, - }, - }, - "guest_os_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "power_state": { - Type: schema.TypeString, - Computed: true, - }, - "nutanix_guest_tools": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "ngt_credentials": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - }, - "ngt_enabled_capability_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "num_vcpus_per_socket": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "num_sockets": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "gpu_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "frame_buffer_size_mib": { - Type: schema.TypeInt, - Computed: true, - }, - "vendor": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "pci_address": { - Type: schema.TypeString, - Computed: true, - }, - "fraction": { - Type: schema.TypeInt, - Computed: true, - }, - "mode": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "num_virtual_display_heads": { - Type: schema.TypeInt, - Computed: true, - }, - "guest_driver_version": { - Type: schema.TypeString, - Computed: true, - }, - "device_id": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - }, - }, - }, - "parent_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "memory_size_mib": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "boot_device_order_list": { - Type: schema.TypeList, - // // remove MaxItems when the issue #28 is fixed - // MaxItems: 1, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "boot_device_disk_address": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "boot_device_mac_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "boot_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"UEFI", "LEGACY", "SECURE_BOOT"}, false), - }, - "machine_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "hardware_clock_timezone": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "guest_customization_cloud_init_user_data": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - }, - "guest_customization_cloud_init_meta_data": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - }, - "guest_customization_cloud_init_custom_key_values": { - Type: schema.TypeMap, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Computed: true, - }, - "guest_customization_is_overridable": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "guest_customization_sysprep": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - ForceNew: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "guest_customization_sysprep_custom_key_values": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - ForceNew: true, - }, - "should_fail_on_script_failure": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "enable_script_exec": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "power_state_mechanism": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "vga_console_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "disk_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "uuid": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "disk_size_bytes": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "disk_size_mib": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "storage_config": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "flash_mode": { - Type: schema.TypeString, - Optional: true, - }, - "storage_container_reference": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "url": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "kind": { - Type: schema.TypeString, - Optional: true, - Default: "storage_container", - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - }, - }, - }, - }, - }, - }, - "device_properties": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "device_type": { - Type: schema.TypeString, - Optional: true, - Default: "DISK", - }, - "disk_address": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "data_source_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "volume_group_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "serial_port_list": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "index": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "is_connected": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - }, - }, - }, - }, + Schema: VMSpecGeneration("create"), } } @@ -2583,3 +2005,610 @@ func resourceNutanixVirtualMachineInstanceResourceV0() *schema.Resource { }, } } + +func VMSpecGeneration(kind string) map[string]*schema.Schema { + sch := map[string]*schema.Schema{ + "cloud_init_cdrom_uuid": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + "metadata": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "categories": categoriesSchema(), + "project_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "owner_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "api_version": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "availability_zone_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cluster_name": { + Type: schema.TypeString, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, + }, + "host_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "hypervisor_type": { + Type: schema.TypeString, + Computed: true, + }, + "nic_list_status": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_type": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "floating_ip": { + Type: schema.TypeString, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "network_function_nic_type": { + Type: schema.TypeString, + Computed: true, + }, + "mac_address": { + Type: schema.TypeString, + Computed: true, + }, + "ip_endpoint_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "network_function_chain_reference": { + Type: schema.TypeMap, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "num_queues": { + Type: schema.TypeInt, + Computed: true, + }, + "subnet_uuid": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_name": { + Type: schema.TypeString, + Computed: true, + }, + "is_connected": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + // RESOURCES ARGUMENTS + + "enable_cpu_passthrough": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "is_vcpu_hard_pinned": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "use_hot_add": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "num_vnuma_nodes": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "nic_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "nic_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "model": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "network_function_nic_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "mac_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "ip_endpoint_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + }, + }, + "network_function_chain_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "num_queues": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "subnet_uuid": { + Type: schema.TypeString, + Optional: true, + }, + "subnet_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "is_connected": { + Type: schema.TypeString, + Optional: true, + Default: "true", + }, + }, + }, + }, + "guest_os_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "power_state": { + Type: schema.TypeString, + Computed: true, + }, + "nutanix_guest_tools": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ngt_credentials": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + }, + "ngt_enabled_capability_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "num_vcpus_per_socket": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "num_sockets": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "gpu_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "frame_buffer_size_mib": { + Type: schema.TypeInt, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "pci_address": { + Type: schema.TypeString, + Computed: true, + }, + "fraction": { + Type: schema.TypeInt, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "num_virtual_display_heads": { + Type: schema.TypeInt, + Computed: true, + }, + "guest_driver_version": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "parent_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "memory_size_mib": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "boot_device_order_list": { + Type: schema.TypeList, + // // remove MaxItems when the issue #28 is fixed + // MaxItems: 1, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "boot_device_disk_address": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "boot_device_mac_address": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "boot_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"UEFI", "LEGACY", "SECURE_BOOT"}, false), + }, + "machine_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "hardware_clock_timezone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "guest_customization_cloud_init_user_data": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "guest_customization_cloud_init_meta_data": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "guest_customization_cloud_init_custom_key_values": { + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + Computed: true, + }, + "guest_customization_is_overridable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "guest_customization_sysprep": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "guest_customization_sysprep_custom_key_values": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + ForceNew: true, + }, + "should_fail_on_script_failure": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "enable_script_exec": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "power_state_mechanism": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "vga_console_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "disk_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uuid": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "disk_size_bytes": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "disk_size_mib": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "storage_config": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "flash_mode": { + Type: schema.TypeString, + Optional: true, + }, + "storage_container_reference": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "kind": { + Type: schema.TypeString, + Optional: true, + Default: "storage_container", + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "uuid": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "device_properties": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_type": { + Type: schema.TypeString, + Optional: true, + Default: "DISK", + }, + "disk_address": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "data_source_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "volume_group_reference": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "serial_port_list": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "index": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "is_connected": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + }, + }, + } + + if kind == "create" { + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + sch["cluster_uuid"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile( + "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"), + "please see http://developer.nutanix.com/reference/prism_central/v3/api/models/cluster-reference"), + } + } + + if kind == "clone" { + sch["source_vm_uuid"] = &schema.Schema{ + Type: schema.TypeString, + Required: true, + } + sch["name"] = &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + } + sch["cluster_uuid"] = &schema.Schema{ + Type: schema.TypeString, + Computed: true, + } + sch["task_uuid"] = &schema.Schema{ + Type: schema.TypeString, + Computed: true, + } + } + + return sch +} diff --git a/nutanix/resource_nutanix_virtual_machine_clone.go b/nutanix/resource_nutanix_virtual_machine_clone.go index e1931f4bd..1d5c78407 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone.go +++ b/nutanix/resource_nutanix_virtual_machine_clone.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" v3 "github.com/terraform-providers/terraform-provider-nutanix/client/v3" "github.com/terraform-providers/terraform-provider-nutanix/utils" ) @@ -20,556 +19,7 @@ func resourceNutanixVirtualMachineClone() *schema.Resource { UpdateContext: resourceNutanixVirtualMachineCloneUpdate, ReadContext: resourceNutanixVirtualMachineCloneRead, DeleteContext: resourceNutanixVirtualMachineCloneDelete, - Schema: map[string]*schema.Schema{ - "vm_uuid": { - Type: schema.TypeString, - Required: true, - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "num_sockets": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "num_vcpus_per_socket": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "num_threads_per_core": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "memory_size_mib": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "nic_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "nic_type": { - Type: schema.TypeString, - Optional: true, - }, - "uuid": { - Type: schema.TypeString, - Optional: true, - }, - "model": { - Type: schema.TypeString, - Optional: true, - }, - "network_function_nic_type": { - Type: schema.TypeString, - Optional: true, - }, - "mac_address": { - Type: schema.TypeString, - Optional: true, - }, - "ip_endpoint_list": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip": { - Type: schema.TypeString, - Optional: true, - }, - "type": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "network_function_chain_reference": { - Type: schema.TypeMap, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "num_queues": { - Type: schema.TypeInt, - Optional: true, - }, - "subnet_uuid": { - Type: schema.TypeString, - Optional: true, - }, - "subnet_name": { - Type: schema.TypeString, - Optional: true, - }, - "is_connected": { - Type: schema.TypeString, - Optional: true, - Default: "true", - }, - }, - }, - }, - - "boot_device_order_list": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "boot_device_disk_address": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "boot_device_mac_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "boot_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice([]string{"UEFI", "LEGACY", "SECURE_BOOT"}, false), - }, - "guest_customization_cloud_init_user_data": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "guest_customization_cloud_init_meta_data": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "guest_customization_cloud_init_custom_key_values": { - Type: schema.TypeMap, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Computed: true, - }, - "guest_customization_is_overridable": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "guest_customization_sysprep": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "guest_customization_sysprep_custom_key_values": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - }, - "metadata": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "task_uuid": { - Type: schema.TypeString, - Computed: true, - }, - - // COMPUTED RESOURCE ARGUMENTS - - "cloud_init_cdrom_uuid": { - Type: schema.TypeString, - Computed: true, - }, - "categories": categoriesSchema(), - "project_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "owner_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "api_version": { - Type: schema.TypeString, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "availability_zone_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "cluster_uuid": { - Type: schema.TypeString, - Computed: true, - }, - "cluster_name": { - Type: schema.TypeString, - Computed: true, - }, - "state": { - Type: schema.TypeString, - Computed: true, - }, - "host_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "hypervisor_type": { - Type: schema.TypeString, - Computed: true, - }, - "nic_list_status": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "nic_type": { - Type: schema.TypeString, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "floating_ip": { - Type: schema.TypeString, - Computed: true, - }, - "model": { - Type: schema.TypeString, - Computed: true, - }, - "network_function_nic_type": { - Type: schema.TypeString, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Computed: true, - }, - "ip_endpoint_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "network_function_chain_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "num_queues": { - Type: schema.TypeInt, - Computed: true, - }, - "subnet_uuid": { - Type: schema.TypeString, - Computed: true, - }, - "subnet_name": { - Type: schema.TypeString, - Computed: true, - }, - "is_connected": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "enable_cpu_passthrough": { - Type: schema.TypeBool, - Computed: true, - }, - "is_vcpu_hard_pinned": { - Type: schema.TypeBool, - Computed: true, - }, - "use_hot_add": { - Type: schema.TypeBool, - Computed: true, - }, - "num_vnuma_nodes": { - Type: schema.TypeInt, - Computed: true, - }, - "guest_os_id": { - Type: schema.TypeString, - Computed: true, - }, - "power_state": { - Type: schema.TypeString, - Computed: true, - }, - "nutanix_guest_tools": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "ngt_credentials": { - Type: schema.TypeMap, - Computed: true, - }, - "ngt_enabled_capability_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "gpu_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "frame_buffer_size_mib": { - Type: schema.TypeInt, - Computed: true, - }, - "vendor": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "pci_address": { - Type: schema.TypeString, - Computed: true, - }, - "fraction": { - Type: schema.TypeInt, - Computed: true, - }, - "mode": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "num_virtual_display_heads": { - Type: schema.TypeInt, - Computed: true, - }, - "guest_driver_version": { - Type: schema.TypeString, - Computed: true, - }, - "device_id": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - }, - }, - }, - "parent_reference": { - Type: schema.TypeMap, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "machine_type": { - Type: schema.TypeString, - Computed: true, - }, - "hardware_clock_timezone": { - Type: schema.TypeString, - Computed: true, - }, - "should_fail_on_script_failure": { - Type: schema.TypeBool, - Computed: true, - }, - "enable_script_exec": { - Type: schema.TypeBool, - Computed: true, - }, - "power_state_mechanism": { - Type: schema.TypeString, - Computed: true, - }, - "vga_console_enabled": { - Type: schema.TypeBool, - Computed: true, - }, - "disk_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "uuid": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "disk_size_bytes": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "disk_size_mib": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "storage_config": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "flash_mode": { - Type: schema.TypeString, - Optional: true, - }, - "storage_container_reference": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "url": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "kind": { - Type: schema.TypeString, - Optional: true, - Default: "storage_container", - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - }, - }, - }, - }, - }, - }, - "device_properties": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "device_type": { - Type: schema.TypeString, - Optional: true, - Default: "DISK", - }, - "disk_address": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "data_source_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "volume_group_reference": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - }, - "serial_port_list": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "index": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "is_connected": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - }, - }, - }, - }, + Schema: VMSpecGeneration("clone"), } } @@ -577,7 +27,7 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res conn := meta.(*Client).API var id string - vmUUID, nok := d.GetOk("vm_uuid") + vmUUID, nok := d.GetOk("source_vm_uuid") if nok { id = *utils.StringPtr(vmUUID.(string)) } @@ -644,13 +94,13 @@ func resourceNutanixVirtualMachineCloneCreate(ctx context.Context, d *schema.Res } } + // Set terraform state id d.SetId(cloneVMUUID) - //return nil return resourceNutanixVirtualMachineCloneRead(ctx, d, meta) } func resourceNutanixVirtualMachineCloneUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - return nil + return resourceNutanixVirtualMachineUpdate(ctx, d, meta) } func resourceNutanixVirtualMachineCloneRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -658,7 +108,7 @@ func resourceNutanixVirtualMachineCloneRead(ctx context.Context, d *schema.Resou } func resourceNutanixVirtualMachineCloneDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - return nil + return resourceNutanixVirtualMachineDelete(ctx, d, meta) } func getMetadataCloneAttributes(d *schema.ResourceData) (out *v3.Metadata) { @@ -673,9 +123,6 @@ func getMetadataCloneAttributes(d *schema.ResourceData) (out *v3.Metadata) { out.UUID = utils.StringPtr(name.(string)) } - if name, ok := meta["entity_version"]; ok { - out.EntityVersion = utils.StringPtr(name.(string)) - } return out } From 34dd18d6bc2d914be983cca0541e3e2f1d117529 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 30 May 2022 11:59:19 +0530 Subject: [PATCH 7/8] proper format for struct --- client/v3/v3_structs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/v3/v3_structs.go b/client/v3/v3_structs.go index e6b1985a0..5146fd749 100644 --- a/client/v3/v3_structs.go +++ b/client/v3/v3_structs.go @@ -1670,7 +1670,7 @@ type Metadata struct { //TODO: add if necessary //CategoriesMapping map[string][]string `json:"categories_mapping,omitempty" mapstructure:"categories_mapping,omitempty"` - // EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` + //EntityVersion *string `json:"entity_version,omitempty" mapstructure:"entity_version,omitempty"` //UseCategoriesMapping *bool `json:"use_categories_mapping,omitempty" mapstructure:"use_categories_mapping,omitempty"` } From e7ebe4502d5f639c96d63c1b56c32754907e6f92 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 13 Jun 2022 16:42:26 +0530 Subject: [PATCH 8/8] test config changes --- ...urce_nutanix_virtual_machine_clone_test.go | 6 ++--- test_config.json | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/nutanix/resource_nutanix_virtual_machine_clone_test.go b/nutanix/resource_nutanix_virtual_machine_clone_test.go index 1b6dc1e97..f4b4af45b 100644 --- a/nutanix/resource_nutanix_virtual_machine_clone_test.go +++ b/nutanix/resource_nutanix_virtual_machine_clone_test.go @@ -109,7 +109,7 @@ func testAccNutanixVMCloneConfig(r int, name string) string { } resource "nutanix_virtual_machine_clone" "vm2"{ - vm_uuid = nutanix_virtual_machine.vm1.id + source_vm_uuid = nutanix_virtual_machine.vm1.id name = "%s" num_vcpus_per_socket = 2 } @@ -136,7 +136,7 @@ func testAccNutanixVMCloneConfigWithBootOrder(r int, name string) string { memory_size_mib = 186 } resource "nutanix_virtual_machine_clone" "vm2"{ - vm_uuid = nutanix_virtual_machine.vm1.id + source_vm_uuid = nutanix_virtual_machine.vm1.id name = "%s" num_vcpus_per_socket = 2 num_sockets = 2 @@ -175,7 +175,7 @@ func testAccNutanixVMCloneConfigWithBootType(r int, name string) string { } resource "nutanix_virtual_machine_clone" "vm2"{ - vm_uuid = nutanix_virtual_machine.vm1.id + source_vm_uuid = nutanix_virtual_machine.vm1.id name = "%[2]s" num_vcpus_per_socket = 2 num_sockets = 2 diff --git a/test_config.json b/test_config.json index c82ac2558..806a473c1 100644 --- a/test_config.json +++ b/test_config.json @@ -4,38 +4,48 @@ "user_group_with_distinguished_name": { "distinguished_name": "cn=sspadmins,cn=users,dc=qa,dc=nucalm,dc=io", "display_name": "sspadmins", - "uuid": "a4f29c09-2552-4c01-992f-b96061796c98" + "uuid": "b2f92a45-c320-4b4e-a40f-51809f0d0a4b" }, "permissions": [ { "name": "", - "uuid": "57f9b783-2a85-4684-b543-1976855027d4" + "uuid": "67fc80e8-f0e7-48d4-90f2-097b4018a550" }, { "name": "Delete_ACP", - "uuid": "0696cac3-516b-460e-9bc1-d6a5d1b761d3" + "uuid": "5036942d-34c7-4bfc-bd1d-8a2bfa4c6fb6" } ], "users": [ { "principal_name": "user4@qa.nucalm.io", "expected_display_name": "user4", - "directory_service_uuid": "0791faca-1a48-499e-8171-60801dd41637" + "directory_service_uuid": "f48b10ca-2fdb-5e75-a58f-1f6e895d1134" }, { "principal_name": "user6@qa.nucalm.io", "expected_display_name": "user6", - "directory_service_uuid": "0791faca-1a48-499e-8171-60801dd41637" + "directory_service_uuid": "f48b10ca-2fdb-5e75-a58f-1f6e895d1134" }, { "principal_name": "ssptest3@qa.nucalm.io", "expected_display_name": "ssptest3", - "directory_service_uuid": "0791faca-1a48-499e-8171-60801dd41637" + "directory_service_uuid": "f48b10ca-2fdb-5e75-a58f-1f6e895d1134" } - ], + ], "node_os_version": "ntnx-1.0", "ad_rule_target": { "name": "ADGroup", "values": "sspadmins" + }, + "protection_policy":{ + "local_az":{ + "uuid":"a973cd7b-7696-4ca5-b959-04b5bcb9e683", + "cluster_uuid":"0005ded3-2367-7205-3507-ac1f6b60292f" + }, + "destination_az":{ + "uuid":"97b0cc07-d838-4925-acd7-540c11bd653d", + "cluster_uuid":"0005dc0f-13a7-62e0-185b-ac1f6b6f97e2" + } } } \ No newline at end of file