diff options
Diffstat (limited to 'vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go')
-rw-r--r-- | vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go b/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go new file mode 100644 index 000000000..55b48f9b4 --- /dev/null +++ b/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go @@ -0,0 +1,141 @@ +package auroradns + +import ( + "fmt" + "github.com/edeckers/auroradnsclient" + "github.com/edeckers/auroradnsclient/records" + "github.com/edeckers/auroradnsclient/zones" + "github.com/xenolf/lego/acme" + "os" + "sync" +) + +// DNSProvider describes a provider for AuroraDNS +type DNSProvider struct { + recordIDs map[string]string + recordIDsMu sync.Mutex + client *auroradnsclient.AuroraDNSClient +} + +// NewDNSProvider returns a DNSProvider instance configured for AuroraDNS. +// Credentials must be passed in the environment variables: AURORA_USER_ID +// and AURORA_KEY. +func NewDNSProvider() (*DNSProvider, error) { + userID := os.Getenv("AURORA_USER_ID") + key := os.Getenv("AURORA_KEY") + + endpoint := os.Getenv("AURORA_ENDPOINT") + if endpoint == "" { + endpoint = "https://api.auroradns.eu" + } + + return NewDNSProviderCredentials(endpoint, userID, key) +} + +// NewDNSProviderCredentials uses the supplied credentials to return a +// DNSProvider instance configured for AuroraDNS. +func NewDNSProviderCredentials(baseURL string, userID string, key string) (*DNSProvider, error) { + client, err := auroradnsclient.NewAuroraDNSClient(baseURL, userID, key) + if err != nil { + return nil, err + } + + return &DNSProvider{ + client: client, + recordIDs: make(map[string]string), + }, nil +} + +func (provider *DNSProvider) getZoneInformationByName(name string) (zones.ZoneRecord, error) { + zs, err := provider.client.GetZones() + + if err != nil { + return zones.ZoneRecord{}, err + } + + for _, element := range zs { + if element.Name == name { + return element, nil + } + } + + return zones.ZoneRecord{}, fmt.Errorf("Could not find Zone record") +} + +// Present creates a record with a secret +func (provider *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value, _ := acme.DNS01Record(domain, keyAuth) + + authZone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers) + if err != nil { + return fmt.Errorf("Could not determine zone for domain: '%s'. %s", domain, err) + } + + // 1. Aurora will happily create the TXT record when it is provided a fqdn, + // but it will only appear in the control panel and will not be + // propagated to DNS servers. Extract and use subdomain instead. + // 2. A trailing dot in the fqdn will cause Aurora to add a trailing dot to + // the subdomain, resulting in _acme-challenge..<domain> rather + // than _acme-challenge.<domain> + + subdomain := fqdn[0 : len(fqdn)-len(authZone)-1] + + authZone = acme.UnFqdn(authZone) + + zoneRecord, err := provider.getZoneInformationByName(authZone) + + reqData := + records.CreateRecordRequest{ + RecordType: "TXT", + Name: subdomain, + Content: value, + TTL: 300, + } + + respData, err := provider.client.CreateRecord(zoneRecord.ID, reqData) + if err != nil { + return fmt.Errorf("Could not create record: '%s'.", err) + } + + provider.recordIDsMu.Lock() + provider.recordIDs[fqdn] = respData.ID + provider.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes a given record that was generated by Present +func (provider *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _, _ := acme.DNS01Record(domain, keyAuth) + + provider.recordIDsMu.Lock() + recordID, ok := provider.recordIDs[fqdn] + provider.recordIDsMu.Unlock() + + if !ok { + return fmt.Errorf("Unknown recordID for '%s'", fqdn) + } + + authZone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers) + if err != nil { + return fmt.Errorf("Could not determine zone for domain: '%s'. %s", domain, err) + } + + authZone = acme.UnFqdn(authZone) + + zoneRecord, err := provider.getZoneInformationByName(authZone) + if err != nil { + return err + } + + _, err = provider.client.RemoveRecord(zoneRecord.ID, recordID) + if err != nil { + return err + } + + provider.recordIDsMu.Lock() + delete(provider.recordIDs, fqdn) + provider.recordIDsMu.Unlock() + + return nil +} |