Create zone before use (#1642)

* preview/push: ensure zones exists before querying them

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>

* HETZNER: reset zone cache when creating a new zone

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>

* ROUTE53: reset zone cache when creating a new zone

Signed-off-by: Jakob Ackermann <das7pad@outlook.com>

Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
Jakob Ackermann 2022-08-01 19:44:17 +01:00 committed by GitHub
parent bd1a7f26dc
commit a00572af4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 11 deletions

View file

@ -129,12 +129,7 @@ DomainLoop:
continue
}
out.StartDomain(domain.UniqueName)
nsList, err := nameservers.DetermineNameservers(domain)
if err != nil {
return err
}
domain.Nameservers = nsList
nameservers.AddNSRecords(domain)
var providersWithExistingZone []*models.DNSProviderInstance
for _, provider := range domain.DNSProviderInstances {
if !args.NoPopulate {
@ -156,7 +151,17 @@ DomainLoop:
}
}
}
providersWithExistingZone = append(providersWithExistingZone, provider)
}
nsList, err := nameservers.DetermineNameserversForProviders(domain, providersWithExistingZone)
if err != nil {
return err
}
domain.Nameservers = nsList
nameservers.AddNSRecords(domain)
for _, provider := range providersWithExistingZone {
dc, err := domain.Copy()
if err != nil {
return err

View file

@ -3,9 +3,8 @@ package nameservers
import (
"fmt"
"strings"
"strconv"
"strings"
"github.com/StackExchange/dnscontrol/v3/models"
)
@ -14,9 +13,14 @@ import (
// 1. All explicitly defined NAMESERVER records will be used.
// 2. Each DSP declares how many nameservers to use. Default is all. 0 indicates to use none.
func DetermineNameservers(dc *models.DomainConfig) ([]*models.Nameserver, error) {
return DetermineNameserversForProviders(dc, dc.DNSProviderInstances)
}
// DetermineNameserversForProviders is like DetermineNameservers, for a subset of providers.
func DetermineNameserversForProviders(dc *models.DomainConfig, providers []*models.DNSProviderInstance) ([]*models.Nameserver, error) {
// always take explicit
ns := dc.Nameservers
for _, dnsProvider := range dc.DNSProviderInstances {
for _, dnsProvider := range providers {
n := dnsProvider.NumberOfNameservers
if n == 0 {
continue

View file

@ -73,6 +73,8 @@ func (api *hetznerProvider) EnsureDomainExists(domain string) error {
}
}
// reset zone cache
api.zones = nil
return api.createZone(domain)
}

View file

@ -5,13 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
"log"
"sort"
"strings"
"time"
"unicode/utf8"
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
@ -122,8 +123,10 @@ func withRetry(f func() error) {
// ListZones lists the zones on this account.
func (r *route53Provider) ListZones() ([]string, error) {
if err := r.getZones(); err != nil {
return nil, err
}
var zones []string
// Assumes r.zones was filled already by newRoute53().
for i := range r.zonesByDomain {
zones = append(zones, i)
}
@ -131,6 +134,10 @@ func (r *route53Provider) ListZones() ([]string, error) {
}
func (r *route53Provider) getZones() error {
if r.zonesByDomain != nil {
return nil
}
var nextMarker *string
r.zonesByDomain = make(map[string]r53Types.HostedZone)
r.zonesByID = make(map[string]r53Types.HostedZone)
@ -178,6 +185,9 @@ func (e errZoneNoExist) Error() string {
}
func (r *route53Provider) GetNameservers(domain string) ([]*models.Nameserver, error) {
if err := r.getZones(); err != nil {
return nil, err
}
zone, ok := r.zonesByDomain[domain]
if !ok {
@ -201,6 +211,10 @@ func (r *route53Provider) GetNameservers(domain string) ([]*models.Nameserver, e
}
func (r *route53Provider) GetZoneRecords(domain string) (models.Records, error) {
if err := r.getZones(); err != nil {
return nil, err
}
if zone, ok := r.zonesByDomain[domain]; ok {
return r.getZoneRecords(zone)
}
@ -209,6 +223,10 @@ func (r *route53Provider) GetZoneRecords(domain string) (models.Records, error)
}
func (r *route53Provider) getZone(dc *models.DomainConfig) (r53Types.HostedZone, error) {
if err := r.getZones(); err != nil {
return r53Types.HostedZone{}, err
}
if zoneID, ok := dc.Metadata["zone_id"]; ok {
zone, ok := r.zonesByID[zoneID]
if !ok {
@ -670,6 +688,10 @@ func unescape(s *string) string {
}
func (r *route53Provider) EnsureDomainExists(domain string) error {
if err := r.getZones(); err != nil {
return err
}
if _, ok := r.zonesByDomain[domain]; ok {
return nil
}
@ -683,6 +705,11 @@ func (r *route53Provider) EnsureDomainExists(domain string) error {
DelegationSetId: r.delegationSet,
CallerReference: aws.String(fmt.Sprint(time.Now().UnixNano())),
}
// reset zone cache
r.zonesByDomain = nil
r.zonesByID = nil
var err error
withRetry(func() error {
_, err := r.client.CreateHostedZone(context.Background(), in)