github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/aws/data_source_aws_route53_zone.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/service/route53"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  )
    11  
    12  func dataSourceAwsRoute53Zone() *schema.Resource {
    13  	return &schema.Resource{
    14  		Read: dataSourceAwsRoute53ZoneRead,
    15  
    16  		Schema: map[string]*schema.Schema{
    17  			"zone_id": {
    18  				Type:     schema.TypeString,
    19  				Optional: true,
    20  				Computed: true,
    21  			},
    22  			"name": {
    23  				Type:     schema.TypeString,
    24  				Optional: true,
    25  				Computed: true,
    26  			},
    27  			"private_zone": {
    28  				Type:     schema.TypeBool,
    29  				Optional: true,
    30  				Default:  false,
    31  			},
    32  			"comment": {
    33  				Type:     schema.TypeString,
    34  				Optional: true,
    35  				Computed: true,
    36  			},
    37  			"caller_reference": {
    38  				Type:     schema.TypeString,
    39  				Optional: true,
    40  				Computed: true,
    41  			},
    42  			"vpc_id": {
    43  				Type:     schema.TypeString,
    44  				Optional: true,
    45  				Computed: true,
    46  			},
    47  			"tags": tagsSchemaComputed(),
    48  			"resource_record_set_count": {
    49  				Type:     schema.TypeInt,
    50  				Optional: true,
    51  				Computed: true,
    52  			},
    53  		},
    54  	}
    55  }
    56  
    57  func dataSourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error {
    58  	conn := meta.(*AWSClient).r53conn
    59  	name, nameExists := d.GetOk("name")
    60  	name = hostedZoneName(name.(string))
    61  	id, idExists := d.GetOk("zone_id")
    62  	vpcId, vpcIdExists := d.GetOk("vpc_id")
    63  	tags := tagsFromMap(d.Get("tags").(map[string]interface{}))
    64  	if nameExists && idExists {
    65  		return fmt.Errorf("zone_id and name arguments can't be used together")
    66  	} else if !nameExists && !idExists {
    67  		return fmt.Errorf("Either name or zone_id must be set")
    68  	}
    69  
    70  	var nextMarker *string
    71  
    72  	var hostedZoneFound *route53.HostedZone
    73  	// We loop through all hostedzone
    74  	for allHostedZoneListed := false; !allHostedZoneListed; {
    75  		req := &route53.ListHostedZonesInput{}
    76  		if nextMarker != nil {
    77  			req.Marker = nextMarker
    78  		}
    79  		resp, err := conn.ListHostedZones(req)
    80  
    81  		if err != nil {
    82  			return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", err)
    83  		}
    84  		for _, hostedZone := range resp.HostedZones {
    85  			hostedZoneId := cleanZoneID(*hostedZone.Id)
    86  			if idExists && hostedZoneId == id.(string) {
    87  				hostedZoneFound = hostedZone
    88  				break
    89  				// we check if the name is the same as requested and if private zone field is the same as requested or if there is a vpc_id
    90  			} else if *hostedZone.Name == name && (*hostedZone.Config.PrivateZone == d.Get("private_zone").(bool) || (*hostedZone.Config.PrivateZone == true && vpcIdExists)) {
    91  				matchingVPC := false
    92  				if vpcIdExists {
    93  					reqHostedZone := &route53.GetHostedZoneInput{}
    94  					reqHostedZone.Id = aws.String(hostedZoneId)
    95  
    96  					respHostedZone, errHostedZone := conn.GetHostedZone(reqHostedZone)
    97  					if errHostedZone != nil {
    98  						return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", errHostedZone)
    99  					}
   100  					// we go through all VPCs
   101  					for _, vpc := range respHostedZone.VPCs {
   102  						if *vpc.VPCId == vpcId.(string) {
   103  							matchingVPC = true
   104  							break
   105  						}
   106  					}
   107  				} else {
   108  					matchingVPC = true
   109  				}
   110  				// we check if tags match
   111  				matchingTags := true
   112  				if len(tags) > 0 {
   113  					reqListTags := &route53.ListTagsForResourceInput{}
   114  					reqListTags.ResourceId = aws.String(hostedZoneId)
   115  					reqListTags.ResourceType = aws.String("hostedzone")
   116  					respListTags, errListTags := conn.ListTagsForResource(reqListTags)
   117  
   118  					if errListTags != nil {
   119  						return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", errListTags)
   120  					}
   121  					for _, tag := range tags {
   122  						found := false
   123  						for _, tagRequested := range respListTags.ResourceTagSet.Tags {
   124  							if *tag.Key == *tagRequested.Key && *tag.Value == *tagRequested.Value {
   125  								found = true
   126  							}
   127  						}
   128  
   129  						if !found {
   130  							matchingTags = false
   131  							break
   132  						}
   133  					}
   134  
   135  				}
   136  
   137  				if matchingTags && matchingVPC {
   138  					if hostedZoneFound != nil {
   139  						return fmt.Errorf("multiple Route53Zone found please use vpc_id option to filter")
   140  					} else {
   141  						hostedZoneFound = hostedZone
   142  					}
   143  				}
   144  			}
   145  
   146  		}
   147  		if *resp.IsTruncated {
   148  
   149  			nextMarker = resp.NextMarker
   150  		} else {
   151  			allHostedZoneListed = true
   152  		}
   153  	}
   154  	if hostedZoneFound == nil {
   155  		return fmt.Errorf("no matching Route53Zone found")
   156  	}
   157  
   158  	idHostedZone := cleanZoneID(*hostedZoneFound.Id)
   159  	d.SetId(idHostedZone)
   160  	d.Set("zone_id", idHostedZone)
   161  	d.Set("name", hostedZoneFound.Name)
   162  	d.Set("comment", hostedZoneFound.Config.Comment)
   163  	d.Set("private_zone", hostedZoneFound.Config.PrivateZone)
   164  	d.Set("caller_reference", hostedZoneFound.CallerReference)
   165  	d.Set("resource_record_set_count", hostedZoneFound.ResourceRecordSetCount)
   166  	return nil
   167  }
   168  
   169  // used to manage trailing .
   170  func hostedZoneName(name string) string {
   171  	if strings.HasSuffix(name, ".") {
   172  		return name
   173  	} else {
   174  		return name + "."
   175  	}
   176  }