github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/digitalocean/resource_digitalocean_record.go (about) 1 package digitalocean 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 "strings" 8 9 "github.com/digitalocean/godo" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceDigitalOceanRecord() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceDigitalOceanRecordCreate, 16 Read: resourceDigitalOceanRecordRead, 17 Update: resourceDigitalOceanRecordUpdate, 18 Delete: resourceDigitalOceanRecordDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "type": { 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 27 "domain": { 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 }, 32 33 "name": { 34 Type: schema.TypeString, 35 Optional: true, 36 }, 37 38 "port": { 39 Type: schema.TypeString, 40 Optional: true, 41 Computed: true, 42 ForceNew: true, 43 }, 44 45 "priority": { 46 Type: schema.TypeString, 47 Optional: true, 48 Computed: true, 49 ForceNew: true, 50 }, 51 52 "weight": { 53 Type: schema.TypeString, 54 Optional: true, 55 Computed: true, 56 ForceNew: true, 57 }, 58 59 "value": { 60 Type: schema.TypeString, 61 Optional: true, 62 Computed: true, 63 ForceNew: true, 64 }, 65 66 "fqdn": { 67 Type: schema.TypeString, 68 Computed: true, 69 }, 70 }, 71 } 72 } 73 74 func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{}) error { 75 client := meta.(*godo.Client) 76 77 newRecord := godo.DomainRecordEditRequest{ 78 Type: d.Get("type").(string), 79 Name: d.Get("name").(string), 80 Data: d.Get("value").(string), 81 } 82 83 var err error 84 if priority := d.Get("priority").(string); priority != "" { 85 newRecord.Priority, err = strconv.Atoi(priority) 86 if err != nil { 87 return fmt.Errorf("Failed to parse priority as an integer: %v", err) 88 } 89 } 90 if port := d.Get("port").(string); port != "" { 91 newRecord.Port, err = strconv.Atoi(port) 92 if err != nil { 93 return fmt.Errorf("Failed to parse port as an integer: %v", err) 94 } 95 } 96 if weight := d.Get("weight").(string); weight != "" { 97 newRecord.Weight, err = strconv.Atoi(weight) 98 if err != nil { 99 return fmt.Errorf("Failed to parse weight as an integer: %v", err) 100 } 101 } 102 103 log.Printf("[DEBUG] record create configuration: %#v", newRecord) 104 rec, _, err := client.Domains.CreateRecord(d.Get("domain").(string), &newRecord) 105 if err != nil { 106 return fmt.Errorf("Failed to create record: %s", err) 107 } 108 109 d.SetId(strconv.Itoa(rec.ID)) 110 log.Printf("[INFO] Record ID: %s", d.Id()) 111 112 return resourceDigitalOceanRecordRead(d, meta) 113 } 114 115 func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) error { 116 client := meta.(*godo.Client) 117 domain := d.Get("domain").(string) 118 id, err := strconv.Atoi(d.Id()) 119 if err != nil { 120 return fmt.Errorf("invalid record ID: %v", err) 121 } 122 123 rec, resp, err := client.Domains.Record(domain, id) 124 if err != nil { 125 // If the record is somehow already destroyed, mark as 126 // successfully gone 127 if resp.StatusCode == 404 { 128 d.SetId("") 129 return nil 130 } 131 132 return err 133 } 134 135 // Update response data for records with domain value 136 if t := rec.Type; t == "CNAME" || t == "MX" || t == "NS" || t == "SRV" { 137 // Append dot to response if resource value is absolute 138 if value := d.Get("value").(string); strings.HasSuffix(value, ".") { 139 rec.Data += "." 140 // If resource value ends with current domain, make response data absolute 141 if strings.HasSuffix(value, domain+".") { 142 rec.Data += domain + "." 143 } 144 } 145 } 146 147 d.Set("name", rec.Name) 148 d.Set("type", rec.Type) 149 d.Set("value", rec.Data) 150 d.Set("weight", strconv.Itoa(rec.Weight)) 151 d.Set("priority", strconv.Itoa(rec.Priority)) 152 d.Set("port", strconv.Itoa(rec.Port)) 153 154 en := constructFqdn(rec.Name, d.Get("domain").(string)) 155 log.Printf("[DEBUG] Constructed FQDN: %s", en) 156 d.Set("fqdn", en) 157 158 return nil 159 } 160 161 func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{}) error { 162 client := meta.(*godo.Client) 163 164 domain := d.Get("domain").(string) 165 id, err := strconv.Atoi(d.Id()) 166 if err != nil { 167 return fmt.Errorf("invalid record ID: %v", err) 168 } 169 170 var editRecord godo.DomainRecordEditRequest 171 if v, ok := d.GetOk("name"); ok { 172 editRecord.Name = v.(string) 173 } 174 175 log.Printf("[DEBUG] record update configuration: %#v", editRecord) 176 _, _, err = client.Domains.EditRecord(domain, id, &editRecord) 177 if err != nil { 178 return fmt.Errorf("Failed to update record: %s", err) 179 } 180 181 return resourceDigitalOceanRecordRead(d, meta) 182 } 183 184 func resourceDigitalOceanRecordDelete(d *schema.ResourceData, meta interface{}) error { 185 client := meta.(*godo.Client) 186 187 domain := d.Get("domain").(string) 188 id, err := strconv.Atoi(d.Id()) 189 if err != nil { 190 return fmt.Errorf("invalid record ID: %v", err) 191 } 192 193 log.Printf("[INFO] Deleting record: %s, %d", domain, id) 194 195 resp, delErr := client.Domains.DeleteRecord(domain, id) 196 if delErr != nil { 197 // If the record is somehow already destroyed, mark as 198 // successfully gone 199 if resp.StatusCode == 404 { 200 return nil 201 } 202 203 return fmt.Errorf("Error deleting record: %s", delErr) 204 } 205 206 return nil 207 } 208 209 func constructFqdn(name, domain string) string { 210 rn := strings.ToLower(strings.TrimSuffix(name, ".")) 211 domain = strings.TrimSuffix(domain, ".") 212 if !strings.HasSuffix(rn, domain) { 213 rn = strings.Join([]string{name, domain}, ".") 214 } 215 return rn 216 }