Make sure we don't provision to a private hosted zone

Route 53 allows multiple zones with the same name to co-exist in an
account. The most common use case for this is a split-view DNS with one
private and one public zone for the same domain name. This patch makes
sure we don’t ever provision the authorization record to the private
zone.
The other case where a user has multiple public zones with the same
name is not covered here since this would require a bigger change in
code in order to determine which of the zones is active from the
viewpoint of the internet. Also this is probably an edge use case that
can be addressed once it comes up in the issues.
This commit is contained in:
JanB 2016-04-21 15:47:43 +02:00
parent 094e3d41bb
commit 4d9e4f1487

View file

@ -84,7 +84,7 @@ func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error { func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
hostedZoneID, err := r.getHostedZoneID(fqdn) hostedZoneID, err := r.getHostedZoneID(fqdn)
if err != nil { if err != nil {
return err return fmt.Errorf("Failed to determine Route 53 hosted zone ID: %v", err)
} }
recordSet := newTXTRecordSet(fqdn, value, ttl) recordSet := newTXTRecordSet(fqdn, value, ttl)
@ -103,7 +103,7 @@ func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
resp, err := r.client.ChangeResourceRecordSets(reqParams) resp, err := r.client.ChangeResourceRecordSets(reqParams)
if err != nil { if err != nil {
return err return fmt.Errorf("Failed to change Route 53 record set: %v", err)
} }
statusID := resp.ChangeInfo.Id statusID := resp.ChangeInfo.Id
@ -114,7 +114,7 @@ func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
} }
resp, err := r.client.GetChange(reqParams) resp, err := r.client.GetChange(reqParams)
if err != nil { if err != nil {
return false, err return false, fmt.Errorf("Failed to query Route 53 change status: %v", err)
} }
if *resp.ChangeInfo.Status == route53.ChangeStatusInsync { if *resp.ChangeInfo.Status == route53.ChangeStatusInsync {
return true, nil return true, nil
@ -132,24 +132,30 @@ func (r *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
// .DNSName should not have a trailing dot // .DNSName should not have a trailing dot
reqParams := &route53.ListHostedZonesByNameInput{ reqParams := &route53.ListHostedZonesByNameInput{
DNSName: aws.String(acme.UnFqdn(authZone)), DNSName: aws.String(acme.UnFqdn(authZone)),
MaxItems: aws.String("1"),
} }
resp, err := r.client.ListHostedZonesByName(reqParams) resp, err := r.client.ListHostedZonesByName(reqParams)
if err != nil { if err != nil {
return "", err return "", err
} }
var hostedZoneID string
for _, hostedZone := range resp.HostedZones {
// .Name has a trailing dot // .Name has a trailing dot
if len(resp.HostedZones) == 0 || *resp.HostedZones[0].Name != authZone { if !*hostedZone.Config.PrivateZone && *hostedZone.Name == authZone {
hostedZoneID = *hostedZone.Id
break
}
}
if len(hostedZoneID) == 0 {
return "", fmt.Errorf("Zone %s not found in Route 53 for domain %s", authZone, fqdn) return "", fmt.Errorf("Zone %s not found in Route 53 for domain %s", authZone, fqdn)
} }
zoneID := *resp.HostedZones[0].Id if strings.HasPrefix(hostedZoneID, "/hostedzone/") {
if strings.HasPrefix(zoneID, "/hostedzone/") { hostedZoneID = strings.TrimPrefix(hostedZoneID, "/hostedzone/")
zoneID = strings.TrimPrefix(zoneID, "/hostedzone/")
} }
return zoneID, nil return hostedZoneID, nil
} }
func newTXTRecordSet(fqdn, value string, ttl int) *route53.ResourceRecordSet { func newTXTRecordSet(fqdn, value string, ttl int) *route53.ResourceRecordSet {