@@ -4,9 +4,12 @@ import (
44 "fmt"
55 "log"
66 "strings"
7+ "time"
78
9+ "golang.org/x/net/context"
10+
11+ "github.com/crackcomm/cloudflare"
812 "github.com/hashicorp/terraform/helper/schema"
9- "github.com/pearkes/cloudflare"
1013)
1114
1215func resourceCloudFlareRecord () * schema.Resource {
@@ -44,14 +47,25 @@ func resourceCloudFlareRecord() *schema.Resource {
4447 },
4548
4649 "ttl" : & schema.Schema {
47- Type : schema .TypeString ,
50+ Type : schema .TypeInt ,
4851 Optional : true ,
4952 Computed : true ,
5053 },
5154
5255 "priority" : & schema.Schema {
53- Type : schema .TypeString ,
56+ Type : schema .TypeInt ,
57+ Optional : true ,
58+ },
59+
60+ "proxied" : & schema.Schema {
61+ Default : false ,
5462 Optional : true ,
63+ Type : schema .TypeBool ,
64+ },
65+
66+ "zone_id" : & schema.Schema {
67+ Type : schema .TypeString ,
68+ Computed : true ,
5569 },
5670 },
5771 }
@@ -60,81 +74,111 @@ func resourceCloudFlareRecord() *schema.Resource {
6074func resourceCloudFlareRecordCreate (d * schema.ResourceData , meta interface {}) error {
6175 client := meta .(* cloudflare.Client )
6276
63- // Create the new record
64- newRecord := & cloudflare.CreateRecord {
65- Name : d .Get ("name" ).(string ),
66- Type : d .Get ("type" ).(string ),
67- Content : d .Get ("value" ).(string ),
77+ newRecord := & cloudflare.Record {
78+ Content : d .Get ("value" ).(string ),
79+ Name : d .Get ("name" ).(string ),
80+ Proxied : d .Get ("proxied" ).(bool ),
81+ Type : d .Get ("type" ).(string ),
82+ ZoneName : d .Get ("domain" ).(string ),
83+ }
84+
85+ if priority , ok := d .GetOk ("priority" ); ok {
86+ newRecord .Priority = priority .(int )
6887 }
6988
7089 if ttl , ok := d .GetOk ("ttl" ); ok {
71- newRecord .Ttl = ttl .(string )
90+ newRecord .TTL = ttl .(int )
7291 }
7392
74- if priority , ok := d .GetOk ("priority" ); ok {
75- newRecord .Priority = priority .(string )
93+ zone , err := retrieveZone (client , newRecord .ZoneName )
94+ if err != nil {
95+ return err
7696 }
7797
98+ d .Set ("zone_id" , zone .ID )
99+ newRecord .ZoneID = zone .ID
100+
78101 log .Printf ("[DEBUG] CloudFlare Record create configuration: %#v" , newRecord )
79102
80- rec , err := client . CreateRecord ( d . Get ( "domain" ).( string ), newRecord )
103+ ctx , _ := context . WithDeadline ( context . Background (), time . Now (). Add ( time . Second * 30 ) )
81104
105+ err = client .Records .Create (ctx , newRecord )
82106 if err != nil {
83- return fmt .Errorf ("Failed to create CloudFlare Record : %s" , err )
107+ return fmt .Errorf ("Failed to create record : %s" , err )
84108 }
85109
86- d .SetId (rec .Id )
110+ d .SetId (newRecord .ID )
111+
87112 log .Printf ("[INFO] CloudFlare Record ID: %s" , d .Id ())
88113
89114 return resourceCloudFlareRecordRead (d , meta )
90115}
91116
92117func resourceCloudFlareRecordRead (d * schema.ResourceData , meta interface {}) error {
93- client := meta .(* cloudflare.Client )
118+ var (
119+ client = meta .(* cloudflare.Client )
120+ domain = d .Get ("domain" ).(string )
121+ rName = strings .Join ([]string {d .Get ("name" ).(string ), domain }, "." )
122+ )
94123
95- rec , err := client . RetrieveRecord ( d . Get ( "domain" ).( string ), d . Id () )
124+ zone , err := retrieveZone ( client , domain )
96125 if err != nil {
97- if strings .Contains (err .Error (), "not found" ) {
98- d .SetId ("" )
99- return nil
100- }
126+ return err
127+ }
101128
102- return fmt . Errorf (
103- "Couldn't find CloudFlare Record ID (%s) for domain (%s): %s" ,
104- d . Id (), d . Get ( "domain" ).( string ), err )
129+ record , err := retrieveRecord ( client , zone , rName )
130+ if err != nil {
131+ return err
105132 }
106133
107- d .Set ("name" , rec .Name )
108- d .Set ("hostname" , rec .FullName )
109- d .Set ("type" , rec .Type )
110- d .Set ("value" , rec .Value )
111- d .Set ("ttl" , rec .Ttl )
112- d .Set ("priority" , rec .Priority )
134+ d .SetId (record .ID )
135+ d .Set ("hostname" , record .Name )
136+ d .Set ("type" , record .Type )
137+ d .Set ("value" , record .Content )
138+ d .Set ("ttl" , record .TTL )
139+ d .Set ("priority" , record .Priority )
140+ d .Set ("proxied" , record .Proxied )
141+ d .Set ("zone_id" , zone .ID )
113142
114143 return nil
115144}
116145
117146func resourceCloudFlareRecordUpdate (d * schema.ResourceData , meta interface {}) error {
118147 client := meta .(* cloudflare.Client )
119148
120- // CloudFlare requires we send all values for an update request
121- updateRecord := & cloudflare.UpdateRecord {
122- Name : d .Get ("name" ).(string ),
123- Type : d .Get ("type" ).(string ),
124- Content : d .Get ("value" ).(string ),
149+ updateRecord := & cloudflare.Record {
150+ Content : d .Get ("value" ).(string ),
151+ ID : d .Id (),
152+ Name : d .Get ("name" ).(string ),
153+ Proxied : false ,
154+ Type : d .Get ("type" ).(string ),
155+ ZoneName : d .Get ("domain" ).(string ),
156+ }
157+
158+ if priority , ok := d .GetOk ("priority" ); ok {
159+ updateRecord .Priority = priority .(int )
160+ }
161+
162+ if proxied , ok := d .GetOk ("proxied" ); ok {
163+ updateRecord .Proxied = proxied .(bool )
125164 }
126165
127166 if ttl , ok := d .GetOk ("ttl" ); ok {
128- updateRecord .Ttl = ttl .(string )
167+ updateRecord .TTL = ttl .(int )
129168 }
130169
131- if priority , ok := d .GetOk ("priority" ); ok {
132- updateRecord .Priority = priority .(string )
170+ zone , err := retrieveZone (client , updateRecord .ZoneName )
171+ if err != nil {
172+ return err
133173 }
134174
175+ updateRecord .ZoneID = zone .ID
176+
135177 log .Printf ("[DEBUG] CloudFlare Record update configuration: %#v" , updateRecord )
136178
137- err := client .UpdateRecord (d .Get ("domain" ).(string ), d .Id (), updateRecord )
179+ ctx , _ := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
180+
181+ err = client .Records .Patch (ctx , updateRecord )
138182 if err != nil {
139183 return fmt .Errorf ("Failed to update CloudFlare Record: %s" , err )
140184 }
@@ -143,15 +187,79 @@ func resourceCloudFlareRecordUpdate(d *schema.ResourceData, meta interface{}) er
143187}
144188
145189func resourceCloudFlareRecordDelete (d * schema.ResourceData , meta interface {}) error {
146- client := meta .(* cloudflare.Client )
190+ var (
191+ client = meta .(* cloudflare.Client )
192+ domain = d .Get ("domain" ).(string )
193+ rName = strings .Join ([]string {d .Get ("name" ).(string ), domain }, "." )
194+ )
195+
196+ zone , err := retrieveZone (client , domain )
197+ if err != nil {
198+ return err
199+ }
147200
148- log .Printf ("[INFO] Deleting CloudFlare Record: %s, %s" , d .Get ("domain" ).(string ), d .Id ())
201+ record , err := retrieveRecord (client , zone , rName )
202+ if err != nil {
203+ return err
204+ }
149205
150- err := client . DestroyRecord ( d . Get ( " domain" ).( string ) , d .Id ())
206+ log . Printf ( "[INFO] Deleting CloudFlare Record: %s, %s" , domain , d .Id ())
151207
208+ ctx , _ := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
209+
210+ err = client .Records .Delete (ctx , zone .ID , record .ID )
152211 if err != nil {
153212 return fmt .Errorf ("Error deleting CloudFlare Record: %s" , err )
154213 }
155214
156215 return nil
157216}
217+
218+ func retrieveRecord (
219+ client * cloudflare.Client ,
220+ zone * cloudflare.Zone ,
221+ name string ,
222+ ) (* cloudflare.Record , error ) {
223+ ctx , _ := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
224+
225+ rs , err := client .Records .List (ctx , zone .ID )
226+ if err != nil {
227+ return nil , fmt .Errorf ("Unable to retrieve records for (%s): %s" , zone .Name , err )
228+ }
229+
230+ var record * cloudflare.Record
231+
232+ for _ , r := range rs {
233+ if r .Name == name {
234+ record = r
235+ }
236+ }
237+ if record == nil {
238+ return nil , fmt .Errorf ("Unable to find Cloudflare record %s" , name )
239+ }
240+
241+ return record , nil
242+ }
243+
244+ func retrieveZone (client * cloudflare.Client , domain string ) (* cloudflare.Zone , error ) {
245+ ctx , _ := context .WithDeadline (context .Background (), time .Now ().Add (time .Second * 30 ))
246+
247+ zs , err := client .Zones .List (ctx )
248+ if err != nil {
249+ return nil , fmt .Errorf ("Failed to fetch zone for %s: %s" , domain , err )
250+ }
251+
252+ var zone * cloudflare.Zone
253+
254+ for _ , z := range zs {
255+ if z .Name == domain {
256+ zone = z
257+ }
258+ }
259+
260+ if zone == nil {
261+ return nil , fmt .Errorf ("Failed to find zone for: %s" , domain )
262+ }
263+
264+ return zone , nil
265+ }
0 commit comments