Skip to content

Commit b05d5fb

Browse files
author
Sander van Harmelen
authored
Merge pull request #7612 from svanharmelen/b-cloudstack-provider
provider/cloudstack: fix and improve several use cases
2 parents 30ff7df + 2854369 commit b05d5fb

14 files changed

+137
-194
lines changed

builtin/providers/cloudstack/resource_cloudstack_disk.go

+12-151
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ func resourceCloudStackDisk() *schema.Resource {
2828
Default: false,
2929
},
3030

31-
"device": &schema.Schema{
32-
Type: schema.TypeString,
31+
"device_id": &schema.Schema{
32+
Type: schema.TypeInt,
3333
Optional: true,
3434
Computed: true,
3535
},
@@ -59,6 +59,7 @@ func resourceCloudStackDisk() *schema.Resource {
5959
"project": &schema.Schema{
6060
Type: schema.TypeString,
6161
Optional: true,
62+
Computed: true,
6263
ForceNew: true,
6364
},
6465

@@ -116,7 +117,7 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
116117
// Set the volume ID and partials
117118
d.SetId(r.Id)
118119
d.SetPartial("name")
119-
d.SetPartial("device")
120+
d.SetPartial("device_id")
120121
d.SetPartial("disk_offering")
121122
d.SetPartial("size")
122123
d.SetPartial("virtual_machine_id")
@@ -163,28 +164,7 @@ func resourceCloudStackDiskRead(d *schema.ResourceData, meta interface{}) error
163164
setValueOrID(d, "zone", v.Zonename, v.Zoneid)
164165

165166
if v.Attached != "" {
166-
// Get the virtual machine details
167-
vm, _, err := cs.VirtualMachine.GetVirtualMachineByID(
168-
v.Virtualmachineid,
169-
cloudstack.WithProject(d.Get("project").(string)),
170-
)
171-
if err != nil {
172-
return err
173-
}
174-
175-
// Get the guest OS type details
176-
os, _, err := cs.GuestOS.GetOsTypeByID(vm.Guestosid)
177-
if err != nil {
178-
return err
179-
}
180-
181-
// Get the guest OS category details
182-
c, _, err := cs.GuestOS.GetOsCategoryByID(os.Oscategoryid)
183-
if err != nil {
184-
return err
185-
}
186-
187-
d.Set("device", retrieveDeviceName(v.Deviceid, c.Name))
167+
d.Set("device_id", int(v.Deviceid))
188168
d.Set("virtual_machine_id", v.Virtualmachineid)
189169
}
190170

@@ -235,9 +215,9 @@ func resourceCloudStackDiskUpdate(d *schema.ResourceData, meta interface{}) erro
235215
d.SetPartial("size")
236216
}
237217

238-
// If the device changed, just detach here so we can re-attach the
218+
// If the device ID changed, just detach here so we can re-attach the
239219
// volume at the end of this function
240-
if d.HasChange("device") || d.HasChange("virtual_machine") {
220+
if d.HasChange("device_id") || d.HasChange("virtual_machine") {
241221
// Detach the volume
242222
if err := resourceCloudStackDiskDetach(d, meta); err != nil {
243223
return fmt.Errorf("Error detaching disk %s from virtual machine: %s", name, err)
@@ -253,7 +233,7 @@ func resourceCloudStackDiskUpdate(d *schema.ResourceData, meta interface{}) erro
253233

254234
// Set the additional partials
255235
d.SetPartial("attach")
256-
d.SetPartial("device")
236+
d.SetPartial("device_id")
257237
d.SetPartial("virtual_machine_id")
258238
} else {
259239
// Detach the volume
@@ -304,21 +284,14 @@ func resourceCloudStackDiskAttach(d *schema.ResourceData, meta interface{}) erro
304284
// Create a new parameter struct
305285
p := cs.Volume.NewAttachVolumeParams(d.Id(), virtualmachineid.(string))
306286

307-
if device, ok := d.GetOk("device"); ok {
308-
// Retrieve the device ID
309-
deviceid := retrieveDeviceID(device.(string))
310-
if deviceid == -1 {
311-
return fmt.Errorf("Device %s is not a valid device", device.(string))
312-
}
313-
314-
// Set the device ID
315-
p.SetDeviceid(deviceid)
287+
if deviceid, ok := d.GetOk("device_id"); ok {
288+
p.SetDeviceid(int64(deviceid.(int)))
316289
}
317290

318291
// Attach the new volume
319-
r, err := Retry(4, retryableAttachVolumeFunc(cs, p))
292+
r, err := Retry(10, retryableAttachVolumeFunc(cs, p))
320293
if err != nil {
321-
return err
294+
return fmt.Errorf("Error attaching volume to VM: %s", err)
322295
}
323296

324297
d.SetId(r.(*cloudstack.AttachVolumeResponse).Id)
@@ -397,115 +370,3 @@ func retryableAttachVolumeFunc(
397370
return r, nil
398371
}
399372
}
400-
401-
func retrieveDeviceID(device string) int64 {
402-
switch device {
403-
case "/dev/xvdb", "D:":
404-
return 1
405-
case "/dev/xvdc", "E:":
406-
return 2
407-
case "/dev/xvde", "F:":
408-
return 4
409-
case "/dev/xvdf", "G:":
410-
return 5
411-
case "/dev/xvdg", "H:":
412-
return 6
413-
case "/dev/xvdh", "I:":
414-
return 7
415-
case "/dev/xvdi", "J:":
416-
return 8
417-
case "/dev/xvdj", "K:":
418-
return 9
419-
case "/dev/xvdk", "L:":
420-
return 10
421-
case "/dev/xvdl", "M:":
422-
return 11
423-
case "/dev/xvdm", "N:":
424-
return 12
425-
case "/dev/xvdn", "O:":
426-
return 13
427-
case "/dev/xvdo", "P:":
428-
return 14
429-
case "/dev/xvdp", "Q:":
430-
return 15
431-
default:
432-
return -1
433-
}
434-
}
435-
436-
func retrieveDeviceName(device int64, os string) string {
437-
switch device {
438-
case 1:
439-
if os == "Windows" {
440-
return "D:"
441-
}
442-
return "/dev/xvdb"
443-
case 2:
444-
if os == "Windows" {
445-
return "E:"
446-
}
447-
return "/dev/xvdc"
448-
case 4:
449-
if os == "Windows" {
450-
return "F:"
451-
}
452-
return "/dev/xvde"
453-
case 5:
454-
if os == "Windows" {
455-
return "G:"
456-
}
457-
return "/dev/xvdf"
458-
case 6:
459-
if os == "Windows" {
460-
return "H:"
461-
}
462-
return "/dev/xvdg"
463-
case 7:
464-
if os == "Windows" {
465-
return "I:"
466-
}
467-
return "/dev/xvdh"
468-
case 8:
469-
if os == "Windows" {
470-
return "J:"
471-
}
472-
return "/dev/xvdi"
473-
case 9:
474-
if os == "Windows" {
475-
return "K:"
476-
}
477-
return "/dev/xvdj"
478-
case 10:
479-
if os == "Windows" {
480-
return "L:"
481-
}
482-
return "/dev/xvdk"
483-
case 11:
484-
if os == "Windows" {
485-
return "M:"
486-
}
487-
return "/dev/xvdl"
488-
case 12:
489-
if os == "Windows" {
490-
return "N:"
491-
}
492-
return "/dev/xvdm"
493-
case 13:
494-
if os == "Windows" {
495-
return "O:"
496-
}
497-
return "/dev/xvdn"
498-
case 14:
499-
if os == "Windows" {
500-
return "P:"
501-
}
502-
return "/dev/xvdo"
503-
case 15:
504-
if os == "Windows" {
505-
return "Q:"
506-
}
507-
return "/dev/xvdp"
508-
default:
509-
return "unknown"
510-
}
511-
}

builtin/providers/cloudstack/resource_cloudstack_disk_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestAccCloudStackDisk_basic(t *testing.T) {
2929
})
3030
}
3131

32-
func TestAccCloudStackDisk_device(t *testing.T) {
32+
func TestAccCloudStackDisk_deviceID(t *testing.T) {
3333
var disk cloudstack.Volume
3434

3535
resource.Test(t, resource.TestCase{
@@ -38,13 +38,13 @@ func TestAccCloudStackDisk_device(t *testing.T) {
3838
CheckDestroy: testAccCheckCloudStackDiskDestroy,
3939
Steps: []resource.TestStep{
4040
resource.TestStep{
41-
Config: testAccCloudStackDisk_device,
41+
Config: testAccCloudStackDisk_deviceID,
4242
Check: resource.ComposeTestCheckFunc(
4343
testAccCheckCloudStackDiskExists(
4444
"cloudstack_disk.foo", &disk),
4545
testAccCheckCloudStackDiskAttributes(&disk),
4646
resource.TestCheckResourceAttr(
47-
"cloudstack_disk.foo", "device", "/dev/xvde"),
47+
"cloudstack_disk.foo", "device_id", "4"),
4848
),
4949
},
5050
},
@@ -170,7 +170,7 @@ resource "cloudstack_disk" "foo" {
170170
CLOUDSTACK_DISK_OFFERING_1,
171171
CLOUDSTACK_ZONE)
172172

173-
var testAccCloudStackDisk_device = fmt.Sprintf(`
173+
var testAccCloudStackDisk_deviceID = fmt.Sprintf(`
174174
resource "cloudstack_instance" "foobar" {
175175
name = "terraform-test"
176176
display_name = "terraform"
@@ -184,7 +184,7 @@ resource "cloudstack_instance" "foobar" {
184184
resource "cloudstack_disk" "foo" {
185185
name = "terraform-disk"
186186
attach = true
187-
device = "/dev/xvde"
187+
device_id = 4
188188
disk_offering = "%s"
189189
virtual_machine_id = "${cloudstack_instance.foobar.id}"
190190
zone = "${cloudstack_instance.foobar.zone}"

builtin/providers/cloudstack/resource_cloudstack_instance.go

+26-23
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func resourceCloudStackInstance() *schema.Resource {
105105
"project": &schema.Schema{
106106
Type: schema.TypeString,
107107
Optional: true,
108+
Computed: true,
108109
ForceNew: true,
109110
},
110111

@@ -251,9 +252,12 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{})
251252
p.SetKeypair(keypair.(string))
252253
}
253254

254-
if ud, err := getUserData(d, cs); err != nil {
255-
return err
256-
} else if len(ud) > 0 {
255+
if userData, ok := d.GetOk("user_data"); ok {
256+
ud, err := getUserData(userData.(string), cs.HTTPGETOnly)
257+
if err != nil {
258+
return err
259+
}
260+
257261
p.SetUserdata(ud)
258262
}
259263

@@ -437,6 +441,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
437441
d.SetPartial("service_offering")
438442
}
439443

444+
// Check if the affinity group IDs have changed and if so, update the IDs
440445
if d.HasChange("affinity_group_ids") {
441446
p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
442447
groups := []string{}
@@ -450,6 +455,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
450455
p.SetAffinitygroupids(groups)
451456
}
452457

458+
// Check if the affinity group names have changed and if so, update the names
453459
if d.HasChange("affinity_group_names") {
454460
p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
455461
groups := []string{}
@@ -463,6 +469,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
463469
p.SetAffinitygroupids(groups)
464470
}
465471

472+
// Check if the keypair has changed and if so, update the keypair
466473
if d.HasChange("keypair") {
467474
log.Printf("[DEBUG] SSH keypair changed for %s, starting update", name)
468475

@@ -477,10 +484,11 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
477484
d.SetPartial("keypair")
478485
}
479486

487+
// Check if the user data has changed and if so, update the user data
480488
if d.HasChange("user_data") {
481489
log.Printf("[DEBUG] user_data changed for %s, starting update", name)
482490

483-
ud, err := getUserData(d, cs)
491+
ud, err := getUserData(d.Get("user_data").(string), cs.HTTPGETOnly)
484492
if err != nil {
485493
return err
486494
}
@@ -533,28 +541,23 @@ func resourceCloudStackInstanceDelete(d *schema.ResourceData, meta interface{})
533541
return nil
534542
}
535543

536-
// getUserData returns user_data as a base64 encoded string. An empty
537-
// string is returned if unset.
538-
func getUserData(d *schema.ResourceData, cs *cloudstack.CloudStackClient) (string, error) {
539-
if userData, ok := d.GetOk("user_data"); ok {
540-
ud := base64.StdEncoding.EncodeToString([]byte(userData.(string)))
541-
542-
// deployVirtualMachine uses POST by default, so max userdata is 32K
543-
maxUD := 32768
544+
// getUserData returns the user data as a base64 encoded string
545+
func getUserData(userData string, httpGetOnly bool) (string, error) {
546+
ud := base64.StdEncoding.EncodeToString([]byte(userData))
544547

545-
if cs.HTTPGETOnly {
546-
// deployVirtualMachine using GET instead, so max userdata is 2K
547-
maxUD = 2048
548-
}
548+
// deployVirtualMachine uses POST by default, so max userdata is 32K
549+
maxUD := 32768
549550

550-
if len(ud) > maxUD {
551-
return "", fmt.Errorf(
552-
"The supplied user_data contains %d bytes after encoding, "+
553-
"this exeeds the limit of %d bytes", len(ud), maxUD)
554-
}
551+
if httpGetOnly {
552+
// deployVirtualMachine using GET instead, so max userdata is 2K
553+
maxUD = 2048
554+
}
555555

556-
return ud, nil
556+
if len(ud) > maxUD {
557+
return "", fmt.Errorf(
558+
"The supplied user_data contains %d bytes after encoding, "+
559+
"this exeeds the limit of %d bytes", len(ud), maxUD)
557560
}
558561

559-
return "", nil
562+
return ud, nil
560563
}

builtin/providers/cloudstack/resource_cloudstack_ipaddress.go

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func resourceCloudStackIPAddress() *schema.Resource {
3131
"project": &schema.Schema{
3232
Type: schema.TypeString,
3333
Optional: true,
34+
Computed: true,
3435
ForceNew: true,
3536
},
3637

0 commit comments

Comments
 (0)