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  }