From 0e00ce7d5cf6bf1eef0de7722fda46fe682fb875 Mon Sep 17 00:00:00 2001 From: Daniel Portella Date: Thu, 9 Mar 2017 14:12:47 +0000 Subject: [PATCH] added support for powerdns4 Support for powerdns provider is called powerdns4 uses the same details of powerdns provider --- main.go | 1 + providers/powerdns4/powerdns4.go | 145 +++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 providers/powerdns4/powerdns4.go diff --git a/main.go b/main.go index c53ba1c..db33c72 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( _ "github.com/rancher/external-dns/providers/gandi" _ "github.com/rancher/external-dns/providers/pointhq" _ "github.com/rancher/external-dns/providers/powerdns" + _ "github.com/rancher/external-dns/providers/powerdns4" _ "github.com/rancher/external-dns/providers/rfc2136" _ "github.com/rancher/external-dns/providers/route53" "github.com/rancher/external-dns/utils" diff --git a/providers/powerdns4/powerdns4.go b/providers/powerdns4/powerdns4.go new file mode 100644 index 0000000..5ae1df3 --- /dev/null +++ b/providers/powerdns4/powerdns4.go @@ -0,0 +1,145 @@ +package powerdns4 + +import ( + "fmt" + "strings" + "os" + + "github.com/Sirupsen/logrus" + "github.com/dmportella/powerdns" + "github.com/rancher/external-dns/providers" + "github.com/rancher/external-dns/utils" +) + +type PdnsProvider struct { + client *powerdns.Client + root string +} + +func init() { + providers.RegisterProvider("powerdns4", &PdnsProvider{}) +} + +func (pdnsProvider *PdnsProvider) Init(rootDomainName string) error { + var url, apiKey string + if url = os.Getenv("POWERDNS_URL"); len(url) == 0 { + return fmt.Errorf("POWERDNS_URL is not set") + } + + if apiKey = os.Getenv("POWERDNS_API_KEY"); len(apiKey) == 0 { + return fmt.Errorf("POWERDNS_API_KEY is not set") + } + + pdnsProvider.root = utils.UnFqdn(rootDomainName) + + var client *powerdns.Client + client, err := powerdns.NewClient(url, apiKey); + if err != nil { + return fmt.Errorf("Failed to connect to '%s': %v", pdnsProvider.root, err) + } + pdnsProvider.client = client + + logrus.Infof("Configured %s with zone '%s'", pdnsProvider.GetName(), pdnsProvider.root) + return nil +} + +func (*PdnsProvider) GetName() string { + return "powerdns4" +} + +func (pdnsProvider *PdnsProvider) HealthCheck() error { + if _, err := pdnsProvider.client.ListZones(); err != nil { + return fmt.Errorf("HealthCheck failed for '%s' with error '%s'.", pdnsProvider.GetName(), err) + } + return nil +} + +func (pdnsProvider *PdnsProvider) AddRecord(record utils.DnsRecord) error { + logrus.Debugf("Called AddRecord with: %v\n", record) + + return pdnsProvider.UpdateRecord(record) +} + +func (pdnsProvider *PdnsProvider) UpdateRecord(record utils.DnsRecord) error { + logrus.Debugf("Called UpdateRecord with: %v\n", record) + + rrSet := powerdns.ResourceRecordSet{ + Name: record.Fqdn, + Type: record.Type, + ChangeType: "REPLACE", + TTL: record.TTL, + } + + records := make([]powerdns.Record, 0) + for _, rec := range record.Records { + if record.Type == "TXT" { + rec = fmt.Sprintf("\"%s\"", rec) + } + + records = append(records, powerdns.Record{ + Content: rec, + }) + } + + rrSet.Records = records + + recordID, err := pdnsProvider.client.ReplaceRecordSet(pdnsProvider.root, rrSet) + if err != nil { + return fmt.Errorf("Failed to add '%s' record on '%s': %v", record.Fqdn, pdnsProvider.root, err) + } + + logrus.Infof("Added '%s' record on '%s'", recordID, pdnsProvider.root) + + return nil +} + +func (pdnsProvider *PdnsProvider) RemoveRecord(record utils.DnsRecord) error { + logrus.Debugf("Called RemoveRecord with: %v\n", record) + + found, err := pdnsProvider.client.RecordExists(pdnsProvider.root, record.Fqdn, record.Type) + if err != nil { + return fmt.Errorf("Failed to remove '%s' record on '%s': %v", record.Fqdn, pdnsProvider.root, err) + } + + if !found { + return nil + } + + + return pdnsProvider.client.DeleteRecordSet(pdnsProvider.root, record.Fqdn, record.Type) +} + +func (pdnsProvider *PdnsProvider) GetRecords() ([]utils.DnsRecord, error) { + logrus.Debugf("Called GetRecords") + + rrSets, err := pdnsProvider.client.ListRecordsAsRRSet(pdnsProvider.root) + if err != nil { + return nil, fmt.Errorf("Failed getting records in zone '%s': %v", pdnsProvider.root, err) + } + + result := make([]utils.DnsRecord, 0) + + for _, rrSet := range rrSets { + rancherRec := utils.DnsRecord{ + Fqdn: rrSet.Name, + Type: rrSet.Type, + TTL: rrSet.TTL, + Records: []string{}, + } + + records := make([]string, 0) + for _, rec := range rrSet.Records { + if rancherRec.Type == "TXT" { + rec.Content = strings.Replace(rec.Content, "\"", "", -1) + } + + records = append(records, rec.Content) + } + + rancherRec.Records = records + + result = append(result, rancherRec) + } + + return result, nil +} \ No newline at end of file