github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/dns/resource_dns_cname_record.go (about)

     1  package dns
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  	"github.com/miekg/dns"
     9  )
    10  
    11  func resourceDnsCnameRecord() *schema.Resource {
    12  	return &schema.Resource{
    13  		Create: resourceDnsCnameRecordCreate,
    14  		Read:   resourceDnsCnameRecordRead,
    15  		Update: resourceDnsCnameRecordUpdate,
    16  		Delete: resourceDnsCnameRecordDelete,
    17  
    18  		Schema: map[string]*schema.Schema{
    19  			"zone": &schema.Schema{
    20  				Type:     schema.TypeString,
    21  				Required: true,
    22  				ForceNew: true,
    23  			},
    24  			"name": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  			"cname": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Required: true,
    32  			},
    33  			"ttl": &schema.Schema{
    34  				Type:     schema.TypeInt,
    35  				Optional: true,
    36  				ForceNew: true,
    37  				Default:  3600,
    38  			},
    39  		},
    40  	}
    41  }
    42  
    43  func resourceDnsCnameRecordCreate(d *schema.ResourceData, meta interface{}) error {
    44  
    45  	rec_name := d.Get("name").(string)
    46  	rec_zone := d.Get("zone").(string)
    47  	rec_cname := d.Get("cname").(string)
    48  
    49  	if rec_zone != dns.Fqdn(rec_zone) {
    50  		return fmt.Errorf("Error creating DNS record: \"zone\" should be an FQDN")
    51  	}
    52  
    53  	if rec_cname != dns.Fqdn(rec_cname) {
    54  		return fmt.Errorf("Error creating DNS record: \"cname\" should be an FQDN")
    55  	}
    56  
    57  	rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
    58  
    59  	d.SetId(rec_fqdn)
    60  
    61  	return resourceDnsCnameRecordUpdate(d, meta)
    62  }
    63  
    64  func resourceDnsCnameRecordRead(d *schema.ResourceData, meta interface{}) error {
    65  
    66  	if meta != nil {
    67  
    68  		rec_name := d.Get("name").(string)
    69  		rec_zone := d.Get("zone").(string)
    70  		rec_cname := d.Get("cname").(string)
    71  
    72  		if rec_zone != dns.Fqdn(rec_zone) {
    73  			return fmt.Errorf("Error reading DNS record: \"zone\" should be an FQDN")
    74  		}
    75  
    76  		if rec_cname != dns.Fqdn(rec_cname) {
    77  			return fmt.Errorf("Error reading DNS record: \"cname\" should be an FQDN")
    78  		}
    79  
    80  		rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
    81  
    82  		c := meta.(*DNSClient).c
    83  		srv_addr := meta.(*DNSClient).srv_addr
    84  
    85  		msg := new(dns.Msg)
    86  		msg.SetQuestion(rec_fqdn, dns.TypeCNAME)
    87  
    88  		r, _, err := c.Exchange(msg, srv_addr)
    89  		if err != nil {
    90  			return fmt.Errorf("Error querying DNS record: %s", err)
    91  		}
    92  		if r.Rcode != dns.RcodeSuccess {
    93  			return fmt.Errorf("Error querying DNS record: %v", r.Rcode)
    94  		}
    95  
    96  		if len(r.Answer) > 1 {
    97  			return fmt.Errorf("Error querying DNS record: multiple responses received")
    98  		}
    99  		record := r.Answer[0]
   100  		cname, err := getCnameVal(record)
   101  		if err != nil {
   102  			return fmt.Errorf("Error querying DNS record: %s", err)
   103  		}
   104  		if rec_cname != cname {
   105  			d.SetId("")
   106  			return fmt.Errorf("DNS record differs")
   107  		}
   108  		return nil
   109  	} else {
   110  		return fmt.Errorf("update server is not set")
   111  	}
   112  }
   113  
   114  func resourceDnsCnameRecordUpdate(d *schema.ResourceData, meta interface{}) error {
   115  
   116  	if meta != nil {
   117  
   118  		rec_name := d.Get("name").(string)
   119  		rec_zone := d.Get("zone").(string)
   120  		rec_cname := d.Get("cname").(string)
   121  		ttl := d.Get("ttl").(int)
   122  
   123  		if rec_zone != dns.Fqdn(rec_zone) {
   124  			return fmt.Errorf("Error updating DNS record: \"zone\" should be an FQDN")
   125  		}
   126  
   127  		if rec_cname != dns.Fqdn(rec_cname) {
   128  			return fmt.Errorf("Error updating DNS record: \"cname\" should be an FQDN")
   129  		}
   130  
   131  		rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
   132  
   133  		c := meta.(*DNSClient).c
   134  		srv_addr := meta.(*DNSClient).srv_addr
   135  		keyname := meta.(*DNSClient).keyname
   136  		keyalgo := meta.(*DNSClient).keyalgo
   137  
   138  		msg := new(dns.Msg)
   139  
   140  		msg.SetUpdate(rec_zone)
   141  
   142  		if d.HasChange("cname") {
   143  			o, n := d.GetChange("cname")
   144  
   145  			if o != "" {
   146  				rr_remove, _ := dns.NewRR(fmt.Sprintf("%s %d CNAME %s", rec_fqdn, ttl, o))
   147  				msg.Remove([]dns.RR{rr_remove})
   148  			}
   149  			if n != "" {
   150  				rr_insert, _ := dns.NewRR(fmt.Sprintf("%s %d CNAME %s", rec_fqdn, ttl, n))
   151  				msg.Insert([]dns.RR{rr_insert})
   152  			}
   153  
   154  			if keyname != "" {
   155  				msg.SetTsig(keyname, keyalgo, 300, time.Now().Unix())
   156  			}
   157  
   158  			r, _, err := c.Exchange(msg, srv_addr)
   159  			if err != nil {
   160  				d.SetId("")
   161  				return fmt.Errorf("Error updating DNS record: %s", err)
   162  			}
   163  			if r.Rcode != dns.RcodeSuccess {
   164  				d.SetId("")
   165  				return fmt.Errorf("Error updating DNS record: %v", r.Rcode)
   166  			}
   167  
   168  			cname := n
   169  			d.Set("cname", cname)
   170  		}
   171  
   172  		return resourceDnsCnameRecordRead(d, meta)
   173  	} else {
   174  		return fmt.Errorf("update server is not set")
   175  	}
   176  }
   177  
   178  func resourceDnsCnameRecordDelete(d *schema.ResourceData, meta interface{}) error {
   179  
   180  	if meta != nil {
   181  
   182  		rec_name := d.Get("name").(string)
   183  		rec_zone := d.Get("zone").(string)
   184  
   185  		if rec_zone != dns.Fqdn(rec_zone) {
   186  			return fmt.Errorf("Error updating DNS record: \"zone\" should be an FQDN")
   187  		}
   188  
   189  		rec_fqdn := fmt.Sprintf("%s.%s", rec_name, rec_zone)
   190  
   191  		c := meta.(*DNSClient).c
   192  		srv_addr := meta.(*DNSClient).srv_addr
   193  		keyname := meta.(*DNSClient).keyname
   194  		keyalgo := meta.(*DNSClient).keyalgo
   195  
   196  		msg := new(dns.Msg)
   197  
   198  		msg.SetUpdate(rec_zone)
   199  
   200  		rr_remove, _ := dns.NewRR(fmt.Sprintf("%s 0 CNAME", rec_fqdn))
   201  		msg.RemoveRRset([]dns.RR{rr_remove})
   202  
   203  		if keyname != "" {
   204  			msg.SetTsig(keyname, keyalgo, 300, time.Now().Unix())
   205  		}
   206  
   207  		r, _, err := c.Exchange(msg, srv_addr)
   208  		if err != nil {
   209  			return fmt.Errorf("Error deleting DNS record: %s", err)
   210  		}
   211  		if r.Rcode != dns.RcodeSuccess {
   212  			return fmt.Errorf("Error deleting DNS record: %v", r.Rcode)
   213  		}
   214  
   215  		return nil
   216  	} else {
   217  		return fmt.Errorf("update server is not set")
   218  	}
   219  }