4
4
"encoding/json"
5
5
"fmt"
6
6
"log"
7
+ "strconv"
7
8
"strings"
8
9
9
10
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
@@ -61,9 +62,88 @@ func resourcePDNSRecord() *schema.Resource {
61
62
}
62
63
}
63
64
64
- func resourcePDNSRecordCreate (d * schema.ResourceData , meta interface {}) error {
65
- client := meta .(* Client )
65
+ func resourcePDNSRecordSOA () * schema.Resource {
66
+ return & schema.Resource {
67
+ Create : resourcePDNSRecordCreateSOA ,
68
+ Read : resourcePDNSRecordRead ,
69
+ Delete : resourcePDNSRecordDelete ,
70
+ Exists : resourcePDNSRecordExists ,
71
+ Importer : & schema.ResourceImporter {
72
+ State : resourcePDNSRecordImport ,
73
+ },
74
+
75
+ Schema : map [string ]* schema.Schema {
76
+ "zone" : {
77
+ Type : schema .TypeString ,
78
+ Required : true ,
79
+ ForceNew : true ,
80
+ },
81
+
82
+ "name" : {
83
+ Type : schema .TypeString ,
84
+ Required : true ,
85
+ ForceNew : true ,
86
+ },
87
+
88
+ "type" : {
89
+ Type : schema .TypeString ,
90
+ Required : true ,
91
+ ForceNew : true ,
92
+ },
93
+
94
+ "ttl" : {
95
+ Type : schema .TypeInt ,
96
+ Required : true ,
97
+ ForceNew : true ,
98
+ },
99
+
100
+ "mname" : {
101
+ Type : schema .TypeString ,
102
+ Optional : false ,
103
+ Required : true ,
104
+ ForceNew : true ,
105
+ },
106
+ "rname" : {
107
+ Type : schema .TypeString ,
108
+ Optional : false ,
109
+ Required : true ,
110
+ ForceNew : true ,
111
+ },
112
+ "serial" : {
113
+ Type : schema .TypeInt ,
114
+ Optional : false ,
115
+ Required : true ,
116
+ ForceNew : true ,
117
+ },
118
+ "refresh" : {
119
+ Type : schema .TypeInt ,
120
+ Optional : false ,
121
+ Required : true ,
122
+ ForceNew : true ,
123
+ },
124
+ "retry" : {
125
+ Type : schema .TypeInt ,
126
+ Optional : false ,
127
+ Required : true ,
128
+ ForceNew : true ,
129
+ },
130
+ "expire" : {
131
+ Type : schema .TypeInt ,
132
+ Optional : false ,
133
+ Required : true ,
134
+ ForceNew : true ,
135
+ },
136
+ "minimum" : {
137
+ Type : schema .TypeInt ,
138
+ Optional : false ,
139
+ Required : true ,
140
+ ForceNew : true ,
141
+ },
142
+ },
143
+ }
144
+ }
66
145
146
+ func resourcePDNSRecordCreatePrepare (d * schema.ResourceData , meta interface {}) (ResourceRecordSet , string , int ) {
67
147
rrSet := ResourceRecordSet {
68
148
Name : d .Get ("name" ).(string ),
69
149
Type : d .Get ("type" ).(string ),
@@ -72,53 +152,96 @@ func resourcePDNSRecordCreate(d *schema.ResourceData, meta interface{}) error {
72
152
73
153
zone := d .Get ("zone" ).(string )
74
154
ttl := d .Get ("ttl" ).(int )
155
+
156
+ return rrSet , zone , ttl
157
+ }
158
+
159
+ func resourcePDNSRecordCreate (d * schema.ResourceData , meta interface {}) error {
160
+ rrSet , zone , ttl := resourcePDNSRecordCreatePrepare (d , meta )
75
161
recs := d .Get ("records" ).(* schema.Set ).List ()
76
162
setPtr := false
77
163
78
- if v , ok := d .GetOk ("set_ptr" ); ok {
79
- setPtr = v .(bool )
80
- }
81
-
82
164
// begin: ValidateFunc
83
165
// https://www.terraform.io/docs/extend/schemas/schema-behaviors.html
84
166
// "ValidateFunc is not yet supported on lists or sets"
85
167
// when terraform will support ValidateFunc for non-primitives
86
168
// we can move this block there
169
+ if len (recs ) == 0 {
170
+ return fmt .Errorf ("'records' must not be empty" )
171
+ }
172
+
87
173
for _ , recs := range recs {
88
174
if len (strings .Trim (recs .(string ), " " )) == 0 {
89
175
log .Printf ("[WARN] One or more values in 'records' contain empty '' value(s)" )
90
176
}
91
177
}
92
- if ! (len (recs ) > 0 ) {
93
- return fmt .Errorf ("'records' must not be empty" )
94
- }
95
178
// end: ValidateFunc
96
179
97
- if len (recs ) > 0 {
98
- records := make ([]Record , 0 , len (recs ))
99
- for _ , recContent := range recs {
100
- records = append (records ,
101
- Record {Name : rrSet .Name ,
102
- Type : rrSet .Type ,
103
- TTL : ttl ,
104
- Content : recContent .(string ),
105
- SetPtr : setPtr })
106
- }
180
+ if v , ok := d .GetOk ("set_ptr" ); ok {
181
+ setPtr = v .(bool )
182
+ }
183
+
184
+ records := make ([]Record , 0 , len (recs ))
185
+ for _ , recContent := range recs {
186
+ records = append (records ,
187
+ Record {Name : rrSet .Name ,
188
+ Type : rrSet .Type ,
189
+ TTL : ttl ,
190
+ Content : recContent .(string ),
191
+ SetPtr : setPtr })
192
+ }
107
193
108
- rrSet .Records = records
194
+ rrSet .Records = records
109
195
110
- log .Printf ("[DEBUG] Creating PowerDNS Record: %#v" , rrSet )
196
+ return (resourcePDNSRecordCreateFinish (d , meta , zone , rrSet ))
197
+ }
111
198
112
- recID , err := client .ReplaceRecordSet (zone , rrSet )
199
+ func resourcePDNSRecordCreateSOA (d * schema.ResourceData , meta interface {}) error {
200
+ rrSet , zone , ttl := resourcePDNSRecordCreatePrepare (d , meta )
201
+ client := meta .(* Client )
202
+
203
+ log .Printf ("[DEBUG] Searching existing SOA record at %s => %s" , zone , d .Get ("name" ).(string ))
204
+ soa_records , err := client .ListRecordsInRRSet (zone , d .Get ("name" ).(string ), "SOA" )
205
+ if err != nil {
206
+ return fmt .Errorf ("Failed to fetch old SOA record: %s" , err )
207
+ }
208
+ var serial int
209
+ if len (soa_records ) > 0 {
210
+ serial , err = strconv .Atoi (strings .Fields (soa_records [0 ].Content )[2 ])
113
211
if err != nil {
114
- return fmt .Errorf ("Failed to create PowerDNS Record : %s" , err )
212
+ return fmt .Errorf ("Failed to parse old serial value in SOA record : %s" , err )
115
213
}
214
+ } else {
215
+ serial = d .Get ("serial" ).(int )
216
+ }
217
+ log .Printf ("[DEBUG] Set serial number to %d" , serial )
218
+
219
+ records := make ([]Record , 0 , 1 )
220
+ records = append (records ,
221
+ Record {Name : rrSet .Name ,
222
+ Type : rrSet .Type ,
223
+ TTL : ttl ,
224
+ Content : fmt .Sprintf ("%s %s %d %d %d %d %d" , d .Get ("mname" ), d .Get ("rname" ), serial , d .Get ("refresh" ), d .Get ("retry" ), d .Get ("expire" ), d .Get ("minimum" )),
225
+ SetPtr : false })
226
+
227
+ rrSet .Records = records
228
+
229
+ return (resourcePDNSRecordCreateFinish (d , meta , zone , rrSet ))
230
+ }
231
+
232
+ func resourcePDNSRecordCreateFinish (d * schema.ResourceData , meta interface {}, zone string , rrSet ResourceRecordSet ) error {
233
+ client := meta .(* Client )
116
234
117
- d .SetId (recID )
118
- log .Printf ("[INFO] Created PowerDNS Record with ID: %s" , d .Id ())
235
+ log .Printf ("[DEBUG] Creating PowerDNS Record: %#v" , rrSet )
119
236
237
+ recID , err := client .ReplaceRecordSet (zone , rrSet )
238
+ if err != nil {
239
+ return fmt .Errorf ("Failed to create PowerDNS Record: %s" , err )
120
240
}
121
241
242
+ d .SetId (recID )
243
+ log .Printf ("[INFO] Created PowerDNS Record with ID: %s" , d .Id ())
244
+
122
245
return resourcePDNSRecordRead (d , meta )
123
246
}
124
247
@@ -132,12 +255,48 @@ func resourcePDNSRecordRead(d *schema.ResourceData, meta interface{}) error {
132
255
}
133
256
134
257
recs := make ([]string , 0 , len (records ))
135
- for _ , r := range records {
136
- recs = append (recs , r .Content )
258
+ if d .Get ("type" ) == "SOA" {
259
+ rsplit := strings .Fields (records [0 ].Content )
260
+ d .Set ("mname" , rsplit [0 ])
261
+ d .Set ("rname" , rsplit [1 ])
262
+
263
+ serial , err := strconv .Atoi (rsplit [2 ])
264
+ if err != nil {
265
+ return fmt .Errorf ("Failed to parse serial value in SOA record: %s" , err )
266
+ }
267
+ d .Set ("serial" , serial )
268
+
269
+ refresh , err := strconv .Atoi (rsplit [3 ])
270
+ if err != nil {
271
+ return fmt .Errorf ("Failed to parse refresh value in SOA record: %s" , err )
272
+ }
273
+ d .Set ("refresh" , refresh )
274
+
275
+ retry , err := strconv .Atoi (rsplit [4 ])
276
+ if err != nil {
277
+ return fmt .Errorf ("Failed to parse retry value in SOA record: %s" , err )
278
+ }
279
+ d .Set ("retry" , retry )
280
+
281
+ expire , err := strconv .Atoi (rsplit [5 ])
282
+ if err != nil {
283
+ return fmt .Errorf ("Failed to parse expire value in SOA record: %s" , err )
284
+ }
285
+ d .Set ("expire" , expire )
286
+
287
+ minimum , err := strconv .Atoi (rsplit [6 ])
288
+ if err != nil {
289
+ return fmt .Errorf ("Failed to parse minimum value in SOA record: %s" , err )
290
+ }
291
+ d .Set ("minimum" , minimum )
292
+ } else {
293
+ for _ , r := range records {
294
+ recs = append (recs , r .Content )
295
+ }
296
+ d .Set ("records" , recs )
137
297
}
138
- d .Set ("records" , recs )
139
298
140
- if len (records ) > 0 {
299
+ if len (records ) > 0 || d . Get ( "Type" ) == "SOA" {
141
300
d .Set ("ttl" , records [0 ].TTL )
142
301
}
143
302
0 commit comments