2016-12-13 17:22:26 +01:00
|
|
|
package aws
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/service/route53"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
)
|
|
|
|
|
|
|
|
func dataSourceAwsRoute53Zone() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Read: dataSourceAwsRoute53ZoneRead,
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"zone_id": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
"name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
"private_zone": {
|
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
Default: false,
|
|
|
|
},
|
|
|
|
"comment": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
"caller_reference": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
"vpc_id": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
"tags": tagsSchemaComputed(),
|
|
|
|
"resource_record_set_count": {
|
|
|
|
Type: schema.TypeInt,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func dataSourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
conn := meta.(*AWSClient).r53conn
|
|
|
|
name, nameExists := d.GetOk("name")
|
|
|
|
name = hostedZoneName(name.(string))
|
|
|
|
id, idExists := d.GetOk("zone_id")
|
|
|
|
vpcId, vpcIdExists := d.GetOk("vpc_id")
|
|
|
|
tags := tagsFromMap(d.Get("tags").(map[string]interface{}))
|
|
|
|
if nameExists && idExists {
|
|
|
|
return fmt.Errorf("zone_id and name arguments can't be used together")
|
|
|
|
} else if !nameExists && !idExists {
|
|
|
|
return fmt.Errorf("Either name or zone_id must be set")
|
|
|
|
}
|
|
|
|
|
|
|
|
var nextMarker *string
|
|
|
|
|
|
|
|
var hostedZoneFound *route53.HostedZone
|
|
|
|
// We loop through all hostedzone
|
|
|
|
for allHostedZoneListed := false; !allHostedZoneListed; {
|
|
|
|
req := &route53.ListHostedZonesInput{}
|
|
|
|
if nextMarker != nil {
|
|
|
|
req.Marker = nextMarker
|
|
|
|
}
|
|
|
|
resp, err := conn.ListHostedZones(req)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", err)
|
|
|
|
}
|
|
|
|
for _, hostedZone := range resp.HostedZones {
|
|
|
|
hostedZoneId := cleanZoneID(*hostedZone.Id)
|
|
|
|
if idExists && hostedZoneId == id.(string) {
|
|
|
|
hostedZoneFound = hostedZone
|
|
|
|
break
|
|
|
|
// 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
|
|
|
|
} else if *hostedZone.Name == name && (*hostedZone.Config.PrivateZone == d.Get("private_zone").(bool) || (*hostedZone.Config.PrivateZone == true && vpcIdExists)) {
|
|
|
|
matchingVPC := false
|
|
|
|
if vpcIdExists {
|
|
|
|
reqHostedZone := &route53.GetHostedZoneInput{}
|
|
|
|
reqHostedZone.Id = aws.String(hostedZoneId)
|
|
|
|
|
|
|
|
respHostedZone, errHostedZone := conn.GetHostedZone(reqHostedZone)
|
|
|
|
if errHostedZone != nil {
|
|
|
|
return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", errHostedZone)
|
|
|
|
}
|
|
|
|
// we go through all VPCs
|
|
|
|
for _, vpc := range respHostedZone.VPCs {
|
|
|
|
if *vpc.VPCId == vpcId.(string) {
|
|
|
|
matchingVPC = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
matchingVPC = true
|
|
|
|
}
|
|
|
|
// we check if tags match
|
|
|
|
matchingTags := true
|
|
|
|
if len(tags) > 0 {
|
|
|
|
reqListTags := &route53.ListTagsForResourceInput{}
|
|
|
|
reqListTags.ResourceId = aws.String(hostedZoneId)
|
|
|
|
reqListTags.ResourceType = aws.String("hostedzone")
|
|
|
|
respListTags, errListTags := conn.ListTagsForResource(reqListTags)
|
|
|
|
|
|
|
|
if errListTags != nil {
|
|
|
|
return fmt.Errorf("Error finding Route 53 Hosted Zone: %v", errListTags)
|
|
|
|
}
|
|
|
|
for _, tag := range tags {
|
|
|
|
found := false
|
|
|
|
for _, tagRequested := range respListTags.ResourceTagSet.Tags {
|
|
|
|
if *tag.Key == *tagRequested.Key && *tag.Value == *tagRequested.Value {
|
|
|
|
found = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
matchingTags = false
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if matchingTags && matchingVPC {
|
|
|
|
if hostedZoneFound != nil {
|
2017-03-30 10:12:15 +02:00
|
|
|
return fmt.Errorf("multiple Route53Zone found please use vpc_id option to filter")
|
2016-12-13 17:22:26 +01:00
|
|
|
} else {
|
|
|
|
hostedZoneFound = hostedZone
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if *resp.IsTruncated {
|
|
|
|
|
|
|
|
nextMarker = resp.NextMarker
|
|
|
|
} else {
|
|
|
|
allHostedZoneListed = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if hostedZoneFound == nil {
|
|
|
|
return fmt.Errorf("no matching Route53Zone found")
|
|
|
|
}
|
|
|
|
|
|
|
|
idHostedZone := cleanZoneID(*hostedZoneFound.Id)
|
|
|
|
d.SetId(idHostedZone)
|
|
|
|
d.Set("zone_id", idHostedZone)
|
|
|
|
d.Set("name", hostedZoneFound.Name)
|
|
|
|
d.Set("comment", hostedZoneFound.Config.Comment)
|
|
|
|
d.Set("private_zone", hostedZoneFound.Config.PrivateZone)
|
|
|
|
d.Set("caller_reference", hostedZoneFound.CallerReference)
|
|
|
|
d.Set("resource_record_set_count", hostedZoneFound.ResourceRecordSetCount)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// used to manage trailing .
|
|
|
|
func hostedZoneName(name string) string {
|
|
|
|
if strings.HasSuffix(name, ".") {
|
|
|
|
return name
|
|
|
|
} else {
|
|
|
|
return name + "."
|
|
|
|
}
|
|
|
|
}
|