provider/scaleway: work around parallel request limitation (#13045)

according to the official scaleway support, requests within the same session can
not be parallelized.

While I do not know for sure that this is a write-only limitation, I've
implemented it as a write-only limitation for now.

Previously requests like this would produce a 500 internal server error:

```
resource "scaleway_ip" "test_ip" {
  count = 2
}
```

now this limitation should be lifted, for all scaleway resources
This commit is contained in:
Raphael Randschau 2017-03-27 12:00:11 +02:00 committed by Paul Stack
parent 47c8fc456a
commit 403ea9f6d7
7 changed files with 59 additions and 5 deletions

View File

@ -1,11 +1,15 @@
package scaleway
import (
"sync"
"github.com/hashicorp/terraform/helper/mutexkv"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
var mu = sync.Mutex{}
// Provider returns a terraform.ResourceProvider.
func Provider() terraform.ResourceProvider {
return &schema.Provider{

View File

@ -2,7 +2,6 @@ package scaleway
import (
"log"
"sync"
"github.com/hashicorp/terraform/helper/schema"
"github.com/scaleway/scaleway-cli/pkg/api"
@ -31,13 +30,12 @@ func resourceScalewayIP() *schema.Resource {
}
}
var mu = sync.Mutex{}
func resourceScalewayIPCreate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
resp, err := scaleway.NewIP()
mu.Unlock()
if err != nil {
return err
}
@ -71,6 +69,10 @@ func resourceScalewayIPRead(d *schema.ResourceData, m interface{}) error {
func resourceScalewayIPUpdate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
if d.HasChange("server") {
if d.Get("server").(string) != "" {
log.Printf("[DEBUG] Attaching IP %q to server %q\n", d.Id(), d.Get("server").(string))
@ -88,6 +90,10 @@ func resourceScalewayIPUpdate(d *schema.ResourceData, m interface{}) error {
func resourceScalewayIPDelete(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
err := scaleway.DeleteIP(d.Id())
if err != nil {
return err

View File

@ -34,6 +34,9 @@ func resourceScalewaySecurityGroup() *schema.Resource {
func resourceScalewaySecurityGroupCreate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
req := api.ScalewayNewSecurityGroup{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
@ -94,6 +97,9 @@ func resourceScalewaySecurityGroupRead(d *schema.ResourceData, m interface{}) er
func resourceScalewaySecurityGroupUpdate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
var req = api.ScalewayUpdateSecurityGroup{
Organization: scaleway.Organization,
Name: d.Get("name").(string),
@ -112,6 +118,9 @@ func resourceScalewaySecurityGroupUpdate(d *schema.ResourceData, m interface{})
func resourceScalewaySecurityGroupDelete(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
err := scaleway.DeleteSecurityGroup(d.Id())
if err != nil {
if serr, ok := err.(api.ScalewayAPIError); ok {

View File

@ -67,6 +67,9 @@ func resourceScalewaySecurityGroupRule() *schema.Resource {
func resourceScalewaySecurityGroupRuleCreate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
req := api.ScalewayNewSecurityGroupRule{
Action: d.Get("action").(string),
Direction: d.Get("direction").(string),
@ -140,6 +143,9 @@ func resourceScalewaySecurityGroupRuleRead(d *schema.ResourceData, m interface{}
func resourceScalewaySecurityGroupRuleUpdate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
var req = api.ScalewayNewSecurityGroupRule{
Action: d.Get("action").(string),
Direction: d.Get("direction").(string),
@ -160,6 +166,9 @@ func resourceScalewaySecurityGroupRuleUpdate(d *schema.ResourceData, m interface
func resourceScalewaySecurityGroupRuleDelete(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
err := scaleway.DeleteSecurityGroupRule(d.Get("security_group").(string), d.Id())
if err != nil {
if serr, ok := err.(api.ScalewayAPIError); ok {

View File

@ -108,6 +108,9 @@ func resourceScalewayServer() *schema.Resource {
func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
image := d.Get("image").(string)
var server = api.ScalewayServerDefinition{
Name: d.Get("name").(string),
@ -217,8 +220,10 @@ func resourceScalewayServerRead(d *schema.ResourceData, m interface{}) error {
func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
var req api.ScalewayServerPatchDefinition
mu.Lock()
defer mu.Unlock()
var req api.ScalewayServerPatchDefinition
if d.HasChange("name") {
name := d.Get("name").(string)
req.Name = &name
@ -258,6 +263,9 @@ func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error {
func resourceScalewayServerDelete(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
s, err := scaleway.GetServer(d.Id())
if err != nil {
return err

View File

@ -45,6 +45,10 @@ func resourceScalewayVolume() *schema.Resource {
func resourceScalewayVolumeCreate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
size := uint64(d.Get("size_in_gb").(int)) * gb
req := api.ScalewayVolumeDefinition{
Name: d.Get("name").(string),
@ -88,6 +92,9 @@ func resourceScalewayVolumeRead(d *schema.ResourceData, m interface{}) error {
func resourceScalewayVolumeUpdate(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
var req api.ScalewayVolumePutDefinition
if d.HasChange("name") {
req.Name = String(d.Get("name").(string))
@ -104,6 +111,10 @@ func resourceScalewayVolumeUpdate(d *schema.ResourceData, m interface{}) error {
func resourceScalewayVolumeDelete(d *schema.ResourceData, m interface{}) error {
scaleway := m.(*Client).scaleway
mu.Lock()
defer mu.Unlock()
err := scaleway.DeleteVolume(d.Id())
if err != nil {
if serr, ok := err.(api.ScalewayAPIError); ok {

View File

@ -95,7 +95,9 @@ func resourceScalewayVolumeAttachmentCreate(d *schema.ResourceData, m interface{
var req = api.ScalewayServerPatchDefinition{
Volumes: &volumes,
}
mu.Lock()
err := scaleway.PatchServer(serverID, req)
mu.Unlock()
if err == nil {
return nil
@ -172,6 +174,9 @@ func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{
scaleway := m.(*Client).scaleway
scaleway.ClearCache()
mu.Lock()
defer mu.Unlock()
var startServerAgain = false
// guard against server shutdown/ startup race conditiond
@ -221,7 +226,9 @@ func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{
var req = api.ScalewayServerPatchDefinition{
Volumes: &volumes,
}
mu.Lock()
err := scaleway.PatchServer(serverID, req)
mu.Unlock()
if err == nil {
return nil