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

Seperate create-domains command (#21)

* removing auto-create from gcloud

* adding create-domains command

* implement DomainCreator for r53
This commit is contained in:
Craig Peterson
2017-01-03 13:26:08 -07:00
committed by GitHub
parent e18d4f9b2e
commit 20bf7ef43b
4 changed files with 74 additions and 52 deletions

17
main.go
View File

@@ -133,6 +133,23 @@ func main() {
fmt.Printf("Initialized %d registrars and %d dns service providers.\n", len(registrars), len(dsps))
anyErrors, totalCorrections := false, 0
switch command {
case "create-domains":
for _, domain := range dnsConfig.Domains {
fmt.Println("*** ", domain.Name)
for prov := range domain.DNSProviders {
dsp, ok := dsps[prov]
if !ok {
log.Fatalf("DSP %s not declared.", prov)
}
if creator, ok := dsp.(providers.DomainCreator); ok {
fmt.Println(" -", prov)
err := creator.EnsureDomainExists(domain.Name)
if err != nil {
fmt.Printf("Error creating domain: %s\n", err)
}
}
}
}
case "preview", "push":
DomainLoop:
for _, domain := range dnsConfig.Domains {

View File

@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"log"
"strings"
"golang.org/x/oauth2"
@@ -86,10 +85,6 @@ func (g *gcloud) getZone(domain string) (*dns.ManagedZone, error) {
func (g *gcloud) GetNameservers(domain string) ([]*models.Nameserver, error) {
zone, err := g.getZone(domain)
if err != nil {
if _, ok := err.(errNoExist); ok {
log.Printf("WARNING: Domain %s is not on your google cloud account. Dnscontrol will add it, but you will need to run a second time to configure nameservers properly.", domain)
return nil, nil
}
return nil, err
}
return models.StringsToNameservers(zone.NameServers), nil
@@ -108,16 +103,10 @@ func keyForRec(r *models.RecordConfig) key {
}
func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
corrections := []*models.Correction{}
rrs, zoneName, err := g.getRecords(dc.Name)
if err != nil {
if _, ok := err.(errNoExist); ok {
c, zn := g.addZone(dc.Name)
corrections = append(corrections, c)
zoneName = zn
} else {
return nil, err
}
return nil, err
}
//convert to dnscontrol RecordConfig format
existingRecords := []diff.Record{}
@@ -200,11 +189,10 @@ func (g *gcloud) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correc
_, err := g.client.Changes.Create(g.project, zoneName, chg).Do()
return err
}
corrections = append(corrections, &models.Correction{
return []*models.Correction{{
Msg: desc,
F: runChange,
})
return corrections, nil
}}, nil
}
func (g *gcloud) getRecords(domain string) ([]*dns.ResourceRecordSet, string, error) {
@@ -236,19 +224,23 @@ func (g *gcloud) getRecords(domain string) ([]*dns.ResourceRecordSet, string, er
return sets, zone.Name, nil
}
func (g *gcloud) addZone(name string) (*models.Correction, string) {
mz := &dns.ManagedZone{}
mz.DnsName = name + "."
mz.Name = strings.Replace(name, ".", "-", -1)
mz.Description = "zone added by dnscontrol"
return &models.Correction{
Msg: fmt.Sprintf("Add zone for %s", name),
F: func() error {
_, err := g.client.ManagedZones.Create(g.project, mz).Do()
if err != nil {
return err
}
return nil
},
}, mz.Name
func (g *gcloud) EnsureDomainExists(domain string) error {
z, err := g.getZone(domain)
if err != nil {
if _, ok := err.(errNoExist); !ok {
return err
}
}
if z != nil {
return nil
}
fmt.Printf("Adding zone for %s to gcloud account\n", domain)
mz := &dns.ManagedZone{
DnsName: domain + ".",
Name: strings.Replace(domain, ".", "-", -1),
Description: "zone added by dnscontrol",
}
g.zones = nil //reset cache
_, err = g.client.ManagedZones.Create(g.project, mz).Do()
return err
}

View File

@@ -19,6 +19,12 @@ type DNSServiceProvider interface {
GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error)
}
//DomainCreator should be implemented by providers that have the ability to add domains to an account. the create-domains command
//can be run to ensure all domains are present before running preview/push
type DomainCreator interface {
EnsureDomainExists(domain string) error
}
//RegistrarInitializer is a function to create a registrar. Function will be passed the unprocessed json payload from the configuration file for the given provider.
type RegistrarInitializer func(map[string]string) (Registrar, error)

View File

@@ -3,7 +3,6 @@ package route53
import (
"encoding/json"
"fmt"
"log"
"strings"
"time"
@@ -78,14 +77,21 @@ func getKey(r diff.Record) key {
return key{r.GetName(), r.GetType()}
}
type errNoExist struct {
domain string
}
func (e errNoExist) Error() string {
return fmt.Sprintf("Domain %s not found in your route 53 account", e.domain)
}
func (r *route53Provider) GetNameservers(domain string) ([]*models.Nameserver, error) {
if err := r.getZones(); err != nil {
return nil, err
}
zone, ok := r.zones[domain]
if !ok {
log.Printf("WARNING: Domain %s is not on your route 53 account. Dnscontrol will add it, but you will need to run a second time to configure nameservers properly.", domain)
return nil, nil
return nil, errNoExist{domain}
}
z, err := r.client.GetHostedZone(&r53.GetHostedZoneInput{Id: zone.Id})
if err != nil {
@@ -107,24 +113,7 @@ func (r *route53Provider) GetDomainCorrections(dc *models.DomainConfig) ([]*mode
zone, ok := r.zones[dc.Name]
// add zone if it doesn't exist
if !ok {
//add correction to add zone
corrections = append(corrections,
&models.Correction{
Msg: "Add zone to aws",
F: func() error {
in := &r53.CreateHostedZoneInput{
Name: &dc.Name,
CallerReference: sPtr(fmt.Sprint(time.Now().UnixNano())),
}
out, err := r.client.CreateHostedZone(in)
zone = out.HostedZone
return err
},
})
//fake zone
zone = &r53.HostedZone{
Id: sPtr(""),
}
return nil, errNoExist{dc.Name}
}
records, err := r.fetchRecordSets(zone.Id)
@@ -285,3 +274,21 @@ func unescape(s *string) string {
name = strings.Replace(name, `\052`, "*", -1) //TODO: escape all octal sequences
return name
}
func (r *route53Provider) EnsureDomainExists(domain string) error {
err := r.getZones()
if err != nil {
return err
}
if _, ok := r.zones[domain]; ok {
return nil
}
fmt.Printf("Adding zone for %s to route 53 account\n", domain)
in := &r53.CreateHostedZoneInput{
Name: &domain,
CallerReference: sPtr(fmt.Sprint(time.Now().UnixNano())),
}
_, err = r.client.CreateHostedZone(in)
return err
}