Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/remove ide3 dependency #227

Merged
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
yannickstruyf3 marked this conversation as resolved.
Show resolved Hide resolved
// 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
yannickstruyf3 marked this conversation as resolved.
Show resolved Hide resolved
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