215 lines
4.6 KiB
Go
215 lines
4.6 KiB
Go
package ultradns
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/Ensighten/udnssdk"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
func newRRSetResource(d *schema.ResourceData) (rRSetResource, error) {
|
|
r := rRSetResource{}
|
|
|
|
// TODO: return error if required attributes aren't ok
|
|
|
|
if attr, ok := d.GetOk("name"); ok {
|
|
r.OwnerName = attr.(string)
|
|
}
|
|
|
|
if attr, ok := d.GetOk("type"); ok {
|
|
r.RRType = attr.(string)
|
|
}
|
|
|
|
if attr, ok := d.GetOk("zone"); ok {
|
|
r.Zone = attr.(string)
|
|
}
|
|
|
|
if attr, ok := d.GetOk("rdata"); ok {
|
|
rdata := attr.(*schema.Set).List()
|
|
r.RData = make([]string, len(rdata))
|
|
for i, j := range rdata {
|
|
r.RData[i] = j.(string)
|
|
}
|
|
}
|
|
|
|
if attr, ok := d.GetOk("ttl"); ok {
|
|
r.TTL, _ = strconv.Atoi(attr.(string))
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
func populateResourceDataFromRRSet(r udnssdk.RRSet, d *schema.ResourceData) error {
|
|
zone := d.Get("zone")
|
|
typ := d.Get("type")
|
|
// ttl
|
|
d.Set("ttl", r.TTL)
|
|
// rdata
|
|
rdata := r.RData
|
|
|
|
// UltraDNS API returns answers double-encoded like JSON, so we must decode. This is their bug.
|
|
if typ == "TXT" {
|
|
rdata = make([]string, len(r.RData))
|
|
for i := range r.RData {
|
|
var s string
|
|
err := json.Unmarshal([]byte(r.RData[i]), &s)
|
|
if err != nil {
|
|
log.Printf("[INFO] TXT answer parse error: %+v", err)
|
|
s = r.RData[i]
|
|
}
|
|
rdata[i] = s
|
|
|
|
}
|
|
}
|
|
|
|
err := d.Set("rdata", makeSetFromStrings(rdata))
|
|
if err != nil {
|
|
return fmt.Errorf("ultradns_record.rdata set failed: %#v", err)
|
|
}
|
|
// hostname
|
|
if r.OwnerName == "" {
|
|
d.Set("hostname", zone)
|
|
} else {
|
|
if strings.HasSuffix(r.OwnerName, ".") {
|
|
d.Set("hostname", r.OwnerName)
|
|
} else {
|
|
d.Set("hostname", fmt.Sprintf("%s.%s", r.OwnerName, zone))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resourceUltradnsRecord() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceUltraDNSRecordCreate,
|
|
Read: resourceUltraDNSRecordRead,
|
|
Update: resourceUltraDNSRecordUpdate,
|
|
Delete: resourceUltraDNSRecordDelete,
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
// Required
|
|
"zone": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"name": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"type": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"rdata": &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Set: schema.HashString,
|
|
Required: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
// Optional
|
|
"ttl": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Default: "3600",
|
|
},
|
|
// Computed
|
|
"hostname": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// CRUD Operations
|
|
|
|
func resourceUltraDNSRecordCreate(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*udnssdk.Client)
|
|
|
|
r, err := newRRSetResource(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("[INFO] ultradns_record create: %+v", r)
|
|
_, err = client.RRSets.Create(r.RRSetKey(), r.RRSet())
|
|
if err != nil {
|
|
return fmt.Errorf("create failed: %v", err)
|
|
}
|
|
|
|
d.SetId(r.ID())
|
|
log.Printf("[INFO] ultradns_record.id: %v", d.Id())
|
|
|
|
return resourceUltraDNSRecordRead(d, meta)
|
|
}
|
|
|
|
func resourceUltraDNSRecordRead(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*udnssdk.Client)
|
|
|
|
r, err := newRRSetResource(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rrsets, err := client.RRSets.Select(r.RRSetKey())
|
|
if err != nil {
|
|
uderr, ok := err.(*udnssdk.ErrorResponseList)
|
|
if ok {
|
|
for _, r := range uderr.Responses {
|
|
// 70002 means Records Not Found
|
|
if r.ErrorCode == 70002 {
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
return fmt.Errorf("not found: %v", err)
|
|
}
|
|
}
|
|
return fmt.Errorf("not found: %v", err)
|
|
}
|
|
rec := rrsets[0]
|
|
return populateResourceDataFromRRSet(rec, d)
|
|
}
|
|
|
|
func resourceUltraDNSRecordUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*udnssdk.Client)
|
|
|
|
r, err := newRRSetResource(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("[INFO] ultradns_record update: %+v", r)
|
|
_, err = client.RRSets.Update(r.RRSetKey(), r.RRSet())
|
|
if err != nil {
|
|
return fmt.Errorf("update failed: %v", err)
|
|
}
|
|
|
|
return resourceUltraDNSRecordRead(d, meta)
|
|
}
|
|
|
|
func resourceUltraDNSRecordDelete(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*udnssdk.Client)
|
|
|
|
r, err := newRRSetResource(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("[INFO] ultradns_record delete: %+v", r)
|
|
_, err = client.RRSets.Delete(r.RRSetKey())
|
|
if err != nil {
|
|
return fmt.Errorf("delete failed: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Conversion helper functions
|