Fix issue #3033 and update tweak several cloudstack resources

- Added a retry loop for attaching disks as this something was tried to
fast when the VM was still booting
- Fix issue #3033
- Update docs for latest updates and done some minor refactoring
(styling)
This commit is contained in:
Sander van Harmelen 2015-08-21 16:59:35 +02:00
parent cb49c8da3d
commit 6b8d37e938
9 changed files with 102 additions and 94 deletions

View File

@ -56,17 +56,17 @@ func resourceCloudStackDisk() *schema.Resource {
Optional: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
@ -80,17 +80,6 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
// Create a new parameter struct
p := cs.Volume.NewCreateVolumeParams(name)
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
// Retrieve the disk_offering UUID
diskofferingid, e := retrieveUUID(cs, "disk_offering", d.Get("disk_offering").(string))
if e != nil {
@ -104,6 +93,17 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
p.SetSize(int64(d.Get("size").(int)))
}
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
// Retrieve the zone UUID
zoneid, e := retrieveUUID(cs, "zone", d.Get("zone").(string))
if e != nil {
@ -125,6 +125,7 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
d.SetPartial("disk_offering")
d.SetPartial("size")
d.SetPartial("virtual_machine")
d.SetPartial("project")
d.SetPartial("zone")
if d.Get("attach").(bool) {
@ -160,8 +161,8 @@ func resourceCloudStackDiskRead(d *schema.ResourceData, meta interface{}) error
d.Set("size", int(v.Size/(1024*1024*1024))) // Needed to get GB's again
setValueOrUUID(d, "disk_offering", v.Diskofferingname, v.Diskofferingid)
setValueOrUUID(d, "zone", v.Zonename, v.Zoneid)
setValueOrUUID(d, "project", v.Project, v.Projectid)
setValueOrUUID(d, "zone", v.Zonename, v.Zoneid)
if v.Attached != "" {
// Get the virtual machine details
@ -319,12 +320,12 @@ func resourceCloudStackDiskAttach(d *schema.ResourceData, meta interface{}) erro
}
// Attach the new volume
r, err := cs.Volume.AttachVolume(p)
r, err := Retry(4, retryableAttachVolumeFunc(cs, p))
if err != nil {
return err
}
d.SetId(r.Id)
d.SetId(r.(*cloudstack.AttachVolumeResponse).Id)
return nil
}
@ -386,6 +387,18 @@ func isAttached(cs *cloudstack.CloudStackClient, id string) (bool, error) {
return v.Attached != "", nil
}
func retryableAttachVolumeFunc(
cs *cloudstack.CloudStackClient,
p *cloudstack.AttachVolumeParams) func() (interface{}, error) {
return func() (interface{}, error) {
r, err := cs.Volume.AttachVolume(p)
if err != nil {
return nil, err
}
return r, nil
}
}
func retrieveDeviceID(device string) int64 {
switch device {
case "/dev/xvdb", "D:":
@ -426,87 +439,73 @@ func retrieveDeviceName(device int64, os string) string {
case 1:
if os == "Windows" {
return "D:"
} else {
return "/dev/xvdb"
}
return "/dev/xvdb"
case 2:
if os == "Windows" {
return "E:"
} else {
return "/dev/xvdc"
}
return "/dev/xvdc"
case 4:
if os == "Windows" {
return "F:"
} else {
return "/dev/xvde"
}
return "/dev/xvde"
case 5:
if os == "Windows" {
return "G:"
} else {
return "/dev/xvdf"
}
return "/dev/xvdf"
case 6:
if os == "Windows" {
return "H:"
} else {
return "/dev/xvdg"
}
return "/dev/xvdg"
case 7:
if os == "Windows" {
return "I:"
} else {
return "/dev/xvdh"
}
return "/dev/xvdh"
case 8:
if os == "Windows" {
return "J:"
} else {
return "/dev/xvdi"
}
return "/dev/xvdi"
case 9:
if os == "Windows" {
return "K:"
} else {
return "/dev/xvdj"
}
return "/dev/xvdj"
case 10:
if os == "Windows" {
return "L:"
} else {
return "/dev/xvdk"
}
return "/dev/xvdk"
case 11:
if os == "Windows" {
return "M:"
} else {
return "/dev/xvdl"
}
return "/dev/xvdl"
case 12:
if os == "Windows" {
return "N:"
} else {
return "/dev/xvdm"
}
return "/dev/xvdm"
case 13:
if os == "Windows" {
return "O:"
} else {
return "/dev/xvdn"
}
return "/dev/xvdn"
case 14:
if os == "Windows" {
return "P:"
} else {
return "/dev/xvdo"
}
return "/dev/xvdo"
case 15:
if os == "Windows" {
return "Q:"
} else {
return "/dev/xvdp"
}
return "/dev/xvdp"
default:
return "unknown"
}

View File

@ -28,16 +28,16 @@ func resourceCloudStackIPAddress() *schema.Resource {
ForceNew: true,
},
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}
@ -52,17 +52,6 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
// Create a new parameter struct
p := cs.Address.NewAssociateIpAddressParams()
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
if network, ok := d.GetOk("network"); ok {
// Retrieve the network UUID
networkid, e := retrieveUUID(cs, "network", network.(string))
@ -85,6 +74,17 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
p.SetVpcid(vpcid)
}
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
// Associate a new IP address
r, err := cs.Address.AssociateIpAddress(p)
if err != nil {

View File

@ -52,17 +52,17 @@ func resourceCloudStackNetwork() *schema.Resource {
ForceNew: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
@ -93,17 +93,6 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e
// Create a new parameter struct
p := cs.Network.NewCreateNetworkParams(displaytext.(string), name, networkofferingid, zoneid)
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
// Get the network details from the CIDR
m, err := parseCIDR(d.Get("cidr").(string))
if err != nil {
@ -136,6 +125,17 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e
}
}
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
}
// Create the new network
r, err := cs.Network.CreateNetwork(p)
if err != nil {
@ -168,8 +168,8 @@ func resourceCloudStackNetworkRead(d *schema.ResourceData, meta interface{}) err
d.Set("cidr", n.Cidr)
setValueOrUUID(d, "network_offering", n.Networkofferingname, n.Networkofferingid)
setValueOrUUID(d, "zone", n.Zonename, n.Zoneid)
setValueOrUUID(d, "project", n.Project, n.Projectid)
setValueOrUUID(d, "zone", n.Zonename, n.Zoneid)
return nil
}

View File

@ -224,10 +224,7 @@ func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{})
// Delete all expected UUIDs from the uuids map
for _, forward := range forwards.List() {
forward := forward.(map[string]interface{})
for _, id := range forward["uuids"].(map[string]interface{}) {
delete(uuids, id.(string))
}
delete(uuids, forward["uuid"].(string))
}
for uuid := range uuids {

View File

@ -40,16 +40,17 @@ func resourceCloudStackVPC() *schema.Resource {
ForceNew: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
@ -80,7 +81,7 @@ func resourceCloudStackVPCCreate(d *schema.ResourceData, meta interface{}) error
// Create a new parameter struct
p := cs.VPC.NewCreateVPCParams(d.Get("cidr").(string), displaytext.(string), name, vpcofferingid, zoneid)
// If there is a project supplied, we retreive and set the project id
// If there is a project supplied, we retreive and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project UUID
projectid, e := retrieveUUID(cs, "project", project.(string))
@ -122,8 +123,6 @@ func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
d.Set("display_text", v.Displaytext)
d.Set("cidr", v.Cidr)
setValueOrUUID(d, "zone", v.Zonename, v.Zoneid)
// Get the VPC offering details
o, _, err := cs.VPC.GetVPCOfferingByID(v.Vpcofferingid)
if err != nil {
@ -132,6 +131,7 @@ func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
setValueOrUUID(d, "vpc_offering", o.Name, v.Vpcofferingid)
setValueOrUUID(d, "project", v.Project, v.Projectid)
setValueOrUUID(d, "zone", v.Zonename, v.Zoneid)
return nil
}

View File

@ -47,6 +47,9 @@ The following arguments are supported:
* `virtual_machine` - (Optional) The name or ID of the virtual machine to which you
want to attach the disk volume.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.
* `zone` - (Required) The name or ID of the zone where this disk volume will be available.
Changing this forces a new resource to be created.

View File

@ -28,6 +28,9 @@ The following arguments are supported:
* `vpc` - (Optional) The name or ID of the VPC for which an IP address should
be acquired and associated. Changing this forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.
*NOTE: Either `network` or `vpc` should have a value!*
## Attributes Reference

View File

@ -43,6 +43,9 @@ The following arguments are supported:
* `aclid` - (Optional) The ID of a network ACL that should be attached to the
network. Changing this forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.
* `zone` - (Required) The name or ID of the zone where this disk volume will be
available. Changing this forces a new resource to be created.

View File

@ -37,6 +37,9 @@ The following arguments are supported:
* `vpc_offering` - (Required) The name or ID of the VPC offering to use for this VPC.
Changing this forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.
* `zone` - (Required) The name or ID of the zone where this disk volume will be
available. Changing this forces a new resource to be created.