44 "encoding/json"
55 "fmt"
66 "log"
7+ "strconv"
78 "strings"
89
910 "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
@@ -61,9 +62,88 @@ func resourcePDNSRecord() *schema.Resource {
6162 }
6263}
6364
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+ }
66145
146+ func resourcePDNSRecordCreatePrepare (d * schema.ResourceData , meta interface {}) (ResourceRecordSet , string , int ) {
67147 rrSet := ResourceRecordSet {
68148 Name : d .Get ("name" ).(string ),
69149 Type : d .Get ("type" ).(string ),
@@ -72,53 +152,96 @@ func resourcePDNSRecordCreate(d *schema.ResourceData, meta interface{}) error {
72152
73153 zone := d .Get ("zone" ).(string )
74154 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 )
75161 recs := d .Get ("records" ).(* schema.Set ).List ()
76162 setPtr := false
77163
78- if v , ok := d .GetOk ("set_ptr" ); ok {
79- setPtr = v .(bool )
80- }
81-
82164 // begin: ValidateFunc
83165 // https://www.terraform.io/docs/extend/schemas/schema-behaviors.html
84166 // "ValidateFunc is not yet supported on lists or sets"
85167 // when terraform will support ValidateFunc for non-primitives
86168 // we can move this block there
169+ if len (recs ) == 0 {
170+ return fmt .Errorf ("'records' must not be empty" )
171+ }
172+
87173 for _ , recs := range recs {
88174 if len (strings .Trim (recs .(string ), " " )) == 0 {
89175 log .Printf ("[WARN] One or more values in 'records' contain empty '' value(s)" )
90176 }
91177 }
92- if ! (len (recs ) > 0 ) {
93- return fmt .Errorf ("'records' must not be empty" )
94- }
95178 // end: ValidateFunc
96179
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+ }
107193
108- rrSet .Records = records
194+ rrSet .Records = records
109195
110- log .Printf ("[DEBUG] Creating PowerDNS Record: %#v" , rrSet )
196+ return (resourcePDNSRecordCreateFinish (d , meta , zone , rrSet ))
197+ }
111198
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 ])
113211 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 )
115213 }
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 )
116234
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 )
119236
237+ recID , err := client .ReplaceRecordSet (zone , rrSet )
238+ if err != nil {
239+ return fmt .Errorf ("Failed to create PowerDNS Record: %s" , err )
120240 }
121241
242+ d .SetId (recID )
243+ log .Printf ("[INFO] Created PowerDNS Record with ID: %s" , d .Id ())
244+
122245 return resourcePDNSRecordRead (d , meta )
123246}
124247
@@ -132,12 +255,48 @@ func resourcePDNSRecordRead(d *schema.ResourceData, meta interface{}) error {
132255 }
133256
134257 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 )
137297 }
138- d .Set ("records" , recs )
139298
140- if len (records ) > 0 {
299+ if len (records ) > 0 || d . Get ( "Type" ) == "SOA" {
141300 d .Set ("ttl" , records [0 ].TTL )
142301 }
143302
0 commit comments