terraform/builtin/providers/dns/resource_dns_ptr_record.go

220 lines
5.1 KiB
Go

package dns
import (
"fmt"
"time"
"github.com/hashicorp/terraform/helper/schema"
"github.com/miekg/dns"
)
func resourceDnsPtrRecord() *schema.Resource {
return &schema.Resource{
Create: resourceDnsPtrRecordCreate,
Read: resourceDnsPtrRecordRead,
Update: resourceDnsPtrRecordUpdate,
Delete: resourceDnsPtrRecordDelete,
Schema: map[string]*schema.Schema{
"zone": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"ptr": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"ttl": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 3600,
},
},
}
}
func resourceDnsPtrRecordCreate(d *schema.ResourceData, meta interface{}) error {
rec_name := d.Get("name").(string)
rec_zone := d.Get("zone").(string)
rec_ptr := d.Get("ptr").(string)
if rec_zone != dns.Fqdn(rec_zone) {
return fmt.Errorf("Error creating DNS record: \"zone\" should be an FQDN")
}
if rec_ptr != dns.Fqdn(rec_ptr) {
return fmt.Errorf("Error creating DNS record: \"ptr\" should be an FQDN")
}
rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
d.SetId(rec_fqdn)
return resourceDnsPtrRecordUpdate(d, meta)
}
func resourceDnsPtrRecordRead(d *schema.ResourceData, meta interface{}) error {
if meta != nil {
rec_name := d.Get("name").(string)
rec_zone := d.Get("zone").(string)
rec_ptr := d.Get("ptr").(string)
if rec_zone != dns.Fqdn(rec_zone) {
return fmt.Errorf("Error reading DNS record: \"zone\" should be an FQDN")
}
if rec_ptr != dns.Fqdn(rec_ptr) {
return fmt.Errorf("Error reading DNS record: \"ptr\" should be an FQDN")
}
rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
c := meta.(*DNSClient).c
srv_addr := meta.(*DNSClient).srv_addr
msg := new(dns.Msg)
msg.SetQuestion(rec_fqdn, dns.TypePTR)
r, _, err := c.Exchange(msg, srv_addr)
if err != nil {
return fmt.Errorf("Error querying DNS record: %s", err)
}
if r.Rcode != dns.RcodeSuccess {
return fmt.Errorf("Error querying DNS record: %v", r.Rcode)
}
if len(r.Answer) > 1 {
return fmt.Errorf("Error querying DNS record: multiple responses received")
}
record := r.Answer[0]
ptr, err := getPtrVal(record)
if err != nil {
return fmt.Errorf("Error querying DNS record: %s", err)
}
if rec_ptr != ptr {
d.SetId("")
return fmt.Errorf("DNS record differs")
}
return nil
} else {
return fmt.Errorf("update server is not set")
}
}
func resourceDnsPtrRecordUpdate(d *schema.ResourceData, meta interface{}) error {
if meta != nil {
rec_name := d.Get("name").(string)
rec_zone := d.Get("zone").(string)
rec_ptr := d.Get("ptr").(string)
ttl := d.Get("ttl").(int)
if rec_zone != dns.Fqdn(rec_zone) {
return fmt.Errorf("Error updating DNS record: \"zone\" should be an FQDN")
}
if rec_ptr != dns.Fqdn(rec_ptr) {
return fmt.Errorf("Error updating DNS record: \"ptr\" should be an FQDN")
}
rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
c := meta.(*DNSClient).c
srv_addr := meta.(*DNSClient).srv_addr
keyname := meta.(*DNSClient).keyname
keyalgo := meta.(*DNSClient).keyalgo
msg := new(dns.Msg)
msg.SetUpdate(rec_zone)
if d.HasChange("ptr") {
o, n := d.GetChange("ptr")
if o != "" {
rr_remove, _ := dns.NewRR(fmt.Sprintf("%s %d PTR %s", rec_fqdn, ttl, o))
msg.Remove([]dns.RR{rr_remove})
}
if n != "" {
rr_insert, _ := dns.NewRR(fmt.Sprintf("%s %d PTR %s", rec_fqdn, ttl, n))
msg.Insert([]dns.RR{rr_insert})
}
if keyname != "" {
msg.SetTsig(keyname, keyalgo, 300, time.Now().Unix())
}
r, _, err := c.Exchange(msg, srv_addr)
if err != nil {
d.SetId("")
return fmt.Errorf("Error updating DNS record: %s", err)
}
if r.Rcode != dns.RcodeSuccess {
d.SetId("")
return fmt.Errorf("Error updating DNS record: %v", r.Rcode)
}
ptr := n
d.Set("ptr", ptr)
}
return resourceDnsPtrRecordRead(d, meta)
} else {
return fmt.Errorf("update server is not set")
}
}
func resourceDnsPtrRecordDelete(d *schema.ResourceData, meta interface{}) error {
if meta != nil {
rec_name := d.Get("name").(string)
rec_zone := d.Get("zone").(string)
if rec_zone != dns.Fqdn(rec_zone) {
return fmt.Errorf("Error updating DNS record: \"zone\" should be an FQDN")
}
rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
c := meta.(*DNSClient).c
srv_addr := meta.(*DNSClient).srv_addr
keyname := meta.(*DNSClient).keyname
keyalgo := meta.(*DNSClient).keyalgo
msg := new(dns.Msg)
msg.SetUpdate(rec_zone)
rr_remove, _ := dns.NewRR(fmt.Sprintf("%s 0 PTR", rec_fqdn))
msg.RemoveRRset([]dns.RR{rr_remove})
if keyname != "" {
msg.SetTsig(keyname, keyalgo, 300, time.Now().Unix())
}
r, _, err := c.Exchange(msg, srv_addr)
if err != nil {
return fmt.Errorf("Error deleting DNS record: %s", err)
}
if r.Rcode != dns.RcodeSuccess {
return fmt.Errorf("Error deleting DNS record: %v", r.Rcode)
}
return nil
} else {
return fmt.Errorf("update server is not set")
}
}