Skip to content

Commit

Permalink
Merge pull request #86 from loganhz/master
Browse files Browse the repository at this point in the history
Support Aliyun DNS
  • Loading branch information
janeczku authored Aug 22, 2017
2 parents c2e9dee + 4a0f35d commit 8ce04fb
Show file tree
Hide file tree
Showing 41 changed files with 4,026 additions and 0 deletions.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/rancher/external-dns/config"
"github.com/rancher/external-dns/metadata"
"github.com/rancher/external-dns/providers"
_ "github.com/rancher/external-dns/providers/alidns"
_ "github.com/rancher/external-dns/providers/cloudflare"
_ "github.com/rancher/external-dns/providers/digitalocean"
_ "github.com/rancher/external-dns/providers/dnsimple"
Expand Down
173 changes: 173 additions & 0 deletions providers/alidns/alidns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package alidns

import (
"fmt"
"os"
"strings"

"github.com/Sirupsen/logrus"
api "github.com/denverdino/aliyungo/dns"
"github.com/rancher/external-dns/providers"
"github.com/rancher/external-dns/utils"
)

type AlidnsProvider struct {
client *api.Client
rootDomainName string
}

func init() {
providers.RegisterProvider("alidns", &AlidnsProvider{})
}

func (a *AlidnsProvider) Init(rootDomainName string) error {
accessKey := os.Getenv("ALICLOUD_ACCESS_KEY_ID")
if len(accessKey) == 0 {
return fmt.Errorf("ALICLOUD_ACCESS_KEY_ID is not set")
}

secretKey := os.Getenv("ALICLOUD_ACCESS_KEY_SECRET")
if len(secretKey) == 0 {
return fmt.Errorf("ALICLOUD_ACCESS_KEY_SECRET is not set")
}

a.client = api.NewClient(accessKey, secretKey)
a.rootDomainName = utils.UnFqdn(rootDomainName)

if _, err := a.client.DescribeDomainInfo(&api.DescribeDomainInfoArgs{
DomainName: a.rootDomainName,
}); err != nil {
return fmt.Errorf("Failed to describe root domain name for '%s': %v", a.rootDomainName, err)
}

logrus.Infof("Configured %s with zone '%s'", a.GetName(), a.rootDomainName)
return nil
}

func (a *AlidnsProvider) GetName() string {
return "AliDNS"
}

func (a *AlidnsProvider) HealthCheck() error {
_, err := a.client.DescribeDomainInfo(&api.DescribeDomainInfoArgs{
DomainName: a.rootDomainName,
})
return err
}

func (a *AlidnsProvider) AddRecord(record utils.DnsRecord) error {
for _, rec := range record.Records {
r := a.prepareRecord(record, rec)
if _, err := a.client.AddDomainRecord(r); err != nil {
return fmt.Errorf("Alibaba Cloud API call has failed: %v", err)
}
}

return nil
}

func (a *AlidnsProvider) UpdateRecord(record utils.DnsRecord) error {
if err := a.RemoveRecord(record); err != nil {
return err
}

return a.AddRecord(record)
}

func (a *AlidnsProvider) RemoveRecord(record utils.DnsRecord) error {
records, err := a.findRecords(record)
if err != nil {
return err
}

for _, rec := range records {
if _, err := a.client.DeleteDomainRecord(&api.DeleteDomainRecordArgs{
RecordId: rec.RecordId,
}); err != nil {
return fmt.Errorf("Alibaba Cloud API call has failed: %v", err)
}
}

return nil
}

func (a *AlidnsProvider) GetRecords() ([]utils.DnsRecord, error) {
var records []utils.DnsRecord
result, err := a.client.DescribeDomainRecords(&api.DescribeDomainRecordsArgs{
DomainName: a.rootDomainName,
})
if err != nil {
return records, fmt.Errorf("Alibaba Cloud API call has failed: %v", err)
}

recordMap := map[string]map[string][]string{}
recordTTLs := map[string]map[string]int{}

for _, rec := range result.DomainRecords.Record {
var fqdn string
if rec.RR == "" {
fqdn = a.rootDomainName + "."
} else {
fqdn = fmt.Sprintf("%s.%s.", rec.RR, a.rootDomainName)
}

recordTTLs[fqdn] = map[string]int{}
recordTTLs[fqdn][rec.Type] = int(rec.TTL)
recordSet, exists := recordMap[fqdn]
if exists {
recordSlice, sliceExists := recordSet[rec.Type]
if sliceExists {
recordSlice = append(recordSlice, rec.Value)
recordSet[rec.Type] = recordSlice
} else {
recordSet[rec.Type] = []string{rec.Value}
}
} else {
recordMap[fqdn] = map[string][]string{}
recordMap[fqdn][rec.Type] = []string{rec.Value}
}
}

for fqdn, recordSet := range recordMap {
for recordType, recordSlice := range recordSet {
ttl := recordTTLs[fqdn][recordType]
record := utils.DnsRecord{Fqdn: fqdn, Records: recordSlice, Type: recordType, TTL: ttl}
records = append(records, record)
}
}

return records, nil
}

func (a *AlidnsProvider) parseName(record utils.DnsRecord) string {
return strings.TrimSuffix(record.Fqdn, fmt.Sprintf(".%s.", a.rootDomainName))
}

func (a *AlidnsProvider) prepareRecord(record utils.DnsRecord, rec string) *api.AddDomainRecordArgs {
return &api.AddDomainRecordArgs{
DomainName: a.rootDomainName,
RR: a.parseName(record),
Type: record.Type,
Value: rec,
TTL: int32(record.TTL),
}
}

func (a *AlidnsProvider) findRecords(record utils.DnsRecord) ([]api.RecordType, error) {
var records []api.RecordType
result, err := a.client.DescribeDomainRecords(&api.DescribeDomainRecordsArgs{
DomainName: a.rootDomainName,
})
if err != nil {
return records, fmt.Errorf("Alibaba Cloud API call has failed: %v", err)
}

name := a.parseName(record)
for _, rec := range result.DomainRecords.Record {
if rec.RR == name && rec.Type == record.Type {
records = append(records, rec)
}
}

return records, nil
}
1 change: 1 addition & 0 deletions vendor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ github.com/cognetoapps/go-pointdns 0.1.0
github.com/crackcomm/cloudflare dc35819
github.com/dghubble/sling 5765fe1
github.com/digitalocean/godo 758b5be
github.com/denverdino/aliyungo 26fc5b6
github.com/go-ini/ini v1.21.1
github.com/google/go-querystring/query 9235644
github.com/gorilla/context 1c83b3e
Expand Down
1 change: 1 addition & 0 deletions vendor/github.com/denverdino/aliyungo/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions vendor/github.com/denverdino/aliyungo/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

191 changes: 191 additions & 0 deletions vendor/github.com/denverdino/aliyungo/LICENSE.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8ce04fb

Please sign in to comment.