terraform-provider-greenhost/digitalocean/resource_digitalocean_recor...

278 lines
6.5 KiB
Go
Raw Normal View History

2014-07-24 17:47:22 +00:00
package digitalocean
import (
"context"
2014-07-24 17:47:22 +00:00
"fmt"
"log"
"strconv"
"strings"
2014-07-24 17:47:22 +00:00
"github.com/digitalocean/godo"
"github.com/hashicorp/terraform/helper/schema"
2014-07-24 17:47:22 +00:00
)
func resourceDigitalOceanRecord() *schema.Resource {
return &schema.Resource{
Create: resourceDigitalOceanRecordCreate,
Read: resourceDigitalOceanRecordRead,
Update: resourceDigitalOceanRecordUpdate,
Delete: resourceDigitalOceanRecordDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"domain": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"port": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"priority": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"weight": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"ttl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"value": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"fqdn": {
Type: schema.TypeString,
Computed: true,
},
"flags": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"tag": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
}
}
func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*godo.Client)
newRecord := godo.DomainRecordEditRequest{
Type: d.Get("type").(string),
Name: d.Get("name").(string),
Data: d.Get("value").(string),
Tag: d.Get("tag").(string),
}
var err error
if priority := d.Get("priority").(string); priority != "" {
newRecord.Priority, err = strconv.Atoi(priority)
if err != nil {
return fmt.Errorf("Failed to parse priority as an integer: %v", err)
}
}
if port := d.Get("port").(string); port != "" {
newRecord.Port, err = strconv.Atoi(port)
if err != nil {
return fmt.Errorf("Failed to parse port as an integer: %v", err)
}
}
if ttl := d.Get("ttl").(string); ttl != "" {
newRecord.TTL, err = strconv.Atoi(ttl)
if err != nil {
return fmt.Errorf("Failed to parse ttl as an integer: %v", err)
}
}
if weight := d.Get("weight").(string); weight != "" {
newRecord.Weight, err = strconv.Atoi(weight)
if err != nil {
return fmt.Errorf("Failed to parse weight as an integer: %v", err)
}
2014-07-24 17:47:22 +00:00
}
if flags := d.Get("flags").(string); flags != "" {
newRecord.Flags, err = strconv.Atoi(flags)
if err != nil {
return fmt.Errorf("Failed to parse flags as an integer: %v", err)
}
}
2014-07-24 17:47:22 +00:00
log.Printf("[DEBUG] record create configuration: %#v", newRecord)
rec, _, err := client.Domains.CreateRecord(context.Background(), d.Get("domain").(string), &newRecord)
2014-07-24 17:47:22 +00:00
if err != nil {
return fmt.Errorf("Failed to create record: %s", err)
2014-07-24 17:47:22 +00:00
}
d.SetId(strconv.Itoa(rec.ID))
log.Printf("[INFO] Record ID: %s", d.Id())
2014-07-24 17:47:22 +00:00
return resourceDigitalOceanRecordRead(d, meta)
2014-07-24 17:47:22 +00:00
}
func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*godo.Client)
domain := d.Get("domain").(string)
id, err := strconv.Atoi(d.Id())
if err != nil {
// Catches an import and sets the id/domain for Record call
if strings.Contains(d.Id(), ",") {
s := strings.Split(d.Id(), ",")
id, err = strconv.Atoi(s[0])
domain = s[1]
if err != nil {
return fmt.Errorf("invalid record ID: %v", err)
}
} else {
return fmt.Errorf("invalid record ID: %v", err)
}
}
rec, resp, err := client.Domains.Record(context.Background(), domain, id)
if err != nil && resp != nil {
// If the record is somehow already destroyed, mark as
2015-09-11 18:56:20 +00:00
// successfully gone
if resp.StatusCode == 404 {
d.SetId("")
return nil
}
return err
} else if err != nil {
return err
}
if t := rec.Type; t == "CNAME" || t == "MX" || t == "NS" || t == "SRV" || t == "CAA" {
if rec.Data == "@" {
rec.Data = domain
}
rec.Data += "."
}
// Sets Id and domain to appropriate values during an import
if strings.Contains(d.Id(), ",") {
d.SetId(strconv.Itoa(rec.ID))
d.Set("domain", domain)
}
d.Set("name", rec.Name)
d.Set("type", rec.Type)
d.Set("value", rec.Data)
d.Set("weight", strconv.Itoa(rec.Weight))
d.Set("priority", strconv.Itoa(rec.Priority))
d.Set("port", strconv.Itoa(rec.Port))
d.Set("ttl", strconv.Itoa(rec.TTL))
d.Set("flags", strconv.Itoa(rec.Flags))
d.Set("tag", rec.Tag)
en := constructFqdn(rec.Name, d.Get("domain").(string))
2016-02-22 18:31:59 +00:00
log.Printf("[DEBUG] Constructed FQDN: %s", en)
d.Set("fqdn", en)
return nil
}
func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*godo.Client)
2014-07-24 17:47:22 +00:00
domain := d.Get("domain").(string)
id, err := strconv.Atoi(d.Id())
if err != nil {
return fmt.Errorf("invalid record ID: %v", err)
}
var editRecord godo.DomainRecordEditRequest
if v, ok := d.GetOk("name"); ok {
editRecord.Name = v.(string)
2014-07-24 17:47:22 +00:00
}
if d.HasChange("ttl") {
newTTL := d.Get("ttl").(string)
editRecord.TTL, err = strconv.Atoi(newTTL)
if err != nil {
return fmt.Errorf("Failed to parse ttl as an integer: %v", err)
}
}
log.Printf("[DEBUG] record update configuration: %#v", editRecord)
_, _, err = client.Domains.EditRecord(context.Background(), domain, id, &editRecord)
2014-07-24 17:47:22 +00:00
if err != nil {
return fmt.Errorf("Failed to update record: %s", err)
2014-07-24 17:47:22 +00:00
}
return resourceDigitalOceanRecordRead(d, meta)
2014-07-24 17:47:22 +00:00
}
func resourceDigitalOceanRecordDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*godo.Client)
domain := d.Get("domain").(string)
id, err := strconv.Atoi(d.Id())
if err != nil {
return fmt.Errorf("invalid record ID: %v", err)
}
log.Printf("[INFO] Deleting record: %s, %d", domain, id)
2014-07-24 17:47:22 +00:00
resp, delErr := client.Domains.DeleteRecord(context.Background(), domain, id)
if delErr != nil {
// If the record is somehow already destroyed, mark as
2015-09-11 18:56:20 +00:00
// successfully gone
if resp.StatusCode == 404 {
return nil
}
return fmt.Errorf("Error deleting record: %s", delErr)
2014-07-24 17:47:22 +00:00
}
return nil
}
func constructFqdn(name, domain string) string {
rn := strings.ToLower(strings.TrimSuffix(name, "."))
domain = strings.TrimSuffix(domain, ".")
if !strings.HasSuffix(rn, domain) {
rn = strings.Join([]string{name, domain}, ".")
}
return rn
}