Skip to content

Commit

Permalink
Merge pull request nutanix#227 from yannickstruyf3/bugfix/remove-ide3…
Browse files Browse the repository at this point in the history
…-dependency

Bugfix/remove ide3 dependency
  • Loading branch information
marinsalinas authored Jan 27, 2021
2 parents 2036083 + f89f31e commit 3242615
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 34 deletions.
77 changes: 48 additions & 29 deletions nutanix/resource_nutanix_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ func resourceNutanixVirtualMachine() *schema.Resource {
},
},
Schema: map[string]*schema.Schema{
"cloud_init_cdrom_uuid": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"metadata": {
Type: schema.TypeMap,
Computed: true,
Expand Down Expand Up @@ -922,6 +927,8 @@ func resourceNutanixVirtualMachineRead(d *schema.ResourceData, meta interface{})
// Get client connection
conn := meta.(*Client).API
setVMTimeout(meta)

var err error
// Make request to the API
resp, err := conn.V3.GetVM(d.Id())

Expand All @@ -940,58 +947,61 @@ func resourceNutanixVirtualMachineRead(d *schema.ResourceData, meta interface{})
return nil
}

if err := flattenClusterReference(resp.Status.ClusterReference, d); err != nil {
if err = flattenClusterReference(resp.Status.ClusterReference, d); err != nil {
return fmt.Errorf("error setting cluster information for Virtual Machine %s: %s", d.Id(), err)
}

m, c := setRSEntityMetadata(resp.Metadata)

if err := d.Set("metadata", m); err != nil {
if err = d.Set("metadata", m); err != nil {
return fmt.Errorf("error setting metadata for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("categories", c); err != nil {
if err = d.Set("categories", c); err != nil {
return fmt.Errorf("error setting categories for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("project_reference", flattenReferenceValues(resp.Metadata.ProjectReference)); err != nil {
if err = d.Set("project_reference", flattenReferenceValues(resp.Metadata.ProjectReference)); err != nil {
return fmt.Errorf("error setting project_reference for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("owner_reference", flattenReferenceValues(resp.Metadata.OwnerReference)); err != nil {
if err = d.Set("owner_reference", flattenReferenceValues(resp.Metadata.OwnerReference)); err != nil {
return fmt.Errorf("error setting owner_reference for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("availability_zone_reference", flattenReferenceValues(resp.Status.AvailabilityZoneReference)); err != nil {
if err = d.Set("availability_zone_reference", flattenReferenceValues(resp.Status.AvailabilityZoneReference)); err != nil {
return fmt.Errorf("error setting availability_zone_reference for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("nic_list", flattenNicList(resp.Spec.Resources.NicList)); err != nil {
if err = d.Set("nic_list", flattenNicList(resp.Spec.Resources.NicList)); err != nil {
return fmt.Errorf("error setting nic_list for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("nic_list_status", flattenNicListStatus(resp.Status.Resources.NicList)); err != nil {
if err = d.Set("nic_list_status", flattenNicListStatus(resp.Status.Resources.NicList)); err != nil {
return fmt.Errorf("error setting nic_list_status for Virtual Machine %s: %s", d.Id(), err)
}

if err := d.Set("disk_list", flattenDiskList(resp.Spec.Resources.DiskList)); err != nil {
flatDiskList, err := flattenDiskListFilterCloudInit(d, resp.Spec.Resources.DiskList)
if err != nil {
return fmt.Errorf("error flattening disk list for vm %s: %s", d.Id(), err)
}
if err = d.Set("disk_list", flatDiskList); err != nil {
return fmt.Errorf("error setting disk_list for Virtual Machine %s: %s", d.Id(), err)
}

if err := d.Set("serial_port_list", flattenSerialPortList(resp.Status.Resources.SerialPortList)); err != nil {
if err = d.Set("serial_port_list", flattenSerialPortList(resp.Status.Resources.SerialPortList)); err != nil {
return fmt.Errorf("error setting serial_port_list for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("host_reference", flattenReferenceValues(resp.Status.Resources.HostReference)); err != nil {
if err = d.Set("host_reference", flattenReferenceValues(resp.Status.Resources.HostReference)); err != nil {
return fmt.Errorf("error setting host_reference for Virtual Machine %s: %s", d.Id(), err)
}
if err := flattenNutanixGuestTools(d, resp.Status.Resources.GuestTools); err != nil {
if err = flattenNutanixGuestTools(d, resp.Status.Resources.GuestTools); err != nil {
return fmt.Errorf("error setting nutanix_guest_tools for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("gpu_list", flattenGPUList(resp.Status.Resources.GpuList)); err != nil {
if err = d.Set("gpu_list", flattenGPUList(resp.Status.Resources.GpuList)); err != nil {
return fmt.Errorf("error setting gpu_list for Virtual Machine %s: %s", d.Id(), err)
}
if err := d.Set("parent_reference", flattenReferenceValues(resp.Status.Resources.ParentReference)); err != nil {
if err = d.Set("parent_reference", flattenReferenceValues(resp.Status.Resources.ParentReference)); err != nil {
return fmt.Errorf("error setting parent_reference for Virtual Machine %s: %s", d.Id(), err)
}

if uha, ok := d.GetOkExists("use_hot_add"); ok {
useHotAdd = uha.(bool)
}
if err := d.Set("use_hot_add", useHotAdd); err != nil {
if err = d.Set("use_hot_add", useHotAdd); err != nil {
return fmt.Errorf("error setting use_hot_add for Virtual Machine %s: %s", d.Id(), err)
}

Expand Down Expand Up @@ -1019,7 +1029,7 @@ func resourceNutanixVirtualMachineRead(d *schema.ResourceData, meta interface{})
}
}

if err := d.Set("boot_device_order_list", b); err != nil {
if err = d.Set("boot_device_order_list", b); err != nil {
return fmt.Errorf("error setting boot_device_order_list %s", err)
}

Expand Down Expand Up @@ -1292,7 +1302,6 @@ func resourceNutanixVirtualMachineUpdate(d *schema.ResourceData, meta interface{
if err != nil {
return err
}

res.DiskList = expandDiskListUpdate(d, response)

postCdromCount, err := CountDiskListCdrom(res.DiskList)
Expand Down Expand Up @@ -1798,13 +1807,11 @@ func expandIPAddressList(ipl []interface{}) []*v3.IPAddress {

func expandDiskListUpdate(d *schema.ResourceData, vm *v3.VMIntentResponse) []*v3.VMDisk {
eDiskList := expandDiskList(d)

if vm.Spec != nil && vm.Spec.Resources != nil {
for _, disk := range vm.Spec.Resources.DiskList {
if disk.DeviceProperties != nil && disk.DeviceProperties.DiskAddress != nil {
index := disk.DeviceProperties.DiskAddress.DeviceIndex
adapterType := disk.DeviceProperties.DiskAddress.AdapterType
if *index == 3 && *adapterType == IDE {
if cloudInitCdromUUIDInt, ok := d.GetOk("cloud_init_cdrom_uuid"); ok {
cloudInitCdromUUID := cloudInitCdromUUIDInt.(string)
if cloudInitCdromUUID != "" && vm.Spec != nil && vm.Spec.Resources != nil {
for _, disk := range vm.Spec.Resources.DiskList {
if disk.UUID != nil && *disk.UUID == cloudInitCdromUUID {
eDiskList = append(eDiskList, disk)
}
}
Expand Down Expand Up @@ -2120,13 +2127,25 @@ func waitForIPRefreshFunc(client *v3.Client, vmUUID string) resource.StateRefres
}
}

func CountDiskListCdrom(dl []*v3.VMDisk) (int, error) {
counter := 0
func GetCdromDiskList(dl []*v3.VMDisk) []*v3.VMDisk {
cdList := make([]*v3.VMDisk, 0)
for _, v := range dl {
if v.DeviceProperties != nil && *v.DeviceProperties.DeviceType == "CDROM" {
counter++
if isCdromDisk(v) {
cdList = append(cdList, v)
}
}
return cdList
}

func isCdromDisk(d *v3.VMDisk) bool {
if d.DeviceProperties != nil && *d.DeviceProperties.DeviceType == "CDROM" {
return true
}
return false
}

func CountDiskListCdrom(dl []*v3.VMDisk) (int, error) {
counter := len(GetCdromDiskList(dl))
return counter, nil
}

Expand Down
102 changes: 97 additions & 5 deletions nutanix/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,99 @@ func flattenNicList(nics []*v3.VMNic) []map[string]interface{} {
return nicLists
}

func usesGuestCustomization(d *schema.ResourceData) bool {
keys := []string{
"guest_customization_cloud_init_user_data",
"guest_customization_cloud_init_meta_data",
"guest_customization_cloud_init_custom_key_values",
"guest_customization_is_overridable",
"guest_customization_sysprep",
"guest_customization_sysprep_custom_key_values"}
for _, k := range keys {
if _, ok := d.GetOk(k); ok {
return true
}
}
return false
}

func getDeviceIndexForDisk(disk *v3.VMDisk) (*int64, error) {
if disk.DeviceProperties == nil {
return nil, fmt.Errorf("deviceproperties was nil for disk")
}
if disk.DeviceProperties.DiskAddress == nil {
return nil, fmt.Errorf("disk address was nil for disk")
}
if disk.DeviceProperties.DiskAddress.DeviceIndex == nil {
return nil, fmt.Errorf("device index was nil for disk")
}
diskIndex := *disk.DeviceProperties.DiskAddress.DeviceIndex
return &diskIndex, nil
}

func flattenDiskListFilterCloudInit(d *schema.ResourceData, disks []*v3.VMDisk) ([]map[string]interface{}, error) {
//todo check if guestcust is passed -> if it is not passed, just continue without searching for cloud-init uuid
// reason: no device_index or disk id will result in crash
cloudInitCdromUUID := ""
if cloudInitCdromUUIDInput, cliOk := d.GetOk("cloud_init_cdrom_uuid"); cliOk {
cloudInitCdromUUID = cloudInitCdromUUIDInput.(string)
}
filteredDiskList := disks
potentialCloudInitIDs := make([]string, 0)
if cloudInitCdromUUID == "" && usesGuestCustomization(d) {
filteredDiskList = make([]*v3.VMDisk, 0)
//expand the user inputted list of disks
expandedOrgDiskList := expandDiskList(d)
//extract the CD-rom drives
userCdromDiskList := GetCdromDiskList(expandedOrgDiskList)
for _, eDisk := range disks {
//if existing disk is not CD-rom, append it to the list and continue
if !isCdromDisk(eDisk) {
filteredDiskList = append(filteredDiskList, eDisk)
continue
} else {
//Get existing CDrom device Index
eDiskIndexP, err := getDeviceIndexForDisk(eDisk) //*eDisk.DeviceProperties.DiskAddress.DeviceIndex
if err != nil {
return nil, err
}
eDiskIndex := *eDiskIndexP
match := false
// Loop over the user defined cdrom drives
for _, uDisk := range userCdromDiskList {
//extract the device index of the user defined cdrom
uDiskIndexP, err := getDeviceIndexForDisk(uDisk)
if err != nil {
return nil, err
}
uDiskIndex := *uDiskIndexP
// if there is a matching device index for a userdefined and an existing cdrom, it is not the cloud-init one
if eDiskIndex == uDiskIndex {
filteredDiskList = append(filteredDiskList, eDisk)
match = true
break
}
}
if !match {
potentialCloudInitIDs = append(potentialCloudInitIDs, *eDisk.UUID)
}
}
}
if len(potentialCloudInitIDs) == 1 {
cloudInitCdromUUID = potentialCloudInitIDs[0]
d.Set("cloud_init_cdrom_uuid", cloudInitCdromUUID)
}
if len(potentialCloudInitIDs) > 1 {
return nil, fmt.Errorf("more than 1 unknown cd-rom device: %v", potentialCloudInitIDs)
}
}
fDiskList := flattenDiskListHelper(filteredDiskList, cloudInitCdromUUID)
return fDiskList, nil
}
func flattenDiskList(disks []*v3.VMDisk) []map[string]interface{} {
return flattenDiskListHelper(disks, "")
}
func flattenDiskListHelper(disks []*v3.VMDisk, cloudInitCdromUUID string) []map[string]interface{} {
diskList := make([]map[string]interface{}, 0)
for _, v := range disks {
var deviceProps []map[string]interface{}
Expand All @@ -114,10 +206,6 @@ func flattenDiskList(disks []*v3.VMDisk) []map[string]interface{} {
index := fmt.Sprintf("%d", utils.Int64Value(v.DeviceProperties.DiskAddress.DeviceIndex))
adapter := v.DeviceProperties.DiskAddress.AdapterType

if index == "3" && *adapter == IDE {
continue
}

deviceProps[0] = map[string]interface{}{
"device_type": v.DeviceProperties.DeviceType,
"disk_address": map[string]interface{}{
Expand All @@ -141,8 +229,12 @@ func flattenDiskList(disks []*v3.VMDisk) []map[string]interface{} {
})
}

diskUUID := utils.StringValue(v.UUID)
if cloudInitCdromUUID == diskUUID {
continue
}
diskList = append(diskList, map[string]interface{}{
"uuid": utils.StringValue(v.UUID),
"uuid": diskUUID,
"disk_size_bytes": utils.Int64Value(v.DiskSizeBytes),
"disk_size_mib": utils.Int64Value(v.DiskSizeMib),
"device_properties": deviceProps,
Expand Down

0 comments on commit 3242615

Please sign in to comment.