github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/builtin/providers/aws/resource_aws_route53_zone.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  
    13  	"github.com/awslabs/aws-sdk-go/aws"
    14  	"github.com/awslabs/aws-sdk-go/service/route53"
    15  )
    16  
    17  func resourceAwsRoute53Zone() *schema.Resource {
    18  	return &schema.Resource{
    19  		Create: resourceAwsRoute53ZoneCreate,
    20  		Read:   resourceAwsRoute53ZoneRead,
    21  		Update: resourceAwsRoute53ZoneUpdate,
    22  		Delete: resourceAwsRoute53ZoneDelete,
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"name": &schema.Schema{
    26  				Type:     schema.TypeString,
    27  				Required: true,
    28  				ForceNew: true,
    29  			},
    30  
    31  			"zone_id": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Computed: true,
    34  			},
    35  
    36  			"name_servers": &schema.Schema{
    37  				Type:     schema.TypeSet,
    38  				Elem:     &schema.Schema{Type: schema.TypeString},
    39  				Computed: true,
    40  				Set: func(v interface{}) int {
    41  					return hashcode.String(v.(string))
    42  				},
    43  			},
    44  
    45  			"tags": tagsSchema(),
    46  		},
    47  	}
    48  }
    49  
    50  func resourceAwsRoute53ZoneCreate(d *schema.ResourceData, meta interface{}) error {
    51  	r53 := meta.(*AWSClient).r53conn
    52  
    53  	comment := &route53.HostedZoneConfig{Comment: aws.String("Managed by Terraform")}
    54  	req := &route53.CreateHostedZoneInput{
    55  		Name:             aws.String(d.Get("name").(string)),
    56  		HostedZoneConfig: comment,
    57  		CallerReference:  aws.String(time.Now().Format(time.RFC3339Nano)),
    58  	}
    59  
    60  	log.Printf("[DEBUG] Creating Route53 hosted zone: %s", *req.Name)
    61  	resp, err := r53.CreateHostedZone(req)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	// Store the zone_id
    67  	zone := cleanZoneID(*resp.HostedZone.ID)
    68  	d.Set("zone_id", zone)
    69  	d.SetId(zone)
    70  
    71  	// Wait until we are done initializing
    72  	wait := resource.StateChangeConf{
    73  		Delay:      30 * time.Second,
    74  		Pending:    []string{"PENDING"},
    75  		Target:     "INSYNC",
    76  		Timeout:    10 * time.Minute,
    77  		MinTimeout: 2 * time.Second,
    78  		Refresh: func() (result interface{}, state string, err error) {
    79  			changeRequest := &route53.GetChangeInput{
    80  				ID: aws.String(cleanChangeID(*resp.ChangeInfo.ID)),
    81  			}
    82  			return resourceAwsGoRoute53Wait(r53, changeRequest)
    83  		},
    84  	}
    85  	_, err = wait.WaitForState()
    86  	if err != nil {
    87  		return err
    88  	}
    89  	return resourceAwsRoute53ZoneUpdate(d, meta)
    90  }
    91  
    92  func resourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error {
    93  	r53 := meta.(*AWSClient).r53conn
    94  	zone, err := r53.GetHostedZone(&route53.GetHostedZoneInput{ID: aws.String(d.Id())})
    95  	if err != nil {
    96  		// Handle a deleted zone
    97  		if r53err, ok := err.(aws.APIError); ok && r53err.Code == "NoSuchHostedZone" {
    98  			d.SetId("")
    99  			return nil
   100  		}
   101  		return err
   102  	}
   103  
   104  	ns := make([]string, len(zone.DelegationSet.NameServers))
   105  	for i := range zone.DelegationSet.NameServers {
   106  		ns[i] = *zone.DelegationSet.NameServers[i]
   107  	}
   108  	if err := d.Set("name_servers", ns); err != nil {
   109  		return fmt.Errorf("[DEBUG] Error setting name servers for: %s, error: %#v", d.Id(), err)
   110  	}
   111  
   112  	// get tags
   113  	req := &route53.ListTagsForResourceInput{
   114  		ResourceID:   aws.String(d.Id()),
   115  		ResourceType: aws.String("hostedzone"),
   116  	}
   117  
   118  	resp, err := r53.ListTagsForResource(req)
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	var tags []*route53.Tag
   124  	if resp.ResourceTagSet != nil {
   125  		tags = resp.ResourceTagSet.Tags
   126  	}
   127  
   128  	if err := d.Set("tags", tagsToMapR53(tags)); err != nil {
   129  		return err
   130  	}
   131  
   132  	return nil
   133  }
   134  
   135  func resourceAwsRoute53ZoneUpdate(d *schema.ResourceData, meta interface{}) error {
   136  	conn := meta.(*AWSClient).r53conn
   137  
   138  	if err := setTagsR53(conn, d); err != nil {
   139  		return err
   140  	} else {
   141  		d.SetPartial("tags")
   142  	}
   143  
   144  	return resourceAwsRoute53ZoneRead(d, meta)
   145  }
   146  
   147  func resourceAwsRoute53ZoneDelete(d *schema.ResourceData, meta interface{}) error {
   148  	r53 := meta.(*AWSClient).r53conn
   149  
   150  	log.Printf("[DEBUG] Deleting Route53 hosted zone: %s (ID: %s)",
   151  		d.Get("name").(string), d.Id())
   152  	_, err := r53.DeleteHostedZone(&route53.DeleteHostedZoneInput{ID: aws.String(d.Id())})
   153  	if err != nil {
   154  		return err
   155  	}
   156  
   157  	return nil
   158  }
   159  
   160  func resourceAwsGoRoute53Wait(r53 *route53.Route53, ref *route53.GetChangeInput) (result interface{}, state string, err error) {
   161  
   162  	status, err := r53.GetChange(ref)
   163  	if err != nil {
   164  		return nil, "UNKNOWN", err
   165  	}
   166  	return true, *status.ChangeInfo.Status, nil
   167  }
   168  
   169  // cleanChangeID is used to remove the leading /change/
   170  func cleanChangeID(ID string) string {
   171  	return cleanPrefix(ID, "/change/")
   172  }
   173  
   174  // cleanZoneID is used to remove the leading /hostedzone/
   175  func cleanZoneID(ID string) string {
   176  	return cleanPrefix(ID, "/hostedzone/")
   177  }
   178  
   179  // cleanPrefix removes a string prefix from an ID
   180  func cleanPrefix(ID, prefix string) string {
   181  	if strings.HasPrefix(ID, prefix) {
   182  		ID = strings.TrimPrefix(ID, prefix)
   183  	}
   184  	return ID
   185  }