Added protection for api limiting

This commit is contained in:
Brett Mack 2015-11-02 16:39:56 +00:00
parent 8376a5a160
commit 965882bfdf
5 changed files with 155 additions and 180 deletions

View File

@ -4,9 +4,7 @@ import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"github.com/opencredo/vmware-govcd"
"regexp"
"strings"
"time"
)
func resourceVcdDNAT() *schema.Resource {
@ -48,41 +46,30 @@ func resourceVcdDNATCreate(d *schema.ResourceData, meta interface{}) error {
// operation we must wait until we can aquire a lock on the client
vcd_client.Mutex.Lock()
defer vcd_client.Mutex.Unlock()
var task govcd.Task
portString := getPortString(d.Get("port").(int))
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
// Creating a loop to offer further protection from the edge gateway erroring
// due to being busy eg another person is using another client so wouldn't be
// constrained by out lock. If the edge gateway reurns with a busy error, wait
// 3 seconds and then try again. Continue until a non-busy error or success
for {
err := vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
task, err = edgeGateway.AddNATMapping("DNAT", d.Get("external_ip").(string),
err = retryCall(4, func() error {
task, err := edgeGateway.AddNATMapping("DNAT", d.Get("external_ip").(string),
d.Get("internal_ip").(string),
portString)
if err != nil {
if v, _ := regexp.MatchString("is busy completing an operation.$", err.Error()); v {
time.Sleep(3 * time.Second)
continue
} else {
return fmt.Errorf("Error setting DNAT rules: %#v", err)
}
return fmt.Errorf("Error setting DNAT rules: %#v", err)
}
break
}
err := task.WaitTaskCompletion()
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
@ -129,41 +116,23 @@ func resourceVcdDNATDelete(d *schema.ResourceData, meta interface{}) error {
// operation we must wait until we can aquire a lock on the client
vcd_client.Mutex.Lock()
defer vcd_client.Mutex.Unlock()
var task govcd.Task
portString := getPortString(d.Get("port").(int))
// Creating a loop to offer further protection from the edge gateway erroring
// due to being busy eg another person is using another client so wouldn't be
// constrained by out lock. If the edge gateway reurns with a busy error, wait
// 3 seconds and then try again. Continue until a non-busy error or success
for {
err := vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
task, err = edgeGateway.RemoveNATMapping("DNAT", d.Get("external_ip").(string),
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
err = retryCall(4, func() error {
task, err := edgeGateway.RemoveNATMapping("DNAT", d.Get("external_ip").(string),
d.Get("internal_ip").(string),
portString)
if err != nil {
if v, _ := regexp.MatchString("is busy completing an operation.$", err.Error()); v {
time.Sleep(3 * time.Second)
continue
} else {
return fmt.Errorf("Error setting DNAT rules: %#v", err)
}
return fmt.Errorf("Error setting DNAT rules: %#v", err)
}
break
}
err := task.WaitTaskCompletion()
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}

View File

@ -6,12 +6,10 @@ import (
"bytes"
"fmt"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/opencredo/vmware-govcd"
types "github.com/opencredo/vmware-govcd/types/v56"
"strings"
"time"
)
func resourceVcdNetwork() *schema.Resource {
@ -151,29 +149,33 @@ func resourceVcdNetworkCreate(d *schema.ResourceData, meta interface{}) error {
}
log.Printf("[INFO] NETWORK: %#v", newnetwork)
err = vcd_client.OrgVdc.CreateOrgVDCNetwork(newnetwork)
err = retryCall(4, func() error {
return vcd_client.OrgVdc.CreateOrgVDCNetwork(newnetwork)
})
if err != nil {
return fmt.Errorf("Error: %#v", err)
}
err = vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
network, err := vcd_client.OrgVdc.FindVDCNetwork(d.Get("name").(string))
if err != nil {
return fmt.Errorf("Error finding network: %#v", err)
}
if dhcp, ok := d.GetOk("dhcp_pool"); ok {
err := vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
err = retryCall(4, func() error {
task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcp.(*schema.Set).List())
if err != nil {
return fmt.Errorf("Error adding DHCP pool: %#v", err)
}
network, err := vcd_client.OrgVdc.FindVDCNetwork(d.Get("name").(string))
if err != nil {
return fmt.Errorf("Error finding network: %#v", err)
}
task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcp.(*schema.Set).List())
if err != nil {
return fmt.Errorf("Error adding DHCP pool: %#v", err)
}
err = task.WaitTaskCompletion()
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
@ -233,16 +235,12 @@ func resourceVcdNetworkDelete(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("Error finding network: %#v", err)
}
err = resource.Retry(3*time.Minute, func() error {
err = retryCall(4, func() error {
task, err := network.Delete()
if err != nil {
return fmt.Errorf("Error Deleting Network: %#v", err)
}
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
return nil
return task.WaitTaskCompletion()
})
if err != nil {
return err

View File

@ -4,8 +4,6 @@ import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"github.com/opencredo/vmware-govcd"
"regexp"
"time"
)
func resourceVcdSNAT() *schema.Resource {
@ -42,42 +40,27 @@ func resourceVcdSNATCreate(d *schema.ResourceData, meta interface{}) error {
// operation we must wait until we can aquire a lock on the client
vcd_client.Mutex.Lock()
defer vcd_client.Mutex.Unlock()
var task govcd.Task
// Creating a loop to offer further protection from the edge gateway erroring
// due to being busy eg another person is using another client so wouldn't be
// constrained by out lock. If the edge gateway reurns with a busy error, wait
// 3 seconds and then try again. Continue until a non-busy error or success
for {
err := vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
task, err = edgeGateway.AddNATMapping("SNAT", d.Get("internal_ip").(string),
d.Get("external_ip").(string),
"any")
if err != nil {
if v, _ := regexp.MatchString("is busy completing an operation.$", err.Error()); v {
time.Sleep(3 * time.Second)
continue
} else {
return fmt.Errorf("Error setting SNAT rules: %#v", err)
}
}
break
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
err := task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := edgeGateway.AddNATMapping("SNAT", d.Get("internal_ip").(string),
d.Get("external_ip").(string),
"any")
if err != nil {
return fmt.Errorf("Error setting SNAT rules: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
return err
}
d.SetId(d.Get("internal_ip").(string))
@ -120,42 +103,24 @@ func resourceVcdSNATDelete(d *schema.ResourceData, meta interface{}) error {
// operation we must wait until we can aquire a lock on the client
vcd_client.Mutex.Lock()
defer vcd_client.Mutex.Unlock()
var task govcd.Task
// Creating a loop to offer further protection from the edge gateway erroring
// due to being busy eg another person is using another client so wouldn't be
// constrained by out lock. If the edge gateway reurns with a busy error, wait
// 3 seconds and then try again. Continue until a non-busy error or success
for {
err := vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error refreshing vdc: %#v", err)
}
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
edgeGateway, err := vcd_client.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Unable to find edge gateway: %#v", err)
}
task, err = edgeGateway.RemoveNATMapping("SNAT", d.Get("internal_ip").(string),
err = retryCall(4, func() error {
task, err := edgeGateway.RemoveNATMapping("SNAT", d.Get("internal_ip").(string),
d.Get("external_ip").(string),
"")
if err != nil {
if v, _ := regexp.MatchString("is busy completing an operation.$", err.Error()); v {
time.Sleep(3 * time.Second)
continue
} else {
return fmt.Errorf("Error setting SNAT rules: %#v", err)
}
return fmt.Errorf("Error setting SNAT rules: %#v", err)
}
break
return task.WaitTaskCompletion()
})
if err != nil {
return err
}
err := task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
return nil
}

View File

@ -2,12 +2,10 @@ package vcd
import (
"fmt"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/opencredo/vmware-govcd"
types "github.com/opencredo/vmware-govcd/types/v56"
"log"
"time"
)
func resourceVcdVApp() *schema.Resource {
@ -135,11 +133,16 @@ func resourceVcdVAppCreate(d *schema.ResourceData, meta interface{}) error {
},
}
err = resource.Retry(4*time.Minute, func() error {
err = vcd_client.OrgVdc.InstantiateVAppTemplate(createvapp)
err = retryCall(4, func() error {
e := vcd_client.OrgVdc.InstantiateVAppTemplate(createvapp)
if err != nil {
return fmt.Errorf("Error: %#v", err)
if e != nil {
return fmt.Errorf("Error: %#v", e)
}
e = vcd_client.OrgVdc.Refresh()
if e != nil {
return fmt.Errorf("Error: %#v", e)
}
return nil
})
@ -147,72 +150,106 @@ func resourceVcdVAppCreate(d *schema.ResourceData, meta interface{}) error {
return err
}
err = vcd_client.OrgVdc.Refresh()
if err != nil {
return fmt.Errorf("Error: %#v", err)
}
// err = resource.Retry(4*time.Minute, func() error {
// err = vcd_client.OrgVdc.InstantiateVAppTemplate(createvapp)
//
// if err != nil {
// return fmt.Errorf("Error: %#v", err)
// }
// return nil
// })
// if err != nil {
// return err
// }
vapp, err := vcd_client.OrgVdc.FindVAppByName(d.Get("name").(string))
task, err := vapp.ChangeMemorySize(d.Get("memory").(int))
err = task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := vapp.ChangeMemorySize(d.Get("memory").(int))
if err != nil {
return fmt.Errorf("Error changing memory size: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error changing memory size: %#v", err)
return err
}
task, err = vapp.ChangeCPUcount(d.Get("cpus").(int))
err = task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := vapp.ChangeCPUcount(d.Get("cpus").(int))
if err != nil {
return fmt.Errorf("Error changing cpu count: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error changing cpu count: %#v", err)
return fmt.Errorf("Error completing task: %#v", err)
}
task, err = vapp.ChangeVMName(d.Get("name").(string))
if err != nil {
return fmt.Errorf("Error with vm name change: %#v", err)
}
err = retryCall(4, func() error {
task, err := vapp.ChangeVMName(d.Get("name").(string))
if err != nil {
return fmt.Errorf("Error with vm name change: %#v", err)
}
err = task.WaitTaskCompletion()
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error changing vmname: %#v", err)
}
task, err = vapp.ChangeNetworkConfig(d.Get("network_name").(string), d.Get("ip").(string))
if err != nil {
return fmt.Errorf("Error with Networking change: %#v", err)
}
err = task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := vapp.ChangeNetworkConfig(d.Get("network_name").(string), d.Get("ip").(string))
if err != nil {
return fmt.Errorf("Error with Networking change: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error changing network: %#v", err)
}
metadata := d.Get("metadata").(map[string]interface{})
for k, v := range metadata {
task, err = vapp.AddMetadata(k, v.(string))
if err != nil {
return fmt.Errorf("Error adding metadata: %#v", err)
}
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
err = retryCall(4, func() error {
metadata := d.Get("metadata").(map[string]interface{})
for k, v := range metadata {
task, err := vapp.AddMetadata(k, v.(string))
if err != nil {
return fmt.Errorf("Error adding metadata: %#v", err)
}
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
}
return nil
})
if err != nil {
return fmt.Errorf("Error adding metadata: %#v", err)
}
if initscript, ok := d.GetOk("initscript"); ok {
task, err = vapp.RunCustomizationScript(d.Get("name").(string), initscript.(string))
if err != nil {
return fmt.Errorf("Error with setting init script: %#v", err)
}
err = task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := vapp.RunCustomizationScript(d.Get("name").(string), initscript.(string))
if err != nil {
return fmt.Errorf("Error with setting init script: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
}
if d.Get("power_on").(bool) {
task, err = vapp.PowerOn()
if err != nil {
return fmt.Errorf("Error Powering Up: %#v", err)
}
err = task.WaitTaskCompletion()
err = retryCall(4, func() error {
task, err := vapp.PowerOn()
if err != nil {
return fmt.Errorf("Error Powering Up: %#v", err)
}
return task.WaitTaskCompletion()
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}

View File

@ -1,8 +1,10 @@
package vcd
import (
"github.com/hashicorp/terraform/helper/resource"
types "github.com/opencredo/vmware-govcd/types/v56"
"strconv"
"time"
)
func expandIpRange(configured []interface{}) (types.IPRanges, error) {
@ -101,3 +103,7 @@ func getPortString(port int) string {
portstring := strconv.Itoa(port)
return portstring
}
func retryCall(min int, f resource.RetryFunc) error {
return resource.Retry(time.Duration(min)*time.Minute, f)
}