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