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:
parent
cb49c8da3d
commit
6b8d37e938
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue