Skip to content

Commit 83e6d8b

Browse files
committed
add Mutex so that we only do one Dyn operation at a time (extra thanks to @daveadams)
1 parent 76dcc66 commit 83e6d8b

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

builtin/providers/dyn/resource_dyn_record.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ package dyn
33
import (
44
"fmt"
55
"log"
6+
"sync"
67

78
"github.com/hashicorp/terraform/helper/schema"
89
"github.com/nesv/go-dynect/dynect"
910
)
1011

12+
var mutex = &sync.Mutex{}
13+
1114
func resourceDynRecord() *schema.Resource {
1215
return &schema.Resource{
1316
Create: resourceDynRecordCreate,
@@ -54,6 +57,8 @@ func resourceDynRecord() *schema.Resource {
5457
}
5558

5659
func resourceDynRecordCreate(d *schema.ResourceData, meta interface{}) error {
60+
mutex.Lock()
61+
5762
client := meta.(*dynect.ConvenientClient)
5863

5964
record := &dynect.Record{
@@ -68,26 +73,33 @@ func resourceDynRecordCreate(d *schema.ResourceData, meta interface{}) error {
6873
// create the record
6974
err := client.CreateRecord(record)
7075
if err != nil {
76+
mutex.Unlock()
7177
return fmt.Errorf("Failed to create Dyn record: %s", err)
7278
}
7379

7480
// publish the zone
7581
err = client.PublishZone(record.Zone)
7682
if err != nil {
83+
mutex.Unlock()
7784
return fmt.Errorf("Failed to publish Dyn zone: %s", err)
7885
}
7986

8087
// get the record ID
8188
err = client.GetRecordID(record)
8289
if err != nil {
90+
mutex.Unlock()
8391
return fmt.Errorf("%s", err)
8492
}
8593
d.SetId(record.ID)
8694

95+
mutex.Unlock()
8796
return resourceDynRecordRead(d, meta)
8897
}
8998

9099
func resourceDynRecordRead(d *schema.ResourceData, meta interface{}) error {
100+
mutex.Lock()
101+
defer mutex.Unlock()
102+
91103
client := meta.(*dynect.ConvenientClient)
92104

93105
record := &dynect.Record{
@@ -115,6 +127,8 @@ func resourceDynRecordRead(d *schema.ResourceData, meta interface{}) error {
115127
}
116128

117129
func resourceDynRecordUpdate(d *schema.ResourceData, meta interface{}) error {
130+
mutex.Lock()
131+
118132
client := meta.(*dynect.ConvenientClient)
119133

120134
record := &dynect.Record{
@@ -129,26 +143,33 @@ func resourceDynRecordUpdate(d *schema.ResourceData, meta interface{}) error {
129143
// update the record
130144
err := client.UpdateRecord(record)
131145
if err != nil {
146+
mutex.Unlock()
132147
return fmt.Errorf("Failed to update Dyn record: %s", err)
133148
}
134149

135150
// publish the zone
136151
err = client.PublishZone(record.Zone)
137152
if err != nil {
153+
mutex.Unlock()
138154
return fmt.Errorf("Failed to publish Dyn zone: %s", err)
139155
}
140156

141157
// get the record ID
142158
err = client.GetRecordID(record)
143159
if err != nil {
160+
mutex.Unlock()
144161
return fmt.Errorf("%s", err)
145162
}
146163
d.SetId(record.ID)
147164

165+
mutex.Unlock()
148166
return resourceDynRecordRead(d, meta)
149167
}
150168

151169
func resourceDynRecordDelete(d *schema.ResourceData, meta interface{}) error {
170+
mutex.Lock()
171+
defer mutex.Unlock()
172+
152173
client := meta.(*dynect.ConvenientClient)
153174

154175
record := &dynect.Record{

builtin/providers/dyn/resource_dyn_record_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,44 @@ func TestAccDynRecord_Updated(t *testing.T) {
7575
})
7676
}
7777

78+
func TestAccDynRecord_Multiple(t *testing.T) {
79+
var record dynect.Record
80+
zone := os.Getenv("DYN_ZONE")
81+
82+
resource.Test(t, resource.TestCase{
83+
PreCheck: func() { testAccPreCheck(t) },
84+
Providers: testAccProviders,
85+
CheckDestroy: testAccCheckDynRecordDestroy,
86+
Steps: []resource.TestStep{
87+
resource.TestStep{
88+
Config: fmt.Sprintf(testAccCheckDynRecordConfig_multiple, zone, zone, zone),
89+
Check: resource.ComposeTestCheckFunc(
90+
testAccCheckDynRecordExists("dyn_record.foobar1", &record),
91+
testAccCheckDynRecordAttributes(&record),
92+
resource.TestCheckResourceAttr(
93+
"dyn_record.foobar1", "name", "terraform1"),
94+
resource.TestCheckResourceAttr(
95+
"dyn_record.foobar1", "zone", zone),
96+
resource.TestCheckResourceAttr(
97+
"dyn_record.foobar1", "value", "192.168.0.10"),
98+
resource.TestCheckResourceAttr(
99+
"dyn_record.foobar2", "name", "terraform2"),
100+
resource.TestCheckResourceAttr(
101+
"dyn_record.foobar2", "zone", zone),
102+
resource.TestCheckResourceAttr(
103+
"dyn_record.foobar2", "value", "192.168.1.10"),
104+
resource.TestCheckResourceAttr(
105+
"dyn_record.foobar3", "name", "terraform3"),
106+
resource.TestCheckResourceAttr(
107+
"dyn_record.foobar3", "zone", zone),
108+
resource.TestCheckResourceAttr(
109+
"dyn_record.foobar3", "value", "192.168.2.10"),
110+
),
111+
},
112+
},
113+
})
114+
}
115+
78116
func testAccCheckDynRecordDestroy(s *terraform.State) error {
79117
client := testAccProvider.Meta().(*dynect.ConvenientClient)
80118

@@ -176,3 +214,26 @@ resource "dyn_record" "foobar" {
176214
type = "A"
177215
ttl = 3600
178216
}`
217+
218+
const testAccCheckDynRecordConfig_multiple = `
219+
resource "dyn_record" "foobar1" {
220+
zone = "%s"
221+
name = "terraform1"
222+
value = "192.168.0.10"
223+
type = "A"
224+
ttl = 3600
225+
}
226+
resource "dyn_record" "foobar2" {
227+
zone = "%s"
228+
name = "terraform2"
229+
value = "192.168.1.10"
230+
type = "A"
231+
ttl = 3600
232+
}
233+
resource "dyn_record" "foobar3" {
234+
zone = "%s"
235+
name = "terraform3"
236+
value = "192.168.2.10"
237+
type = "A"
238+
ttl = 3600
239+
}`

0 commit comments

Comments
 (0)