-
Notifications
You must be signed in to change notification settings - Fork 113
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
Vm disk feature #412
Vm disk feature #412
Changes from 56 commits
6585559
e247d25
cf1e7c2
be6790f
6f4c5cb
c73d402
261d142
c431d43
414b3bf
8b03ab8
36c5487
db01eec
331e895
a85d555
e1996e3
9c63eec
5073f6c
f0bdef3
24f169d
06b36d1
30d6a79
0ca001f
8c9c7c4
4c8d081
206bc9f
48970bc
e7ef092
cb5659a
1e097fd
ae2d955
67f9230
989c183
4368664
8a257d6
5d82958
ed2cf5d
867b991
b117594
2584e44
6719df7
f00f701
4ecf4d3
b53ff76
5da5f42
f611a02
3d00b87
422b288
cde0d91
0ddb014
535b1ba
993c1b7
e2a282d
2e93c71
2243df6
f5a9047
670d980
7ec2137
e314843
87c4fdb
f36ba2c
4d2c5f4
3f3798b
ec131aa
b838db2
66ad708
9398399
c29c06f
7fe4e2f
0ffff89
9024466
7d87bcb
2dcdeae
84db69d
45fd197
94703ff
863eb45
02319bc
3c736ab
07aeb35
f050743
d7468a7
c328f91
0782758
7895068
bd60379
8de2600
4451115
97da6e4
ec0eac7
803f2a8
734559a
6643176
54759fb
35a9b08
bc20d55
d0b7480
8e95632
820c92e
70d8e52
55d6340
5eb531b
1c0d2d2
757a03d
30904da
8e54b3e
0aa3325
5615855
543bf7f
e7eaafe
584b615
f5f4d82
624adf4
c238651
a669fdd
36d7b90
3b47d98
a0e4aa3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ package vcd | |
import ( | ||
"bytes" | ||
"fmt" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" | ||
"log" | ||
"net" | ||
"sort" | ||
|
@@ -11,12 +12,12 @@ import ( | |
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" | ||
"github.com/vmware/go-vcloud-director/v2/govcd" | ||
"github.com/vmware/go-vcloud-director/v2/types/v56" | ||
) | ||
|
||
func resourceVcdVAppVm() *schema.Resource { | ||
|
||
return &schema.Resource{ | ||
Create: resourceVcdVAppVmCreate, | ||
Update: resourceVcdVAppVmUpdate, | ||
|
@@ -241,6 +242,104 @@ func resourceVcdVAppVm() *schema.Resource { | |
Optional: true, | ||
Set: resourceVcdVmIndependentDiskHash, | ||
}, | ||
"override_template_disk": { | ||
Type: schema.TypeSet, | ||
Optional: true, | ||
ForceNew: true, | ||
Description: " A block to match internal_disk interface in template. Multiple can be used. Disk will be matched by bus_type, bus_number and unit_number.", | ||
Didainius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Elem: &schema.Resource{Schema: map[string]*schema.Schema{ | ||
"bus_type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringInSlice([]string{"ide", "parallel", "sas", "paravirtual", "sata"}, true), | ||
Description: "The type of disk controller. Possible values: ide, parallel( LSI Logic Parallel SCSI), sas(LSI Logic SAS (SCSI)), paravirtual(Paravirtual (SCSI)), sata", | ||
}, | ||
"size_in_mb": { | ||
dataclouder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Type: schema.TypeInt, | ||
ForceNew: true, | ||
Required: true, | ||
Description: "The size of the disk in MB.", | ||
}, | ||
"bus_number": { | ||
Type: schema.TypeInt, | ||
ForceNew: true, | ||
Required: true, | ||
Description: "The number of the SCSI or IDE controller itself.", | ||
}, | ||
"unit_number": { | ||
Type: schema.TypeInt, | ||
ForceNew: true, | ||
Required: true, | ||
Description: "The device number on the SCSI or IDE controller of the disk.", | ||
}, | ||
"thin_provisioned": { | ||
Type: schema.TypeBool, | ||
ForceNew: true, | ||
Optional: true, | ||
Description: "Specifies whether the disk storage is pre-allocated or allocated on demand.", | ||
}, | ||
"iops": { | ||
Type: schema.TypeInt, | ||
ForceNew: true, | ||
Optional: true, | ||
Description: "Specifies the IOPS for the disk. Default - 0.", | ||
}, | ||
"storage_profile": &schema.Schema{ | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Optional: true, | ||
Description: "Storage profile to override the VM default one", | ||
}, | ||
}}, | ||
}, | ||
"internal_disk": { | ||
Didainius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Type: schema.TypeList, | ||
Didainius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Computed: true, | ||
Description: "A block will show internal disk details", | ||
Elem: &schema.Resource{Schema: map[string]*schema.Schema{ | ||
"disk_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "The disk ID.", | ||
}, | ||
"bus_type": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "The type of disk controller. Possible values: ide, parallel( LSI Logic Parallel SCSI), sas(LSI Logic SAS (SCSI)), paravirtual(Paravirtual (SCSI)), sata", | ||
}, | ||
"size_in_mb": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "The size of the disk in MB.", | ||
}, | ||
"bus_number": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "The number of the SCSI or IDE controller itself.", | ||
}, | ||
"unit_number": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "The device number on the SCSI or IDE controller of the disk.", | ||
}, | ||
"thin_provisioned": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
Description: "Specifies whether the disk storage is pre-allocated or allocated on demand.", | ||
}, | ||
"iops": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "Specifies the IOPS for the disk. Default - 0.", | ||
}, | ||
"storage_profile": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "Storage profile to override the VM default one", | ||
}, | ||
}}, | ||
}, | ||
"expose_hardware_virtualization": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
|
@@ -417,6 +516,20 @@ func resourceVcdVAppVmCreate(d *schema.ResourceData, meta interface{}) error { | |
|
||
d.SetId(vm.VM.ID) | ||
|
||
// update existing internal disks in template | ||
err = updateTemplateInternalDisks(d, meta, *vm) | ||
if err != nil { | ||
d.Set("override_template_disk", nil) | ||
return fmt.Errorf("error managing internal disks : %s", err) | ||
} else { | ||
// add details of internal disk to state | ||
errReadInternalDisk := updateStateOfInternalDisks(d, *vm) | ||
if errReadInternalDisk != nil { | ||
d.Set("internal_disk", nil) | ||
log.Printf("error reading interal disks : %s", errReadInternalDisk) | ||
} | ||
} | ||
|
||
// TODO do not trigger resourceVcdVAppVmUpdate from create. These must be separate actions. | ||
err = resourceVcdVAppVmUpdateExecute(d, meta) | ||
if err != nil { | ||
|
@@ -427,6 +540,7 @@ func resourceVcdVAppVmCreate(d *schema.ResourceData, meta interface{}) error { | |
} | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -646,7 +760,8 @@ func resourceVcdVAppVmUpdateExecute(d *schema.ResourceData, meta interface{}) er | |
if d.HasChange("memory") || d.HasChange("cpus") || d.HasChange("cpu_cores") || d.HasChange("power_on") || d.HasChange("disk") || | ||
d.HasChange("expose_hardware_virtualization") || d.HasChange("network") || d.HasChange("computer_name") { | ||
|
||
log.Printf("[TRACE] VM %s has changes: memory(%t), cpus(%t), cpu_cores(%t), power_on(%t), disk(%t), expose_hardware_virtualization(%t), network(%t), computer_name(%t)", | ||
log.Printf("[TRACE] VM %s has changes: memory(%t), cpus(%t), cpu_cores(%t), power_on(%t), disk(%t), expose_hardware_virtualization(%t),"+ | ||
" network(%t), computer_name(%t)", | ||
vm.VM.Name, d.HasChange("memory"), d.HasChange("cpus"), d.HasChange("cpu_cores"), d.HasChange("power_on"), d.HasChange("disk"), | ||
d.HasChange("expose_hardware_virtualization"), d.HasChange("network"), d.HasChange("computer_name")) | ||
|
||
|
@@ -1003,10 +1118,16 @@ func genericVcdVAppVmRead(d *schema.ResourceData, meta interface{}, origin strin | |
return fmt.Errorf("[VM read] unable to set guest properties in state: %s", err) | ||
} | ||
|
||
err = updateStateOfInternalDisks(d, *vm) | ||
if err != nil { | ||
d.Set("internal_disk", nil) | ||
return fmt.Errorf("[VM read] error reading internal disks : %s", err) | ||
} | ||
|
||
err = updateStateOfAttachedDisks(d, *vm, vdc) | ||
if err != nil { | ||
d.Set("disk", nil) | ||
return fmt.Errorf("[VM read] error updating attached disks : %s", err) | ||
return fmt.Errorf("[VM read] error reading attached disks : %s", err) | ||
} | ||
|
||
guestCustomizationSection, err := vm.GetGuestCustomizationSection() | ||
|
@@ -1042,6 +1163,109 @@ func updateStateOfAttachedDisks(d *schema.ResourceData, vm govcd.VM, vdc *govcd. | |
return d.Set("disk", transformed) | ||
} | ||
|
||
func updateStateOfInternalDisks(d *schema.ResourceData, vm govcd.VM) error { | ||
err := vm.Refresh() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
existingInternalDisks := vm.VM.VmSpecSection.DiskSection.DiskSettings | ||
lvirbalas marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a check for VmSpecSection and fail gracefully if it is nil. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
var internalDiskList []map[string]interface{} | ||
for _, internalDisk := range existingInternalDisks { | ||
newValue := map[string]interface{}{ | ||
"disk_id": internalDisk.DiskId, | ||
"bus_type": internalDiskBusTypesFromValues[internalDisk.AdapterType], | ||
"size_in_mb": int(internalDisk.SizeMb), | ||
"bus_number": internalDisk.BusNumber, | ||
"unit_number": internalDisk.UnitNumber, | ||
"iops": int(*internalDisk.Iops), | ||
"thin_provisioned": *internalDisk.ThinProvisioned, | ||
"storage_profile": internalDisk.StorageProfile.Name, | ||
} | ||
internalDiskList = append(internalDiskList, newValue) | ||
} | ||
|
||
return d.Set("internal_disk", internalDiskList) | ||
} | ||
|
||
func updateTemplateInternalDisks(d *schema.ResourceData, meta interface{}, vm govcd.VM) error { | ||
vcdClient := meta.(*VCDClient) | ||
|
||
_, vdc, err := vcdClient.GetOrgAndVdcFromResource(d) | ||
if err != nil { | ||
return fmt.Errorf(errorRetrievingOrgAndVdc, err) | ||
} | ||
|
||
diskSettings := vm.VM.VmSpecSection.DiskSection.DiskSettings | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check if VmSpecSection is not nil There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
var storageProfilePrt *types.Reference | ||
var overrideVmDefault bool | ||
|
||
internalDisksList := d.Get("override_template_disk").(*schema.Set).List() | ||
|
||
if len(internalDisksList) == 0 { | ||
return nil | ||
} | ||
|
||
for _, internalDisk := range internalDisksList { | ||
internalDiskProvidedConfig := internalDisk.(map[string]interface{}) | ||
diskCreatedByTemplate := getMatchedDisk(internalDiskProvidedConfig, diskSettings) | ||
|
||
storageProfileName := internalDiskProvidedConfig["storage_profile"].(string) | ||
if storageProfileName != "" { | ||
storageProfile, err := vdc.FindStorageProfileReference(storageProfileName) | ||
if err != nil { | ||
return fmt.Errorf("[vm creation] error retrieving storage profile %s : %s", storageProfileName, err) | ||
} | ||
storageProfilePrt = &storageProfile | ||
overrideVmDefault = true | ||
} else { | ||
storageProfilePrt = vm.VM.StorageProfile | ||
overrideVmDefault = false | ||
} | ||
|
||
if diskCreatedByTemplate == nil { | ||
return fmt.Errorf("[vm creation] disk with bus type %s, bust number %d and unit number %d not found", | ||
internalDiskProvidedConfig["bus_type"].(string), internalDiskProvidedConfig["bus_number"].(int), internalDiskProvidedConfig["unit_number"].(int)) | ||
} | ||
|
||
// Update details of internal disk for disk existing in template | ||
if value, ok := internalDiskProvidedConfig["iops"]; ok { | ||
iops := int64(value.(int)) | ||
diskCreatedByTemplate.Iops = &iops | ||
} | ||
|
||
if value, ok := internalDiskProvidedConfig["thin_provisioned"]; ok { | ||
thinProvisioned := value.(bool) | ||
diskCreatedByTemplate.ThinProvisioned = &thinProvisioned | ||
} | ||
|
||
diskCreatedByTemplate.SizeMb = int64(internalDiskProvidedConfig["size_in_mb"].(int)) | ||
diskCreatedByTemplate.StorageProfile = storageProfilePrt | ||
diskCreatedByTemplate.OverrideVmDefault = overrideVmDefault | ||
} | ||
|
||
vmSpecSection := vm.VM.VmSpecSection | ||
vmSpecSection.DiskSection.DiskSettings = diskSettings | ||
_, err = vm.UpdateInternalDisks(vmSpecSection) | ||
if err != nil { | ||
return fmt.Errorf("error updating VM disks: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func getMatchedDisk(internalDiskProvidedConfig map[string]interface{}, diskSettings []*types.DiskSettings) *types.DiskSettings { | ||
dataclouder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for _, diskSetting := range diskSettings { | ||
if diskSetting.AdapterType == internalDiskBusTypes[internalDiskProvidedConfig["bus_type"].(string)] && | ||
diskSetting.BusNumber == internalDiskProvidedConfig["bus_number"].(int) && | ||
diskSetting.UnitNumber == internalDiskProvidedConfig["unit_number"].(int) { | ||
return diskSetting | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func resourceVcdVAppVmDelete(d *schema.ResourceData, meta interface{}) error { | ||
vcdClient := meta.(*VCDClient) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This resource should be in 2.7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated