github.com/richardmarshall/terraform@v0.9.5-0.20170429023105-15704cc6ee35/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 }