github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/builtin/providers/cloudflare/resource_cloudflare_record.go (about)

     1  package cloudflare
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  	"time"
     8  
     9  	"golang.org/x/net/context"
    10  
    11  	"github.com/crackcomm/cloudflare"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceCloudFlareRecord() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceCloudFlareRecordCreate,
    18  		Read:   resourceCloudFlareRecordRead,
    19  		Update: resourceCloudFlareRecordUpdate,
    20  		Delete: resourceCloudFlareRecordDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"domain": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  			},
    27  
    28  			"name": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  			},
    32  
    33  			"hostname": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Computed: true,
    36  			},
    37  
    38  			"type": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ForceNew: true,
    42  			},
    43  
    44  			"value": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Required: true,
    47  			},
    48  
    49  			"ttl": &schema.Schema{
    50  				Type:     schema.TypeInt,
    51  				Optional: true,
    52  				Computed: true,
    53  			},
    54  
    55  			"priority": &schema.Schema{
    56  				Type:     schema.TypeInt,
    57  				Optional: true,
    58  			},
    59  
    60  			"proxied": &schema.Schema{
    61  				Default:  false,
    62  				Optional: true,
    63  				Type:     schema.TypeBool,
    64  			},
    65  
    66  			"zone_id": &schema.Schema{
    67  				Type:     schema.TypeString,
    68  				Computed: true,
    69  			},
    70  		},
    71  	}
    72  }
    73  
    74  func resourceCloudFlareRecordCreate(d *schema.ResourceData, meta interface{}) error {
    75  	client := meta.(*cloudflare.Client)
    76  
    77  	newRecord := &cloudflare.Record{
    78  		Content:  d.Get("value").(string),
    79  		Name:     d.Get("name").(string),
    80  		Proxied:  d.Get("proxied").(bool),
    81  		Type:     d.Get("type").(string),
    82  		ZoneName: d.Get("domain").(string),
    83  	}
    84  
    85  	if priority, ok := d.GetOk("priority"); ok {
    86  		newRecord.Priority = priority.(int)
    87  	}
    88  
    89  	if ttl, ok := d.GetOk("ttl"); ok {
    90  		newRecord.TTL = ttl.(int)
    91  	}
    92  
    93  	zone, err := retrieveZone(client, newRecord.ZoneName)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	d.Set("zone_id", zone.ID)
    99  	newRecord.ZoneID = zone.ID
   100  
   101  	log.Printf("[DEBUG] CloudFlare Record create configuration: %#v", newRecord)
   102  
   103  	ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
   104  
   105  	err = client.Records.Create(ctx, newRecord)
   106  	if err != nil {
   107  		return fmt.Errorf("Failed to create record: %s", err)
   108  	}
   109  
   110  	d.SetId(newRecord.ID)
   111  
   112  	log.Printf("[INFO] CloudFlare Record ID: %s", d.Id())
   113  
   114  	return resourceCloudFlareRecordRead(d, meta)
   115  }
   116  
   117  func resourceCloudFlareRecordRead(d *schema.ResourceData, meta interface{}) error {
   118  	var (
   119  		client = meta.(*cloudflare.Client)
   120  		domain = d.Get("domain").(string)
   121  		rName  = strings.Join([]string{d.Get("name").(string), domain}, ".")
   122  	)
   123  
   124  	zone, err := retrieveZone(client, domain)
   125  	if err != nil {
   126  		return err
   127  	}
   128  
   129  	record, err := retrieveRecord(client, zone, rName)
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	d.SetId(record.ID)
   135  	d.Set("hostname", record.Name)
   136  	d.Set("type", record.Type)
   137  	d.Set("value", record.Content)
   138  	d.Set("ttl", record.TTL)
   139  	d.Set("priority", record.Priority)
   140  	d.Set("proxied", record.Proxied)
   141  	d.Set("zone_id", zone.ID)
   142  
   143  	return nil
   144  }
   145  
   146  func resourceCloudFlareRecordUpdate(d *schema.ResourceData, meta interface{}) error {
   147  	client := meta.(*cloudflare.Client)
   148  
   149  	updateRecord := &cloudflare.Record{
   150  		Content:  d.Get("value").(string),
   151  		ID:       d.Id(),
   152  		Name:     d.Get("name").(string),
   153  		Proxied:  false,
   154  		Type:     d.Get("type").(string),
   155  		ZoneName: d.Get("domain").(string),
   156  	}
   157  
   158  	if priority, ok := d.GetOk("priority"); ok {
   159  		updateRecord.Priority = priority.(int)
   160  	}
   161  
   162  	if proxied, ok := d.GetOk("proxied"); ok {
   163  		updateRecord.Proxied = proxied.(bool)
   164  	}
   165  
   166  	if ttl, ok := d.GetOk("ttl"); ok {
   167  		updateRecord.TTL = ttl.(int)
   168  	}
   169  
   170  	zone, err := retrieveZone(client, updateRecord.ZoneName)
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	updateRecord.ZoneID = zone.ID
   176  
   177  	log.Printf("[DEBUG] CloudFlare Record update configuration: %#v", updateRecord)
   178  
   179  	ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
   180  
   181  	err = client.Records.Patch(ctx, updateRecord)
   182  	if err != nil {
   183  		return fmt.Errorf("Failed to update CloudFlare Record: %s", err)
   184  	}
   185  
   186  	return resourceCloudFlareRecordRead(d, meta)
   187  }
   188  
   189  func resourceCloudFlareRecordDelete(d *schema.ResourceData, meta interface{}) error {
   190  	var (
   191  		client = meta.(*cloudflare.Client)
   192  		domain = d.Get("domain").(string)
   193  		rName  = strings.Join([]string{d.Get("name").(string), domain}, ".")
   194  	)
   195  
   196  	zone, err := retrieveZone(client, domain)
   197  	if err != nil {
   198  		return err
   199  	}
   200  
   201  	record, err := retrieveRecord(client, zone, rName)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	log.Printf("[INFO] Deleting CloudFlare Record: %s, %s", domain, d.Id())
   207  
   208  	ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
   209  
   210  	err = client.Records.Delete(ctx, zone.ID, record.ID)
   211  	if err != nil {
   212  		return fmt.Errorf("Error deleting CloudFlare Record: %s", err)
   213  	}
   214  
   215  	return nil
   216  }
   217  
   218  func retrieveRecord(
   219  	client *cloudflare.Client,
   220  	zone *cloudflare.Zone,
   221  	name string,
   222  ) (*cloudflare.Record, error) {
   223  	ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
   224  
   225  	rs, err := client.Records.List(ctx, zone.ID)
   226  	if err != nil {
   227  		return nil, fmt.Errorf("Unable to retrieve records for (%s): %s", zone.Name, err)
   228  	}
   229  
   230  	var record *cloudflare.Record
   231  
   232  	for _, r := range rs {
   233  		if r.Name == name {
   234  			record = r
   235  		}
   236  	}
   237  	if record == nil {
   238  		return nil, fmt.Errorf("Unable to find Cloudflare record %s", name)
   239  	}
   240  
   241  	return record, nil
   242  }
   243  
   244  func retrieveZone(client *cloudflare.Client, domain string) (*cloudflare.Zone, error) {
   245  	ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
   246  
   247  	zs, err := client.Zones.List(ctx)
   248  	if err != nil {
   249  		return nil, fmt.Errorf("Failed to fetch zone for %s: %s", domain, err)
   250  	}
   251  
   252  	var zone *cloudflare.Zone
   253  
   254  	for _, z := range zs {
   255  		if z.Name == domain {
   256  			zone = z
   257  		}
   258  	}
   259  
   260  	if zone == nil {
   261  		return nil, fmt.Errorf("Failed to find zone for: %s", domain)
   262  	}
   263  
   264  	return zone, nil
   265  }