From 323bb88640cb9be7860d2a21e93d5f823560ae11 Mon Sep 17 00:00:00 2001 From: Jan Broer Date: Fri, 22 Jan 2016 18:50:18 +0100 Subject: [PATCH] Fetch remaining zones when response is truncated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Route53 API won’t return more than 100 zones per request. --- acme/dns_challenge_route53.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/acme/dns_challenge_route53.go b/acme/dns_challenge_route53.go index 6121a00c..b97a619b 100644 --- a/acme/dns_challenge_route53.go +++ b/acme/dns_challenge_route53.go @@ -2,8 +2,8 @@ package acme import ( "fmt" - "math" "strings" + "time" "github.com/mitchellh/goamz/aws" "github.com/mitchellh/goamz/route53" @@ -64,13 +64,28 @@ func (r *DNSProviderRoute53) changeRecord(action, fqdn, value string, ttl int) e } func (r *DNSProviderRoute53) getHostedZoneID(fqdn string) (string, error) { - zoneResp, err := r.client.ListHostedZones("", math.MaxInt32) + zones := []route53.HostedZone{} + zoneResp, err := r.client.ListHostedZones("", 0) if err != nil { return "", err } + zones = append(zones, zoneResp.HostedZones...) + + for zoneResp.IsTruncated { + resp, err := r.client.ListHostedZones(zoneResp.Marker, 0) + if err != nil { + if rateExceeded(err) { + time.Sleep(time.Second) + continue + } + return "", err + } + zoneResp = resp + zones = append(zones, zoneResp.HostedZones...) + } + var hostedZone route53.HostedZone - for _, zone := range zoneResp.HostedZones { - //if strings.HasSuffix(domain, strings.Trim(zone.Name, ".")) { + for _, zone := range zones { if strings.HasSuffix(fqdn, zone.Name) { if len(zone.Name) > len(hostedZone.Name) { hostedZone = zone @@ -78,7 +93,7 @@ func (r *DNSProviderRoute53) getHostedZoneID(fqdn string) (string, error) { } } if hostedZone.ID == "" { - return "", fmt.Errorf("No Route53 zone found for domain %s", fqdn) + return "", fmt.Errorf("No Route53 hosted zone found for domain %s", fqdn) } return hostedZone.ID, nil @@ -92,3 +107,12 @@ func newTXTRecordSet(fqdn, value string, ttl int) route53.ResourceRecordSet { TTL: ttl, } } + +// Route53 API has pretty strict rate limits (5req/s globally per account) +// Hence we check if we are being throttled to maybe retry the request +func rateExceeded (err error) bool { + if strings.Contains(err.Error(), "Throttling") { + return true + } + return false +}