1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

Implement get-zones (#641)

This commit is contained in:
Tom Limoncelli
2020-02-21 13:49:10 -05:00
committed by GitHub
parent f5d6f8074d
commit 1ec696e4fa

View File

@ -22,7 +22,7 @@ var features = providers.DocumentationNotes{
providers.CanUseSRV: providers.Can(), providers.CanUseSRV: providers.Can(),
providers.CanUseCAA: providers.Can(), providers.CanUseCAA: providers.Can(),
providers.CanUseTXTMulti: providers.Can(), providers.CanUseTXTMulti: providers.Can(),
providers.CanGetZones: providers.Unimplemented(), providers.CanGetZones: providers.Can(),
} }
func sPtr(s string) *string { func sPtr(s string) *string {
@ -40,6 +40,14 @@ type gcloud struct {
zones map[string]*gdns.ManagedZone zones map[string]*gdns.ManagedZone
} }
type errNoExist struct {
domain string
}
func (e errNoExist) Error() string {
return fmt.Sprintf("Domain '%s' not found in gcloud account", e.domain)
}
// New creates a new gcloud provider // New creates a new gcloud provider
func New(cfg map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) { func New(cfg map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
// the key as downloaded is json encoded with literal "\n" instead of newlines. // the key as downloaded is json encoded with literal "\n" instead of newlines.
@ -67,29 +75,25 @@ func New(cfg map[string]string, metadata json.RawMessage) (providers.DNSServiceP
fmt.Printf("GCLOUD :name_server_set %s configured\n", val) fmt.Printf("GCLOUD :name_server_set %s configured\n", val)
nss = sPtr(val) nss = sPtr(val)
} }
return &gcloud{
g := &gcloud{
client: dcli, client: dcli,
nameServerSet: nss, nameServerSet: nss,
project: cfg["project_id"], project: cfg["project_id"],
}, nil }
return g, g.loadZoneInfo()
} }
type errNoExist struct { func (g *gcloud) loadZoneInfo() error {
domain string if g.zones != nil {
} return nil
}
func (e errNoExist) Error() string {
return fmt.Sprintf("Domain %s not found in gcloud account", e.domain)
}
func (g *gcloud) getZone(domain string) (*gdns.ManagedZone, error) {
if g.zones == nil {
g.zones = map[string]*gdns.ManagedZone{} g.zones = map[string]*gdns.ManagedZone{}
pageToken := "" pageToken := ""
for { for {
resp, err := g.client.ManagedZones.List(g.project).PageToken(pageToken).Do() resp, err := g.client.ManagedZones.List(g.project).PageToken(pageToken).Do()
if err != nil { if err != nil {
return nil, err return err
} }
for _, z := range resp.ManagedZones { for _, z := range resp.ManagedZones {
g.zones[z.DnsName] = z g.zones[z.DnsName] = z
@ -98,10 +102,19 @@ func (g *gcloud) getZone(domain string) (*gdns.ManagedZone, error) {
break break
} }
} }
return nil
}
// ListZones returns the list of zones (domains) in this account.
func (g *gcloud) ListZones() ([]string, error) {
var zones []string
for i, _ := range g.zones {
zones = append(zones, strings.TrimSuffix(i, "."))
} }
if g.zones[domain+"."] == nil { return zones, nil
return nil, errNoExist{domain} }
}
func (g *gcloud) getZone(domain string) (*gdns.ManagedZone, error) {
return g.zones[domain+"."], nil return g.zones[domain+"."], nil
} }
@ -126,20 +139,15 @@ func keyForRec(r *models.RecordConfig) key {
} }
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format. // GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
func (client *gcloud) GetZoneRecords(domain string) (models.Records, error) { func (g *gcloud) GetZoneRecords(domain string) (models.Records, error) {
return nil, fmt.Errorf("not implemented") existingRecords, _, _, err := g.getZoneSets(domain)
// This enables the get-zones subcommand. return existingRecords, err
// Implement this by extracting the code from GetDomainCorrections into
// a single function. For most providers this should be relatively easy.
} }
func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { func (g *gcloud) getZoneSets(domain string) (models.Records, map[key]*gdns.ResourceRecordSet, string, error) {
if err := dc.Punycode(); err != nil { rrs, zoneName, err := g.getRecords(domain)
return nil, err
}
rrs, zoneName, err := g.getRecords(dc.Name)
if err != nil { if err != nil {
return nil, err return nil, nil, "", err
} }
// convert to dnscontrol RecordConfig format // convert to dnscontrol RecordConfig format
existingRecords := []*models.RecordConfig{} existingRecords := []*models.RecordConfig{}
@ -147,9 +155,20 @@ func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correc
for _, set := range rrs { for _, set := range rrs {
oldRRs[keyFor(set)] = set oldRRs[keyFor(set)] = set
for _, rec := range set.Rrdatas { for _, rec := range set.Rrdatas {
existingRecords = append(existingRecords, nativeToRecord(set, rec, dc.Name)) existingRecords = append(existingRecords, nativeToRecord(set, rec, domain))
} }
} }
return existingRecords, oldRRs, zoneName, err
}
func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
if err := dc.Punycode(); err != nil {
return nil, err
}
existingRecords, oldRRs, zoneName, err := g.getZoneSets(dc.Name)
if err != nil {
return nil, err
}
// Normalize // Normalize
models.PostProcessRecords(existingRecords) models.PostProcessRecords(existingRecords)