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  }