summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/xenolf/lego/providers/dns
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/xenolf/lego/providers/dns')
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go141
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns_test.go148
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/azure/azure.go151
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/azure/azure_test.go89
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go223
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare_test.go80
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go166
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean_test.go117
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dns_providers.go86
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dns_providers_test.go50
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple.go180
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple_test.go140
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go248
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go37
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go146
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod_test.go72
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dyn/dyn.go274
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/dyn/dyn_test.go53
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go128
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale_test.go103
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/gandi/gandi.go472
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/gandi/gandi_test.go939
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy.go155
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy_test.go60
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go205
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud_test.go99
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/linode/linode.go131
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/linode/linode_test.go317
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go416
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap_test.go402
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/ns1/ns1.go97
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/ns1/ns1_test.go67
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/otc/mock.go152
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/otc/otc.go388
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/otc/otc_test.go112
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/ovh/ovh.go159
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/ovh/ovh_test.go103
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/pdns/README.md7
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go343
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/pdns/pdns_test.go80
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go284
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace_test.go220
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go152
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go244
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/fixtures_test.go39
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53.go185
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53_integration_test.go70
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go105
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/testutil_test.go38
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go127
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/vultr/vultr_test.go65
51 files changed, 0 insertions, 8865 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
deleted file mode 100644
index 55b48f9b4..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns.go
+++ /dev/null
@@ -1,141 +0,0 @@
-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
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns_test.go b/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns_test.go
deleted file mode 100644
index f4df7fa61..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/auroradns/auroradns_test.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package auroradns
-
-import (
- "fmt"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-var fakeAuroraDNSUserId = "asdf1234"
-var fakeAuroraDNSKey = "key"
-
-func TestAuroraDNSPresent(t *testing.T) {
- var requestReceived bool
-
- mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "GET" && r.URL.Path == "/zones" {
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `[{
- "id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
- "name": "example.com"
- }]`)
- return
- }
-
- requestReceived = true
-
- if got, want := r.Method, "POST"; got != want {
- t.Errorf("Expected method to be '%s' but got '%s'", want, got)
- }
-
- if got, want := r.URL.Path, "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records"; got != want {
- t.Errorf("Expected path to be '%s' but got '%s'", want, got)
- }
-
- if got, want := r.Header.Get("Content-Type"), "application/json"; got != want {
- t.Errorf("Expected Content-Type to be '%s' but got '%s'", want, got)
- }
-
- reqBody, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Fatalf("Error reading request body: %v", err)
- }
-
- if got, want := string(reqBody),
- `{"type":"TXT","name":"_acme-challenge","content":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":300}`; got != want {
-
- t.Errorf("Expected body data to be: `%s` but got `%s`", want, got)
- }
-
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `{
- "id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
- "type": "TXT",
- "name": "_acme-challenge",
- "ttl": 300
- }`)
- }))
-
- defer mock.Close()
-
- auroraProvider, err := NewDNSProviderCredentials(mock.URL, fakeAuroraDNSUserId, fakeAuroraDNSKey)
- if auroraProvider == nil {
- t.Fatal("Expected non-nil AuroraDNS provider, but was nil")
- }
-
- if err != nil {
- t.Fatalf("Expected no error creating provider, but got: %v", err)
- }
-
- err = auroraProvider.Present("example.com", "", "foobar")
- if err != nil {
- t.Fatalf("Expected no error creating TXT record, but got: %v", err)
- }
-
- if !requestReceived {
- t.Error("Expected request to be received by mock backend, but it wasn't")
- }
-}
-
-func TestAuroraDNSCleanUp(t *testing.T) {
- var requestReceived bool
-
- mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "GET" && r.URL.Path == "/zones" {
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `[{
- "id": "c56a4180-65aa-42ec-a945-5fd21dec0538",
- "name": "example.com"
- }]`)
- return
- }
-
- if r.Method == "POST" && r.URL.Path == "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records" {
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `{
- "id": "ec56a4180-65aa-42ec-a945-5fd21dec0538",
- "type": "TXT",
- "name": "_acme-challenge",
- "ttl": 300
- }`)
- return
- }
-
- requestReceived = true
-
- if got, want := r.Method, "DELETE"; got != want {
- t.Errorf("Expected method to be '%s' but got '%s'", want, got)
- }
-
- if got, want := r.URL.Path,
- "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records/ec56a4180-65aa-42ec-a945-5fd21dec0538"; got != want {
- t.Errorf("Expected path to be '%s' but got '%s'", want, got)
- }
-
- if got, want := r.Header.Get("Content-Type"), "application/json"; got != want {
- t.Errorf("Expected Content-Type to be '%s' but got '%s'", want, got)
- }
-
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `{}`)
- }))
- defer mock.Close()
-
- auroraProvider, err := NewDNSProviderCredentials(mock.URL, fakeAuroraDNSUserId, fakeAuroraDNSKey)
- if auroraProvider == nil {
- t.Fatal("Expected non-nil AuroraDNS provider, but was nil")
- }
-
- if err != nil {
- t.Fatalf("Expected no error creating provider, but got: %v", err)
- }
-
- err = auroraProvider.Present("example.com", "", "foobar")
- if err != nil {
- t.Fatalf("Expected no error creating TXT record, but got: %v", err)
- }
-
- err = auroraProvider.CleanUp("example.com", "", "foobar")
- if err != nil {
- t.Fatalf("Expected no error removing TXT record, but got: %v", err)
- }
-
- if !requestReceived {
- t.Error("Expected request to be received by mock backend, but it wasn't")
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go b/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go
deleted file mode 100644
index 6a30b318a..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/azure/azure.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Package azure implements a DNS provider for solving the DNS-01
-// challenge using azure DNS.
-// Azure doesn't like trailing dots on domain names, most of the acme code does.
-package azure
-
-import (
- "fmt"
- "os"
- "time"
-
- "github.com/Azure/azure-sdk-for-go/arm/dns"
-
- "strings"
-
- "github.com/Azure/go-autorest/autorest"
- "github.com/Azure/go-autorest/autorest/adal"
- "github.com/Azure/go-autorest/autorest/azure"
- "github.com/Azure/go-autorest/autorest/to"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-type DNSProvider struct {
- clientId string
- clientSecret string
- subscriptionId string
- tenantId string
- resourceGroup string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for azure.
-// Credentials must be passed in the environment variables: AZURE_CLIENT_ID,
-// AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_RESOURCE_GROUP
-func NewDNSProvider() (*DNSProvider, error) {
- clientId := os.Getenv("AZURE_CLIENT_ID")
- clientSecret := os.Getenv("AZURE_CLIENT_SECRET")
- subscriptionId := os.Getenv("AZURE_SUBSCRIPTION_ID")
- tenantId := os.Getenv("AZURE_TENANT_ID")
- resourceGroup := os.Getenv("AZURE_RESOURCE_GROUP")
- return NewDNSProviderCredentials(clientId, clientSecret, subscriptionId, tenantId, resourceGroup)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for azure.
-func NewDNSProviderCredentials(clientId, clientSecret, subscriptionId, tenantId, resourceGroup string) (*DNSProvider, error) {
- if clientId == "" || clientSecret == "" || subscriptionId == "" || tenantId == "" || resourceGroup == "" {
- return nil, fmt.Errorf("Azure configuration missing")
- }
-
- return &DNSProvider{
- clientId: clientId,
- clientSecret: clientSecret,
- subscriptionId: subscriptionId,
- tenantId: tenantId,
- resourceGroup: resourceGroup,
- }, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Adjusting here to cope with spikes in propagation times.
-func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 120 * time.Second, 2 * time.Second
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zone, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return err
- }
-
- rsc := dns.NewRecordSetsClient(c.subscriptionId)
- spt, err := c.newServicePrincipalTokenFromCredentials(azure.PublicCloud.ResourceManagerEndpoint)
- rsc.Authorizer = autorest.NewBearerAuthorizer(spt)
-
- relative := toRelativeRecord(fqdn, acme.ToFqdn(zone))
- rec := dns.RecordSet{
- Name: &relative,
- RecordSetProperties: &dns.RecordSetProperties{
- TTL: to.Int64Ptr(60),
- TxtRecords: &[]dns.TxtRecord{dns.TxtRecord{Value: &[]string{value}}},
- },
- }
- _, err = rsc.CreateOrUpdate(c.resourceGroup, zone, relative, dns.TXT, rec, "", "")
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Returns the relative record to the domain
-func toRelativeRecord(domain, zone string) string {
- return acme.UnFqdn(strings.TrimSuffix(domain, zone))
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return err
- }
-
- relative := toRelativeRecord(fqdn, acme.ToFqdn(zone))
- rsc := dns.NewRecordSetsClient(c.subscriptionId)
- spt, err := c.newServicePrincipalTokenFromCredentials(azure.PublicCloud.ResourceManagerEndpoint)
- rsc.Authorizer = autorest.NewBearerAuthorizer(spt)
- _, err = rsc.Delete(c.resourceGroup, zone, relative, dns.TXT, "")
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Checks that azure has a zone for this domain name.
-func (c *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- // Now we want to to Azure and get the zone.
- spt, err := c.newServicePrincipalTokenFromCredentials(azure.PublicCloud.ResourceManagerEndpoint)
-
- dc := dns.NewZonesClient(c.subscriptionId)
- dc.Authorizer = autorest.NewBearerAuthorizer(spt)
-
- zone, err := dc.Get(c.resourceGroup, acme.UnFqdn(authZone))
-
- if err != nil {
- return "", err
- }
-
- // zone.Name shouldn't have a trailing dot(.)
- return to.String(zone.Name), nil
-}
-
-// NewServicePrincipalTokenFromCredentials creates a new ServicePrincipalToken using values of the
-// passed credentials map.
-func (c *DNSProvider) newServicePrincipalTokenFromCredentials(scope string) (*adal.ServicePrincipalToken, error) {
- oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, c.tenantId)
- if err != nil {
- panic(err)
- }
- return adal.NewServicePrincipalToken(*oauthConfig, c.clientId, c.clientSecret, scope)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/azure/azure_test.go b/vendor/github.com/xenolf/lego/providers/dns/azure/azure_test.go
deleted file mode 100644
index db55f578a..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/azure/azure_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package azure
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- azureLiveTest bool
- azureClientID string
- azureClientSecret string
- azureSubscriptionID string
- azureTenantID string
- azureResourceGroup string
- azureDomain string
-)
-
-func init() {
- azureClientID = os.Getenv("AZURE_CLIENT_ID")
- azureClientSecret = os.Getenv("AZURE_CLIENT_SECRET")
- azureSubscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID")
- azureTenantID = os.Getenv("AZURE_TENANT_ID")
- azureResourceGroup = os.Getenv("AZURE_RESOURCE_GROUP")
- azureDomain = os.Getenv("AZURE_DOMAIN")
- if len(azureClientID) > 0 && len(azureClientSecret) > 0 {
- azureLiveTest = true
- }
-}
-
-func restoreAzureEnv() {
- os.Setenv("AZURE_CLIENT_ID", azureClientID)
- os.Setenv("AZURE_SUBSCRIPTION_ID", azureSubscriptionID)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- if !azureLiveTest {
- t.Skip("skipping live test (requires credentials)")
- }
- os.Setenv("AZURE_CLIENT_ID", "")
- _, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azureSubscriptionID, azureTenantID, azureResourceGroup)
- assert.NoError(t, err)
- restoreAzureEnv()
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- if !azureLiveTest {
- t.Skip("skipping live test (requires credentials)")
- }
- os.Setenv("AZURE_CLIENT_ID", "other")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restoreAzureEnv()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("AZURE_SUBSCRIPTION_ID", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "Azure configuration missing")
- restoreAzureEnv()
-}
-
-func TestLiveAzurePresent(t *testing.T) {
- if !azureLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azureSubscriptionID, azureTenantID, azureResourceGroup)
- assert.NoError(t, err)
-
- err = provider.Present(azureDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveAzureCleanUp(t *testing.T) {
- if !azureLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(azureClientID, azureClientSecret, azureSubscriptionID, azureTenantID, azureResourceGroup)
- time.Sleep(time.Second * 1)
-
- assert.NoError(t, err)
-
- err = provider.CleanUp(azureDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go b/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go
deleted file mode 100644
index 84952238d..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Package cloudflare implements a DNS provider for solving the DNS-01
-// challenge using cloudflare DNS.
-package cloudflare
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "os"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// CloudFlareAPIURL represents the API endpoint to call.
-// TODO: Unexport?
-const CloudFlareAPIURL = "https://api.cloudflare.com/client/v4"
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-type DNSProvider struct {
- authEmail string
- authKey string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for cloudflare.
-// Credentials must be passed in the environment variables: CLOUDFLARE_EMAIL
-// and CLOUDFLARE_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- email := os.Getenv("CLOUDFLARE_EMAIL")
- key := os.Getenv("CLOUDFLARE_API_KEY")
- return NewDNSProviderCredentials(email, key)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for cloudflare.
-func NewDNSProviderCredentials(email, key string) (*DNSProvider, error) {
- if email == "" || key == "" {
- return nil, fmt.Errorf("CloudFlare credentials missing")
- }
-
- return &DNSProvider{
- authEmail: email,
- authKey: key,
- }, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Adjusting here to cope with spikes in propagation times.
-func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 120 * time.Second, 2 * time.Second
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zoneID, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return err
- }
-
- rec := cloudFlareRecord{
- Type: "TXT",
- Name: acme.UnFqdn(fqdn),
- Content: value,
- TTL: 120,
- }
-
- body, err := json.Marshal(rec)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("POST", fmt.Sprintf("/zones/%s/dns_records", zoneID), bytes.NewReader(body))
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- record, err := c.findTxtRecord(fqdn)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("DELETE", fmt.Sprintf("/zones/%s/dns_records/%s", record.ZoneID, record.ID), nil)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (c *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
- // HostedZone represents a CloudFlare DNS zone
- type HostedZone struct {
- ID string `json:"id"`
- Name string `json:"name"`
- }
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- result, err := c.makeRequest("GET", "/zones?name="+acme.UnFqdn(authZone), nil)
- if err != nil {
- return "", err
- }
-
- var hostedZone []HostedZone
- err = json.Unmarshal(result, &hostedZone)
- if err != nil {
- return "", err
- }
-
- if len(hostedZone) != 1 {
- return "", fmt.Errorf("Zone %s not found in CloudFlare for domain %s", authZone, fqdn)
- }
-
- return hostedZone[0].ID, nil
-}
-
-func (c *DNSProvider) findTxtRecord(fqdn string) (*cloudFlareRecord, error) {
- zoneID, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return nil, err
- }
-
- result, err := c.makeRequest(
- "GET",
- fmt.Sprintf("/zones/%s/dns_records?per_page=1000&type=TXT&name=%s", zoneID, acme.UnFqdn(fqdn)),
- nil,
- )
- if err != nil {
- return nil, err
- }
-
- var records []cloudFlareRecord
- err = json.Unmarshal(result, &records)
- if err != nil {
- return nil, err
- }
-
- for _, rec := range records {
- if rec.Name == acme.UnFqdn(fqdn) {
- return &rec, nil
- }
- }
-
- return nil, fmt.Errorf("No existing record found for %s", fqdn)
-}
-
-func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) {
- // APIError contains error details for failed requests
- type APIError struct {
- Code int `json:"code,omitempty"`
- Message string `json:"message,omitempty"`
- ErrorChain []APIError `json:"error_chain,omitempty"`
- }
-
- // APIResponse represents a response from CloudFlare API
- type APIResponse struct {
- Success bool `json:"success"`
- Errors []*APIError `json:"errors"`
- Result json.RawMessage `json:"result"`
- }
-
- req, err := http.NewRequest(method, fmt.Sprintf("%s%s", CloudFlareAPIURL, uri), body)
- if err != nil {
- return nil, err
- }
-
- req.Header.Set("X-Auth-Email", c.authEmail)
- req.Header.Set("X-Auth-Key", c.authKey)
- //req.Header.Set("User-Agent", userAgent())
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("Error querying Cloudflare API -> %v", err)
- }
-
- defer resp.Body.Close()
-
- var r APIResponse
- err = json.NewDecoder(resp.Body).Decode(&r)
- if err != nil {
- return nil, err
- }
-
- if !r.Success {
- if len(r.Errors) > 0 {
- errStr := ""
- for _, apiErr := range r.Errors {
- errStr += fmt.Sprintf("\t Error: %d: %s", apiErr.Code, apiErr.Message)
- for _, chainErr := range apiErr.ErrorChain {
- errStr += fmt.Sprintf("<- %d: %s", chainErr.Code, chainErr.Message)
- }
- }
- return nil, fmt.Errorf("Cloudflare API Error \n%s", errStr)
- }
- return nil, fmt.Errorf("Cloudflare API error")
- }
-
- return r.Result, nil
-}
-
-// cloudFlareRecord represents a CloudFlare DNS record
-type cloudFlareRecord struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Content string `json:"content"`
- ID string `json:"id,omitempty"`
- TTL int `json:"ttl,omitempty"`
- ZoneID string `json:"zone_id,omitempty"`
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare_test.go b/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare_test.go
deleted file mode 100644
index 19b5a40b9..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package cloudflare
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- cflareLiveTest bool
- cflareEmail string
- cflareAPIKey string
- cflareDomain string
-)
-
-func init() {
- cflareEmail = os.Getenv("CLOUDFLARE_EMAIL")
- cflareAPIKey = os.Getenv("CLOUDFLARE_API_KEY")
- cflareDomain = os.Getenv("CLOUDFLARE_DOMAIN")
- if len(cflareEmail) > 0 && len(cflareAPIKey) > 0 && len(cflareDomain) > 0 {
- cflareLiveTest = true
- }
-}
-
-func restoreCloudFlareEnv() {
- os.Setenv("CLOUDFLARE_EMAIL", cflareEmail)
- os.Setenv("CLOUDFLARE_API_KEY", cflareAPIKey)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- os.Setenv("CLOUDFLARE_EMAIL", "")
- os.Setenv("CLOUDFLARE_API_KEY", "")
- _, err := NewDNSProviderCredentials("123", "123")
- assert.NoError(t, err)
- restoreCloudFlareEnv()
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("CLOUDFLARE_EMAIL", "test@example.com")
- os.Setenv("CLOUDFLARE_API_KEY", "123")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restoreCloudFlareEnv()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("CLOUDFLARE_EMAIL", "")
- os.Setenv("CLOUDFLARE_API_KEY", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "CloudFlare credentials missing")
- restoreCloudFlareEnv()
-}
-
-func TestCloudFlarePresent(t *testing.T) {
- if !cflareLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey)
- assert.NoError(t, err)
-
- err = provider.Present(cflareDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestCloudFlareCleanUp(t *testing.T) {
- if !cflareLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 2)
-
- provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey)
- assert.NoError(t, err)
-
- err = provider.CleanUp(cflareDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go b/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go
deleted file mode 100644
index da261b39a..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Package digitalocean implements a DNS provider for solving the DNS-01
-// challenge using digitalocean DNS.
-package digitalocean
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "net/http"
- "os"
- "sync"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-// that uses DigitalOcean's REST API to manage TXT records for a domain.
-type DNSProvider struct {
- apiAuthToken string
- recordIDs map[string]int
- recordIDsMu sync.Mutex
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Digital
-// Ocean. Credentials must be passed in the environment variable:
-// DO_AUTH_TOKEN.
-func NewDNSProvider() (*DNSProvider, error) {
- apiAuthToken := os.Getenv("DO_AUTH_TOKEN")
- return NewDNSProviderCredentials(apiAuthToken)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Digital Ocean.
-func NewDNSProviderCredentials(apiAuthToken string) (*DNSProvider, error) {
- if apiAuthToken == "" {
- return nil, fmt.Errorf("DigitalOcean credentials missing")
- }
- return &DNSProvider{
- apiAuthToken: apiAuthToken,
- recordIDs: make(map[string]int),
- }, nil
-}
-
-// Present creates a TXT record using the specified parameters
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
- // txtRecordRequest represents the request body to DO's API to make a TXT record
- type txtRecordRequest struct {
- RecordType string `json:"type"`
- Name string `json:"name"`
- Data string `json:"data"`
- }
-
- // txtRecordResponse represents a response from DO's API after making a TXT record
- type txtRecordResponse struct {
- DomainRecord struct {
- ID int `json:"id"`
- Type string `json:"type"`
- Name string `json:"name"`
- Data string `json:"data"`
- } `json:"domain_record"`
- }
-
- 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)
- }
-
- authZone = acme.UnFqdn(authZone)
-
- reqURL := fmt.Sprintf("%s/v2/domains/%s/records", digitalOceanBaseURL, authZone)
- reqData := txtRecordRequest{RecordType: "TXT", Name: fqdn, Data: value}
- body, err := json.Marshal(reqData)
- if err != nil {
- return err
- }
-
- req, err := http.NewRequest("POST", reqURL, bytes.NewReader(body))
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", d.apiAuthToken))
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- var errInfo digitalOceanAPIError
- json.NewDecoder(resp.Body).Decode(&errInfo)
- return fmt.Errorf("HTTP %d: %s: %s", resp.StatusCode, errInfo.ID, errInfo.Message)
- }
-
- // Everything looks good; but we'll need the ID later to delete the record
- var respData txtRecordResponse
- err = json.NewDecoder(resp.Body).Decode(&respData)
- if err != nil {
- return err
- }
- d.recordIDsMu.Lock()
- d.recordIDs[fqdn] = respData.DomainRecord.ID
- d.recordIDsMu.Unlock()
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- // get the record's unique ID from when we created it
- d.recordIDsMu.Lock()
- recordID, ok := d.recordIDs[fqdn]
- d.recordIDsMu.Unlock()
- if !ok {
- return fmt.Errorf("unknown record ID 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)
-
- reqURL := fmt.Sprintf("%s/v2/domains/%s/records/%d", digitalOceanBaseURL, authZone, recordID)
- req, err := http.NewRequest("DELETE", reqURL, nil)
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", d.apiAuthToken))
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- var errInfo digitalOceanAPIError
- json.NewDecoder(resp.Body).Decode(&errInfo)
- return fmt.Errorf("HTTP %d: %s: %s", resp.StatusCode, errInfo.ID, errInfo.Message)
- }
-
- // Delete record ID from map
- d.recordIDsMu.Lock()
- delete(d.recordIDs, fqdn)
- d.recordIDsMu.Unlock()
-
- return nil
-}
-
-type digitalOceanAPIError struct {
- ID string `json:"id"`
- Message string `json:"message"`
-}
-
-var digitalOceanBaseURL = "https://api.digitalocean.com"
diff --git a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean_test.go b/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean_test.go
deleted file mode 100644
index 7498508ba..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/digitalocean/digitalocean_test.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package digitalocean
-
-import (
- "fmt"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-var fakeDigitalOceanAuth = "asdf1234"
-
-func TestDigitalOceanPresent(t *testing.T) {
- var requestReceived bool
-
- mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- requestReceived = true
-
- if got, want := r.Method, "POST"; got != want {
- t.Errorf("Expected method to be '%s' but got '%s'", want, got)
- }
- if got, want := r.URL.Path, "/v2/domains/example.com/records"; got != want {
- t.Errorf("Expected path to be '%s' but got '%s'", want, got)
- }
- if got, want := r.Header.Get("Content-Type"), "application/json"; got != want {
- t.Errorf("Expected Content-Type to be '%s' but got '%s'", want, got)
- }
- if got, want := r.Header.Get("Authorization"), "Bearer asdf1234"; got != want {
- t.Errorf("Expected Authorization to be '%s' but got '%s'", want, got)
- }
-
- reqBody, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Fatalf("Error reading request body: %v", err)
- }
- if got, want := string(reqBody), `{"type":"TXT","name":"_acme-challenge.example.com.","data":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI"}`; got != want {
- t.Errorf("Expected body data to be: `%s` but got `%s`", want, got)
- }
-
- w.WriteHeader(http.StatusCreated)
- fmt.Fprintf(w, `{
- "domain_record": {
- "id": 1234567,
- "type": "TXT",
- "name": "_acme-challenge",
- "data": "w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI",
- "priority": null,
- "port": null,
- "weight": null
- }
- }`)
- }))
- defer mock.Close()
- digitalOceanBaseURL = mock.URL
-
- doprov, err := NewDNSProviderCredentials(fakeDigitalOceanAuth)
- if doprov == nil {
- t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
- }
- if err != nil {
- t.Fatalf("Expected no error creating provider, but got: %v", err)
- }
-
- err = doprov.Present("example.com", "", "foobar")
- if err != nil {
- t.Fatalf("Expected no error creating TXT record, but got: %v", err)
- }
- if !requestReceived {
- t.Error("Expected request to be received by mock backend, but it wasn't")
- }
-}
-
-func TestDigitalOceanCleanUp(t *testing.T) {
- var requestReceived bool
-
- mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- requestReceived = true
-
- if got, want := r.Method, "DELETE"; got != want {
- t.Errorf("Expected method to be '%s' but got '%s'", want, got)
- }
- if got, want := r.URL.Path, "/v2/domains/example.com/records/1234567"; got != want {
- t.Errorf("Expected path to be '%s' but got '%s'", want, got)
- }
- // NOTE: Even though the body is empty, DigitalOcean API docs still show setting this Content-Type...
- if got, want := r.Header.Get("Content-Type"), "application/json"; got != want {
- t.Errorf("Expected Content-Type to be '%s' but got '%s'", want, got)
- }
- if got, want := r.Header.Get("Authorization"), "Bearer asdf1234"; got != want {
- t.Errorf("Expected Authorization to be '%s' but got '%s'", want, got)
- }
-
- w.WriteHeader(http.StatusNoContent)
- }))
- defer mock.Close()
- digitalOceanBaseURL = mock.URL
-
- doprov, err := NewDNSProviderCredentials(fakeDigitalOceanAuth)
- if doprov == nil {
- t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
- }
- if err != nil {
- t.Fatalf("Expected no error creating provider, but got: %v", err)
- }
-
- doprov.recordIDsMu.Lock()
- doprov.recordIDs["_acme-challenge.example.com."] = 1234567
- doprov.recordIDsMu.Unlock()
-
- err = doprov.CleanUp("example.com", "", "")
- if err != nil {
- t.Fatalf("Expected no error removing TXT record, but got: %v", err)
- }
- if !requestReceived {
- t.Error("Expected request to be received by mock backend, but it wasn't")
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go b/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
deleted file mode 100644
index d7530f788..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Factory for DNS providers
-package dns
-
-import (
- "fmt"
-
- "github.com/xenolf/lego/acme"
- "github.com/xenolf/lego/providers/dns/auroradns"
- "github.com/xenolf/lego/providers/dns/azure"
- "github.com/xenolf/lego/providers/dns/cloudflare"
- "github.com/xenolf/lego/providers/dns/digitalocean"
- "github.com/xenolf/lego/providers/dns/dnsimple"
- "github.com/xenolf/lego/providers/dns/dnsmadeeasy"
- "github.com/xenolf/lego/providers/dns/dnspod"
- "github.com/xenolf/lego/providers/dns/dyn"
- "github.com/xenolf/lego/providers/dns/exoscale"
- "github.com/xenolf/lego/providers/dns/gandi"
- "github.com/xenolf/lego/providers/dns/godaddy"
- "github.com/xenolf/lego/providers/dns/googlecloud"
- "github.com/xenolf/lego/providers/dns/linode"
- "github.com/xenolf/lego/providers/dns/namecheap"
- "github.com/xenolf/lego/providers/dns/ns1"
- "github.com/xenolf/lego/providers/dns/otc"
- "github.com/xenolf/lego/providers/dns/ovh"
- "github.com/xenolf/lego/providers/dns/pdns"
- "github.com/xenolf/lego/providers/dns/rackspace"
- "github.com/xenolf/lego/providers/dns/rfc2136"
- "github.com/xenolf/lego/providers/dns/route53"
- "github.com/xenolf/lego/providers/dns/vultr"
-)
-
-func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error) {
- var err error
- var provider acme.ChallengeProvider
- switch name {
- case "azure":
- provider, err = azure.NewDNSProvider()
- case "auroradns":
- provider, err = auroradns.NewDNSProvider()
- case "cloudflare":
- provider, err = cloudflare.NewDNSProvider()
- case "digitalocean":
- provider, err = digitalocean.NewDNSProvider()
- case "dnsimple":
- provider, err = dnsimple.NewDNSProvider()
- case "dnsmadeeasy":
- provider, err = dnsmadeeasy.NewDNSProvider()
- case "dnspod":
- provider, err = dnspod.NewDNSProvider()
- case "dyn":
- provider, err = dyn.NewDNSProvider()
- case "exoscale":
- provider, err = exoscale.NewDNSProvider()
- case "gandi":
- provider, err = gandi.NewDNSProvider()
- case "gcloud":
- provider, err = googlecloud.NewDNSProvider()
- case "godaddy":
- provider, err = godaddy.NewDNSProvider()
- case "linode":
- provider, err = linode.NewDNSProvider()
- case "manual":
- provider, err = acme.NewDNSProviderManual()
- case "namecheap":
- provider, err = namecheap.NewDNSProvider()
- case "rackspace":
- provider, err = rackspace.NewDNSProvider()
- case "route53":
- provider, err = route53.NewDNSProvider()
- case "rfc2136":
- provider, err = rfc2136.NewDNSProvider()
- case "vultr":
- provider, err = vultr.NewDNSProvider()
- case "ovh":
- provider, err = ovh.NewDNSProvider()
- case "pdns":
- provider, err = pdns.NewDNSProvider()
- case "ns1":
- provider, err = ns1.NewDNSProvider()
- case "otc":
- provider, err = otc.NewDNSProvider()
- default:
- err = fmt.Errorf("Unrecognised DNS provider: %s", name)
- }
- return provider, err
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dns_providers_test.go b/vendor/github.com/xenolf/lego/providers/dns/dns_providers_test.go
deleted file mode 100644
index 3f87ffd33..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dns_providers_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package dns
-
-import (
- "os"
- "reflect"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/xenolf/lego/providers/dns/exoscale"
-)
-
-var (
- apiKey string
- apiSecret string
-)
-
-func init() {
- apiSecret = os.Getenv("EXOSCALE_API_SECRET")
- apiKey = os.Getenv("EXOSCALE_API_KEY")
-}
-
-func restoreExoscaleEnv() {
- os.Setenv("EXOSCALE_API_KEY", apiKey)
- os.Setenv("EXOSCALE_API_SECRET", apiSecret)
-}
-
-func TestKnownDNSProviderSuccess(t *testing.T) {
- os.Setenv("EXOSCALE_API_KEY", "abc")
- os.Setenv("EXOSCALE_API_SECRET", "123")
- provider, err := NewDNSChallengeProviderByName("exoscale")
- assert.NoError(t, err)
- assert.NotNil(t, provider)
- if reflect.TypeOf(provider) != reflect.TypeOf(&exoscale.DNSProvider{}) {
- t.Errorf("Not loaded correct DNS proviver: %v is not *exoscale.DNSProvider", reflect.TypeOf(provider))
- }
- restoreExoscaleEnv()
-}
-
-func TestKnownDNSProviderError(t *testing.T) {
- os.Setenv("EXOSCALE_API_KEY", "")
- os.Setenv("EXOSCALE_API_SECRET", "")
- _, err := NewDNSChallengeProviderByName("exoscale")
- assert.Error(t, err)
- restoreExoscaleEnv()
-}
-
-func TestUnknownDNSProvider(t *testing.T) {
- _, err := NewDNSChallengeProviderByName("foobar")
- assert.Error(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple.go b/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple.go
deleted file mode 100644
index e3fea79ec..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Package dnsimple implements a DNS provider for solving the DNS-01 challenge
-// using dnsimple DNS.
-package dnsimple
-
-import (
- "fmt"
- "os"
- "strconv"
- "strings"
-
- "github.com/dnsimple/dnsimple-go/dnsimple"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface.
-type DNSProvider struct {
- client *dnsimple.Client
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for dnsimple.
-// Credentials must be passed in the environment variables: DNSIMPLE_OAUTH_TOKEN.
-//
-// See: https://developer.dnsimple.com/v2/#authentication
-func NewDNSProvider() (*DNSProvider, error) {
- accessToken := os.Getenv("DNSIMPLE_OAUTH_TOKEN")
- baseUrl := os.Getenv("DNSIMPLE_BASE_URL")
-
- return NewDNSProviderCredentials(accessToken, baseUrl)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for dnsimple.
-func NewDNSProviderCredentials(accessToken, baseUrl string) (*DNSProvider, error) {
- if accessToken == "" {
- return nil, fmt.Errorf("DNSimple OAuth token is missing")
- }
-
- client := dnsimple.NewClient(dnsimple.NewOauthTokenCredentials(accessToken))
- client.UserAgent = "lego"
-
- if baseUrl != "" {
- client.BaseURL = baseUrl
- }
-
- return &DNSProvider{client: client}, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- zoneName, err := c.getHostedZone(domain)
-
- if err != nil {
- return err
- }
-
- accountID, err := c.getAccountID()
- if err != nil {
- return err
- }
-
- recordAttributes := c.newTxtRecord(zoneName, fqdn, value, ttl)
- _, err = c.client.Zones.CreateRecord(accountID, zoneName, *recordAttributes)
- if err != nil {
- return fmt.Errorf("DNSimple API call failed: %v", err)
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- records, err := c.findTxtRecords(domain, fqdn)
- if err != nil {
- return err
- }
-
- accountID, err := c.getAccountID()
- if err != nil {
- return err
- }
-
- for _, rec := range records {
- _, err := c.client.Zones.DeleteRecord(accountID, rec.ZoneID, rec.ID)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *DNSProvider) getHostedZone(domain string) (string, error) {
- authZone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- accountID, err := c.getAccountID()
- if err != nil {
- return "", err
- }
-
- zoneName := acme.UnFqdn(authZone)
-
- zones, err := c.client.Zones.ListZones(accountID, &dnsimple.ZoneListOptions{NameLike: zoneName})
- if err != nil {
- return "", fmt.Errorf("DNSimple API call failed: %v", err)
- }
-
- var hostedZone dnsimple.Zone
- for _, zone := range zones.Data {
- if zone.Name == zoneName {
- hostedZone = zone
- }
- }
-
- if hostedZone.ID == 0 {
- return "", fmt.Errorf("Zone %s not found in DNSimple for domain %s", authZone, domain)
-
- }
-
- return hostedZone.Name, nil
-}
-
-func (c *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnsimple.ZoneRecord, error) {
- zoneName, err := c.getHostedZone(domain)
- if err != nil {
- return nil, err
- }
-
- accountID, err := c.getAccountID()
- if err != nil {
- return nil, err
- }
-
- recordName := c.extractRecordName(fqdn, zoneName)
-
- result, err := c.client.Zones.ListRecords(accountID, zoneName, &dnsimple.ZoneRecordListOptions{Name: recordName, Type: "TXT", ListOptions: dnsimple.ListOptions{}})
- if err != nil {
- return []dnsimple.ZoneRecord{}, fmt.Errorf("DNSimple API call has failed: %v", err)
- }
-
- return result.Data, nil
-}
-
-func (c *DNSProvider) newTxtRecord(zoneName, fqdn, value string, ttl int) *dnsimple.ZoneRecord {
- name := c.extractRecordName(fqdn, zoneName)
-
- return &dnsimple.ZoneRecord{
- Type: "TXT",
- Name: name,
- Content: value,
- TTL: ttl,
- }
-}
-
-func (c *DNSProvider) extractRecordName(fqdn, domain string) string {
- name := acme.UnFqdn(fqdn)
- if idx := strings.Index(name, "."+domain); idx != -1 {
- return name[:idx]
- }
- return name
-}
-
-func (c *DNSProvider) getAccountID() (string, error) {
- whoamiResponse, err := c.client.Identity.Whoami()
- if err != nil {
- return "", err
- }
-
- if whoamiResponse.Data.Account == nil {
- return "", fmt.Errorf("DNSimple user tokens are not supported, please use an account token.")
- }
-
- return strconv.Itoa(whoamiResponse.Data.Account.ID), nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple_test.go b/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple_test.go
deleted file mode 100644
index bd35790d7..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnsimple/dnsimple_test.go
+++ /dev/null
@@ -1,140 +0,0 @@
-package dnsimple
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- dnsimpleLiveTest bool
- dnsimpleOauthToken string
- dnsimpleDomain string
- dnsimpleBaseUrl string
-)
-
-func init() {
- dnsimpleOauthToken = os.Getenv("DNSIMPLE_OAUTH_TOKEN")
- dnsimpleDomain = os.Getenv("DNSIMPLE_DOMAIN")
- dnsimpleBaseUrl = "https://api.sandbox.dnsimple.com"
-
- if len(dnsimpleOauthToken) > 0 && len(dnsimpleDomain) > 0 {
- baseUrl := os.Getenv("DNSIMPLE_BASE_URL")
-
- if baseUrl != "" {
- dnsimpleBaseUrl = baseUrl
- }
-
- dnsimpleLiveTest = true
- }
-}
-
-func restoreDNSimpleEnv() {
- os.Setenv("DNSIMPLE_OAUTH_TOKEN", dnsimpleOauthToken)
- os.Setenv("DNSIMPLE_BASE_URL", dnsimpleBaseUrl)
-}
-
-//
-// NewDNSProvider
-//
-
-func TestNewDNSProviderValid(t *testing.T) {
- defer restoreDNSimpleEnv()
-
- os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123")
- provider, err := NewDNSProvider()
-
- assert.NotNil(t, provider)
- assert.Equal(t, "lego", provider.client.UserAgent)
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderValidWithBaseUrl(t *testing.T) {
- defer restoreDNSimpleEnv()
-
- os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123")
- os.Setenv("DNSIMPLE_BASE_URL", "https://api.dnsimple.test")
- provider, err := NewDNSProvider()
-
- assert.NotNil(t, provider)
- assert.NoError(t, err)
-
- assert.Equal(t, provider.client.BaseURL, "https://api.dnsimple.test")
-}
-
-func TestNewDNSProviderInvalidWithMissingOauthToken(t *testing.T) {
- if dnsimpleLiveTest {
- t.Skip("skipping test in live mode")
- }
-
- defer restoreDNSimpleEnv()
-
- provider, err := NewDNSProvider()
-
- assert.Nil(t, provider)
- assert.EqualError(t, err, "DNSimple OAuth token is missing")
-}
-
-//
-// NewDNSProviderCredentials
-//
-
-func TestNewDNSProviderCredentialsValid(t *testing.T) {
- provider, err := NewDNSProviderCredentials("123", "")
-
- assert.NotNil(t, provider)
- assert.Equal(t, "lego", provider.client.UserAgent)
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderCredentialsValidWithBaseUrl(t *testing.T) {
- provider, err := NewDNSProviderCredentials("123", "https://api.dnsimple.test")
-
- assert.NotNil(t, provider)
- assert.NoError(t, err)
-
- assert.Equal(t, provider.client.BaseURL, "https://api.dnsimple.test")
-}
-
-func TestNewDNSProviderCredentialsInvalidWithMissingOauthToken(t *testing.T) {
- provider, err := NewDNSProviderCredentials("", "")
-
- assert.Nil(t, provider)
- assert.EqualError(t, err, "DNSimple OAuth token is missing")
-}
-
-//
-// Present
-//
-
-func TestLiveDNSimplePresent(t *testing.T) {
- if !dnsimpleLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(dnsimpleOauthToken, dnsimpleBaseUrl)
- assert.NoError(t, err)
-
- err = provider.Present(dnsimpleDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-//
-// Cleanup
-//
-
-func TestLiveDNSimpleCleanUp(t *testing.T) {
- if !dnsimpleLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProviderCredentials(dnsimpleOauthToken, dnsimpleBaseUrl)
- assert.NoError(t, err)
-
- err = provider.CleanUp(dnsimpleDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go b/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go
deleted file mode 100644
index c4363a4eb..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go
+++ /dev/null
@@ -1,248 +0,0 @@
-package dnsmadeeasy
-
-import (
- "bytes"
- "crypto/hmac"
- "crypto/sha1"
- "crypto/tls"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "net/http"
- "os"
- "strconv"
- "strings"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses
-// DNSMadeEasy's DNS API to manage TXT records for a domain.
-type DNSProvider struct {
- baseURL string
- apiKey string
- apiSecret string
-}
-
-// Domain holds the DNSMadeEasy API representation of a Domain
-type Domain struct {
- ID int `json:"id"`
- Name string `json:"name"`
-}
-
-// Record holds the DNSMadeEasy API representation of a Domain Record
-type Record struct {
- ID int `json:"id"`
- Type string `json:"type"`
- Name string `json:"name"`
- Value string `json:"value"`
- TTL int `json:"ttl"`
- SourceID int `json:"sourceId"`
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for DNSMadeEasy DNS.
-// Credentials must be passed in the environment variables: DNSMADEEASY_API_KEY
-// and DNSMADEEASY_API_SECRET.
-func NewDNSProvider() (*DNSProvider, error) {
- dnsmadeeasyAPIKey := os.Getenv("DNSMADEEASY_API_KEY")
- dnsmadeeasyAPISecret := os.Getenv("DNSMADEEASY_API_SECRET")
- dnsmadeeasySandbox := os.Getenv("DNSMADEEASY_SANDBOX")
-
- var baseURL string
-
- sandbox, _ := strconv.ParseBool(dnsmadeeasySandbox)
- if sandbox {
- baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
- } else {
- baseURL = "https://api.dnsmadeeasy.com/V2.0"
- }
-
- return NewDNSProviderCredentials(baseURL, dnsmadeeasyAPIKey, dnsmadeeasyAPISecret)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for DNSMadeEasy.
-func NewDNSProviderCredentials(baseURL, apiKey, apiSecret string) (*DNSProvider, error) {
- if baseURL == "" || apiKey == "" || apiSecret == "" {
- return nil, fmt.Errorf("DNS Made Easy credentials missing")
- }
-
- return &DNSProvider{
- baseURL: baseURL,
- apiKey: apiKey,
- apiSecret: apiSecret,
- }, nil
-}
-
-// Present creates a TXT record using the specified parameters
-func (d *DNSProvider) Present(domainName, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domainName, keyAuth)
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- // fetch the domain details
- domain, err := d.getDomain(authZone)
- if err != nil {
- return err
- }
-
- // create the TXT record
- name := strings.Replace(fqdn, "."+authZone, "", 1)
- record := &Record{Type: "TXT", Name: name, Value: value, TTL: ttl}
-
- err = d.createRecord(domain, record)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT records matching the specified parameters
-func (d *DNSProvider) CleanUp(domainName, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domainName, keyAuth)
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- // fetch the domain details
- domain, err := d.getDomain(authZone)
- if err != nil {
- return err
- }
-
- // find matching records
- name := strings.Replace(fqdn, "."+authZone, "", 1)
- records, err := d.getRecords(domain, name, "TXT")
- if err != nil {
- return err
- }
-
- // delete records
- for _, record := range *records {
- err = d.deleteRecord(record)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (d *DNSProvider) getDomain(authZone string) (*Domain, error) {
- domainName := authZone[0 : len(authZone)-1]
- resource := fmt.Sprintf("%s%s", "/dns/managed/name?domainname=", domainName)
-
- resp, err := d.sendRequest("GET", resource, nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- domain := &Domain{}
- err = json.NewDecoder(resp.Body).Decode(&domain)
- if err != nil {
- return nil, err
- }
-
- return domain, nil
-}
-
-func (d *DNSProvider) getRecords(domain *Domain, recordName, recordType string) (*[]Record, error) {
- resource := fmt.Sprintf("%s/%d/%s%s%s%s", "/dns/managed", domain.ID, "records?recordName=", recordName, "&type=", recordType)
-
- resp, err := d.sendRequest("GET", resource, nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- type recordsResponse struct {
- Records *[]Record `json:"data"`
- }
-
- records := &recordsResponse{}
- err = json.NewDecoder(resp.Body).Decode(&records)
- if err != nil {
- return nil, err
- }
-
- return records.Records, nil
-}
-
-func (d *DNSProvider) createRecord(domain *Domain, record *Record) error {
- url := fmt.Sprintf("%s/%d/%s", "/dns/managed", domain.ID, "records")
-
- resp, err := d.sendRequest("POST", url, record)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- return nil
-}
-
-func (d *DNSProvider) deleteRecord(record Record) error {
- resource := fmt.Sprintf("%s/%d/%s/%d", "/dns/managed", record.SourceID, "records", record.ID)
-
- resp, err := d.sendRequest("DELETE", resource, nil)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- return nil
-}
-
-func (d *DNSProvider) sendRequest(method, resource string, payload interface{}) (*http.Response, error) {
- url := fmt.Sprintf("%s%s", d.baseURL, resource)
-
- body, err := json.Marshal(payload)
- if err != nil {
- return nil, err
- }
-
- timestamp := time.Now().UTC().Format(time.RFC1123)
- signature := computeHMAC(timestamp, d.apiSecret)
-
- req, err := http.NewRequest(method, url, bytes.NewReader(body))
- if err != nil {
- return nil, err
- }
- req.Header.Set("x-dnsme-apiKey", d.apiKey)
- req.Header.Set("x-dnsme-requestDate", timestamp)
- req.Header.Set("x-dnsme-hmac", signature)
- req.Header.Set("accept", "application/json")
- req.Header.Set("content-type", "application/json")
-
- transport := &http.Transport{
- TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
- }
- client := &http.Client{
- Transport: transport,
- Timeout: time.Duration(10 * time.Second),
- }
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
-
- if resp.StatusCode > 299 {
- return nil, fmt.Errorf("DNSMadeEasy API request failed with HTTP status code %d", resp.StatusCode)
- }
-
- return resp, nil
-}
-
-func computeHMAC(message string, secret string) string {
- key := []byte(secret)
- h := hmac.New(sha1.New, key)
- h.Write([]byte(message))
- return hex.EncodeToString(h.Sum(nil))
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go b/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go
deleted file mode 100644
index e860ecb69..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package dnsmadeeasy
-
-import (
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- testLive bool
- testAPIKey string
- testAPISecret string
- testDomain string
-)
-
-func init() {
- testAPIKey = os.Getenv("DNSMADEEASY_API_KEY")
- testAPISecret = os.Getenv("DNSMADEEASY_API_SECRET")
- testDomain = os.Getenv("DNSMADEEASY_DOMAIN")
- os.Setenv("DNSMADEEASY_SANDBOX", "true")
- testLive = len(testAPIKey) > 0 && len(testAPISecret) > 0
-}
-
-func TestPresentAndCleanup(t *testing.T) {
- if !testLive {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
-
- err = provider.Present(testDomain, "", "123d==")
- assert.NoError(t, err)
-
- err = provider.CleanUp(testDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go b/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go
deleted file mode 100644
index 0ce08a8bb..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Package dnspod implements a DNS provider for solving the DNS-01 challenge
-// using dnspod DNS.
-package dnspod
-
-import (
- "fmt"
- "os"
- "strings"
-
- "github.com/decker502/dnspod-go"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface.
-type DNSProvider struct {
- client *dnspod.Client
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for dnspod.
-// Credentials must be passed in the environment variables: DNSPOD_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- key := os.Getenv("DNSPOD_API_KEY")
- return NewDNSProviderCredentials(key)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for dnspod.
-func NewDNSProviderCredentials(key string) (*DNSProvider, error) {
- if key == "" {
- return nil, fmt.Errorf("dnspod credentials missing")
- }
-
- params := dnspod.CommonParams{LoginToken: key, Format: "json"}
- return &DNSProvider{
- client: dnspod.NewClient(params),
- }, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- zoneID, zoneName, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- recordAttributes := c.newTxtRecord(zoneName, fqdn, value, ttl)
- _, _, err = c.client.Domains.CreateRecord(zoneID, *recordAttributes)
- if err != nil {
- return fmt.Errorf("dnspod API call failed: %v", err)
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- records, err := c.findTxtRecords(domain, fqdn)
- if err != nil {
- return err
- }
-
- zoneID, _, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- for _, rec := range records {
- _, err := c.client.Domains.DeleteRecord(zoneID, rec.ID)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (c *DNSProvider) getHostedZone(domain string) (string, string, error) {
- zones, _, err := c.client.Domains.List()
- if err != nil {
- return "", "", fmt.Errorf("dnspod API call failed: %v", err)
- }
-
- authZone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers)
- if err != nil {
- return "", "", err
- }
-
- var hostedZone dnspod.Domain
- for _, zone := range zones {
- if zone.Name == acme.UnFqdn(authZone) {
- hostedZone = zone
- }
- }
-
- if hostedZone.ID == 0 {
- return "", "", fmt.Errorf("Zone %s not found in dnspod for domain %s", authZone, domain)
-
- }
-
- return fmt.Sprintf("%v", hostedZone.ID), hostedZone.Name, nil
-}
-
-func (c *DNSProvider) newTxtRecord(zone, fqdn, value string, ttl int) *dnspod.Record {
- name := c.extractRecordName(fqdn, zone)
-
- return &dnspod.Record{
- Type: "TXT",
- Name: name,
- Value: value,
- Line: "默认",
- TTL: "600",
- }
-}
-
-func (c *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnspod.Record, error) {
- zoneID, zoneName, err := c.getHostedZone(domain)
- if err != nil {
- return nil, err
- }
-
- var records []dnspod.Record
- result, _, err := c.client.Domains.ListRecords(zoneID, "")
- if err != nil {
- return records, fmt.Errorf("dnspod API call has failed: %v", err)
- }
-
- recordName := c.extractRecordName(fqdn, zoneName)
-
- for _, record := range result {
- if record.Name == recordName {
- records = append(records, record)
- }
- }
-
- return records, nil
-}
-
-func (c *DNSProvider) extractRecordName(fqdn, domain string) string {
- name := acme.UnFqdn(fqdn)
- if idx := strings.Index(name, "."+domain); idx != -1 {
- return name[:idx]
- }
- return name
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod_test.go b/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod_test.go
deleted file mode 100644
index 3311eb0a6..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dnspod/dnspod_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package dnspod
-
-import (
- "github.com/stretchr/testify/assert"
- "os"
- "testing"
- "time"
-)
-
-var (
- dnspodLiveTest bool
- dnspodAPIKey string
- dnspodDomain string
-)
-
-func init() {
- dnspodAPIKey = os.Getenv("DNSPOD_API_KEY")
- dnspodDomain = os.Getenv("DNSPOD_DOMAIN")
- if len(dnspodAPIKey) > 0 && len(dnspodDomain) > 0 {
- dnspodLiveTest = true
- }
-}
-
-func restorednspodEnv() {
- os.Setenv("DNSPOD_API_KEY", dnspodAPIKey)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- os.Setenv("DNSPOD_API_KEY", "")
- _, err := NewDNSProviderCredentials("123")
- assert.NoError(t, err)
- restorednspodEnv()
-}
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("DNSPOD_API_KEY", "123")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restorednspodEnv()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("DNSPOD_API_KEY", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "dnspod credentials missing")
- restorednspodEnv()
-}
-
-func TestLivednspodPresent(t *testing.T) {
- if !dnspodLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(dnspodAPIKey)
- assert.NoError(t, err)
-
- err = provider.Present(dnspodDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLivednspodCleanUp(t *testing.T) {
- if !dnspodLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProviderCredentials(dnspodAPIKey)
- assert.NoError(t, err)
-
- err = provider.CleanUp(dnspodDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn.go b/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn.go
deleted file mode 100644
index 384bc850c..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Package dyn implements a DNS provider for solving the DNS-01 challenge
-// using Dyn Managed DNS.
-package dyn
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "net/http"
- "os"
- "strconv"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-var dynBaseURL = "https://api.dynect.net/REST"
-
-type dynResponse struct {
- // One of 'success', 'failure', or 'incomplete'
- Status string `json:"status"`
-
- // The structure containing the actual results of the request
- Data json.RawMessage `json:"data"`
-
- // The ID of the job that was created in response to a request.
- JobID int `json:"job_id"`
-
- // A list of zero or more messages
- Messages json.RawMessage `json:"msgs"`
-}
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses
-// Dyn's Managed DNS API to manage TXT records for a domain.
-type DNSProvider struct {
- customerName string
- userName string
- password string
- token string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Dyn DNS.
-// Credentials must be passed in the environment variables: DYN_CUSTOMER_NAME,
-// DYN_USER_NAME and DYN_PASSWORD.
-func NewDNSProvider() (*DNSProvider, error) {
- customerName := os.Getenv("DYN_CUSTOMER_NAME")
- userName := os.Getenv("DYN_USER_NAME")
- password := os.Getenv("DYN_PASSWORD")
- return NewDNSProviderCredentials(customerName, userName, password)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Dyn DNS.
-func NewDNSProviderCredentials(customerName, userName, password string) (*DNSProvider, error) {
- if customerName == "" || userName == "" || password == "" {
- return nil, fmt.Errorf("DynDNS credentials missing")
- }
-
- return &DNSProvider{
- customerName: customerName,
- userName: userName,
- password: password,
- }, nil
-}
-
-func (d *DNSProvider) sendRequest(method, resource string, payload interface{}) (*dynResponse, error) {
- url := fmt.Sprintf("%s/%s", dynBaseURL, resource)
-
- body, err := json.Marshal(payload)
- if err != nil {
- return nil, err
- }
-
- req, err := http.NewRequest(method, url, bytes.NewReader(body))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "application/json")
- if len(d.token) > 0 {
- req.Header.Set("Auth-Token", d.token)
- }
-
- client := &http.Client{Timeout: time.Duration(10 * time.Second)}
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return nil, fmt.Errorf("Dyn API request failed with HTTP status code %d", resp.StatusCode)
- } else if resp.StatusCode == 307 {
- // TODO add support for HTTP 307 response and long running jobs
- return nil, fmt.Errorf("Dyn API request returned HTTP 307. This is currently unsupported")
- }
-
- var dynRes dynResponse
- err = json.NewDecoder(resp.Body).Decode(&dynRes)
- if err != nil {
- return nil, err
- }
-
- if dynRes.Status == "failure" {
- // TODO add better error handling
- return nil, fmt.Errorf("Dyn API request failed: %s", dynRes.Messages)
- }
-
- return &dynRes, nil
-}
-
-// Starts a new Dyn API Session. Authenticates using customerName, userName,
-// password and receives a token to be used in for subsequent requests.
-func (d *DNSProvider) login() error {
- type creds struct {
- Customer string `json:"customer_name"`
- User string `json:"user_name"`
- Pass string `json:"password"`
- }
-
- type session struct {
- Token string `json:"token"`
- Version string `json:"version"`
- }
-
- payload := &creds{Customer: d.customerName, User: d.userName, Pass: d.password}
- dynRes, err := d.sendRequest("POST", "Session", payload)
- if err != nil {
- return err
- }
-
- var s session
- err = json.Unmarshal(dynRes.Data, &s)
- if err != nil {
- return err
- }
-
- d.token = s.Token
-
- return nil
-}
-
-// Destroys Dyn Session
-func (d *DNSProvider) logout() error {
- if len(d.token) == 0 {
- // nothing to do
- return nil
- }
-
- url := fmt.Sprintf("%s/Session", dynBaseURL)
- req, err := http.NewRequest("DELETE", url, nil)
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Auth-Token", d.token)
-
- client := &http.Client{Timeout: time.Duration(10 * time.Second)}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return fmt.Errorf("Dyn API request failed to delete session with HTTP status code %d", resp.StatusCode)
- }
-
- d.token = ""
-
- return nil
-}
-
-// Present creates a TXT record using the specified parameters
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- err = d.login()
- if err != nil {
- return err
- }
-
- data := map[string]interface{}{
- "rdata": map[string]string{
- "txtdata": value,
- },
- "ttl": strconv.Itoa(ttl),
- }
-
- resource := fmt.Sprintf("TXTRecord/%s/%s/", authZone, fqdn)
- _, err = d.sendRequest("POST", resource, data)
- if err != nil {
- return err
- }
-
- err = d.publish(authZone, "Added TXT record for ACME dns-01 challenge using lego client")
- if err != nil {
- return err
- }
-
- err = d.logout()
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *DNSProvider) publish(zone, notes string) error {
- type publish struct {
- Publish bool `json:"publish"`
- Notes string `json:"notes"`
- }
-
- pub := &publish{Publish: true, Notes: notes}
- resource := fmt.Sprintf("Zone/%s/", zone)
- _, err := d.sendRequest("PUT", resource, pub)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- err = d.login()
- if err != nil {
- return err
- }
-
- resource := fmt.Sprintf("TXTRecord/%s/%s/", authZone, fqdn)
- url := fmt.Sprintf("%s/%s", dynBaseURL, resource)
- req, err := http.NewRequest("DELETE", url, nil)
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Auth-Token", d.token)
-
- client := &http.Client{Timeout: time.Duration(10 * time.Second)}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return fmt.Errorf("Dyn API request failed to delete TXT record HTTP status code %d", resp.StatusCode)
- }
-
- err = d.publish(authZone, "Removed TXT record for ACME dns-01 challenge using lego client")
- if err != nil {
- return err
- }
-
- err = d.logout()
- if err != nil {
- return err
- }
-
- return nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn_test.go b/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn_test.go
deleted file mode 100644
index 0d28d5d0e..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/dyn/dyn_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package dyn
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- dynLiveTest bool
- dynCustomerName string
- dynUserName string
- dynPassword string
- dynDomain string
-)
-
-func init() {
- dynCustomerName = os.Getenv("DYN_CUSTOMER_NAME")
- dynUserName = os.Getenv("DYN_USER_NAME")
- dynPassword = os.Getenv("DYN_PASSWORD")
- dynDomain = os.Getenv("DYN_DOMAIN")
- if len(dynCustomerName) > 0 && len(dynUserName) > 0 && len(dynPassword) > 0 && len(dynDomain) > 0 {
- dynLiveTest = true
- }
-}
-
-func TestLiveDynPresent(t *testing.T) {
- if !dynLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.Present(dynDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveDynCleanUp(t *testing.T) {
- if !dynLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.CleanUp(dynDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go b/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go
deleted file mode 100644
index 4b125e8df..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Package exoscale implements a DNS provider for solving the DNS-01 challenge
-// using exoscale DNS.
-package exoscale
-
-import (
- "errors"
- "fmt"
- "os"
-
- "github.com/exoscale/egoscale"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface.
-type DNSProvider struct {
- client *egoscale.Client
-}
-
-// Credentials must be passed in the environment variables:
-// EXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINT.
-func NewDNSProvider() (*DNSProvider, error) {
- key := os.Getenv("EXOSCALE_API_KEY")
- secret := os.Getenv("EXOSCALE_API_SECRET")
- endpoint := os.Getenv("EXOSCALE_ENDPOINT")
- return NewDNSProviderClient(key, secret, endpoint)
-}
-
-// Uses the supplied parameters to return a DNSProvider instance
-// configured for Exoscale.
-func NewDNSProviderClient(key, secret, endpoint string) (*DNSProvider, error) {
- if key == "" || secret == "" {
- return nil, fmt.Errorf("Exoscale credentials missing")
- }
- if endpoint == "" {
- endpoint = "https://api.exoscale.ch/dns"
- }
-
- return &DNSProvider{
- client: egoscale.NewClient(endpoint, key, secret),
- }, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- zone, recordName, err := c.FindZoneAndRecordName(fqdn, domain)
- if err != nil {
- return err
- }
-
- recordID, err := c.FindExistingRecordId(zone, recordName)
- if err != nil {
- return err
- }
-
- record := egoscale.DNSRecord{
- Name: recordName,
- TTL: ttl,
- Content: value,
- RecordType: "TXT",
- }
-
- if recordID == 0 {
- _, err := c.client.CreateRecord(zone, record)
- if err != nil {
- return errors.New("Error while creating DNS record: " + err.Error())
- }
- } else {
- record.ID = recordID
- _, err := c.client.UpdateRecord(zone, record)
- if err != nil {
- return errors.New("Error while updating DNS record: " + err.Error())
- }
- }
-
- return nil
-}
-
-// CleanUp removes the record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
- zone, recordName, err := c.FindZoneAndRecordName(fqdn, domain)
- if err != nil {
- return err
- }
-
- recordID, err := c.FindExistingRecordId(zone, recordName)
- if err != nil {
- return err
- }
-
- if recordID != 0 {
- err = c.client.DeleteRecord(zone, recordID)
- if err != nil {
- return errors.New("Error while deleting DNS record: " + err.Error())
- }
- }
-
- return nil
-}
-
-// Query Exoscale to find an existing record for this name.
-// Returns nil if no record could be found
-func (c *DNSProvider) FindExistingRecordId(zone, recordName string) (int64, error) {
- records, err := c.client.GetRecords(zone)
- if err != nil {
- return -1, errors.New("Error while retrievening DNS records: " + err.Error())
- }
- for _, record := range records {
- if record.Name == recordName {
- return record.ID, nil
- }
- }
- return 0, nil
-}
-
-// Extract DNS zone and DNS entry name
-func (c *DNSProvider) FindZoneAndRecordName(fqdn, domain string) (string, string, error) {
- zone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers)
- if err != nil {
- return "", "", err
- }
- zone = acme.UnFqdn(zone)
- name := acme.UnFqdn(fqdn)
- name = name[:len(name)-len("."+zone)]
-
- return zone, name, nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale_test.go b/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale_test.go
deleted file mode 100644
index 343dd56f8..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package exoscale
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- exoscaleLiveTest bool
- exoscaleAPIKey string
- exoscaleAPISecret string
- exoscaleDomain string
-)
-
-func init() {
- exoscaleAPISecret = os.Getenv("EXOSCALE_API_SECRET")
- exoscaleAPIKey = os.Getenv("EXOSCALE_API_KEY")
- exoscaleDomain = os.Getenv("EXOSCALE_DOMAIN")
- if len(exoscaleAPIKey) > 0 && len(exoscaleAPISecret) > 0 && len(exoscaleDomain) > 0 {
- exoscaleLiveTest = true
- }
-}
-
-func restoreExoscaleEnv() {
- os.Setenv("EXOSCALE_API_KEY", exoscaleAPIKey)
- os.Setenv("EXOSCALE_API_SECRET", exoscaleAPISecret)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- os.Setenv("EXOSCALE_API_KEY", "")
- os.Setenv("EXOSCALE_API_SECRET", "")
- _, err := NewDNSProviderClient("example@example.com", "123", "")
- assert.NoError(t, err)
- restoreExoscaleEnv()
-}
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("EXOSCALE_API_KEY", "example@example.com")
- os.Setenv("EXOSCALE_API_SECRET", "123")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restoreExoscaleEnv()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("EXOSCALE_API_KEY", "")
- os.Setenv("EXOSCALE_API_SECRET", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "Exoscale credentials missing")
- restoreExoscaleEnv()
-}
-
-func TestExtractRootRecordName(t *testing.T) {
- provider, err := NewDNSProviderClient("example@example.com", "123", "")
- assert.NoError(t, err)
-
- zone, recordName, err := provider.FindZoneAndRecordName("_acme-challenge.bar.com.", "bar.com")
- assert.NoError(t, err)
- assert.Equal(t, "bar.com", zone)
- assert.Equal(t, "_acme-challenge", recordName)
-}
-
-func TestExtractSubRecordName(t *testing.T) {
- provider, err := NewDNSProviderClient("example@example.com", "123", "")
- assert.NoError(t, err)
-
- zone, recordName, err := provider.FindZoneAndRecordName("_acme-challenge.foo.bar.com.", "foo.bar.com")
- assert.NoError(t, err)
- assert.Equal(t, "bar.com", zone)
- assert.Equal(t, "_acme-challenge.foo", recordName)
-}
-
-func TestLiveExoscalePresent(t *testing.T) {
- if !exoscaleLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderClient(exoscaleAPIKey, exoscaleAPISecret, "")
- assert.NoError(t, err)
-
- err = provider.Present(exoscaleDomain, "", "123d==")
- assert.NoError(t, err)
-
- // Present Twice to handle create / update
- err = provider.Present(exoscaleDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveExoscaleCleanUp(t *testing.T) {
- if !exoscaleLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProviderClient(exoscaleAPIKey, exoscaleAPISecret, "")
- assert.NoError(t, err)
-
- err = provider.CleanUp(exoscaleDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi.go b/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi.go
deleted file mode 100644
index 422b02a21..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi.go
+++ /dev/null
@@ -1,472 +0,0 @@
-// Package gandi implements a DNS provider for solving the DNS-01
-// challenge using Gandi DNS.
-package gandi
-
-import (
- "bytes"
- "encoding/xml"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "os"
- "strings"
- "sync"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// Gandi API reference: http://doc.rpc.gandi.net/index.html
-// Gandi API domain examples: http://doc.rpc.gandi.net/domain/faq.html
-
-var (
- // endpoint is the Gandi XML-RPC endpoint used by Present and
- // CleanUp. It is overridden during tests.
- endpoint = "https://rpc.gandi.net/xmlrpc/"
- // findZoneByFqdn determines the DNS zone of an fqdn. It is overridden
- // during tests.
- findZoneByFqdn = acme.FindZoneByFqdn
-)
-
-// inProgressInfo contains information about an in-progress challenge
-type inProgressInfo struct {
- zoneID int // zoneID of gandi zone to restore in CleanUp
- newZoneID int // zoneID of temporary gandi zone containing TXT record
- authZone string // the domain name registered at gandi with trailing "."
-}
-
-// DNSProvider is an implementation of the
-// acme.ChallengeProviderTimeout interface that uses Gandi's XML-RPC
-// API to manage TXT records for a domain.
-type DNSProvider struct {
- apiKey string
- inProgressFQDNs map[string]inProgressInfo
- inProgressAuthZones map[string]struct{}
- inProgressMu sync.Mutex
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Gandi.
-// Credentials must be passed in the environment variable: GANDI_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- apiKey := os.Getenv("GANDI_API_KEY")
- return NewDNSProviderCredentials(apiKey)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Gandi.
-func NewDNSProviderCredentials(apiKey string) (*DNSProvider, error) {
- if apiKey == "" {
- return nil, fmt.Errorf("No Gandi API Key given")
- }
- return &DNSProvider{
- apiKey: apiKey,
- inProgressFQDNs: make(map[string]inProgressInfo),
- inProgressAuthZones: make(map[string]struct{}),
- }, nil
-}
-
-// Present creates a TXT record using the specified parameters. It
-// does this by creating and activating a new temporary Gandi DNS
-// zone. This new zone contains the TXT record.
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- if ttl < 300 {
- ttl = 300 // 300 is gandi minimum value for ttl
- }
- // find authZone and Gandi zone_id for fqdn
- authZone, err := findZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return fmt.Errorf("Gandi DNS: findZoneByFqdn failure: %v", err)
- }
- zoneID, err := d.getZoneID(authZone)
- if err != nil {
- return err
- }
- // determine name of TXT record
- if !strings.HasSuffix(
- strings.ToLower(fqdn), strings.ToLower("."+authZone)) {
- return fmt.Errorf(
- "Gandi DNS: unexpected authZone %s for fqdn %s", authZone, fqdn)
- }
- name := fqdn[:len(fqdn)-len("."+authZone)]
- // acquire lock and check there is not a challenge already in
- // progress for this value of authZone
- d.inProgressMu.Lock()
- defer d.inProgressMu.Unlock()
- if _, ok := d.inProgressAuthZones[authZone]; ok {
- return fmt.Errorf(
- "Gandi DNS: challenge already in progress for authZone %s",
- authZone)
- }
- // perform API actions to create and activate new gandi zone
- // containing the required TXT record
- newZoneName := fmt.Sprintf(
- "%s [ACME Challenge %s]",
- acme.UnFqdn(authZone), time.Now().Format(time.RFC822Z))
- newZoneID, err := d.cloneZone(zoneID, newZoneName)
- if err != nil {
- return err
- }
- newZoneVersion, err := d.newZoneVersion(newZoneID)
- if err != nil {
- return err
- }
- err = d.addTXTRecord(newZoneID, newZoneVersion, name, value, ttl)
- if err != nil {
- return err
- }
- err = d.setZoneVersion(newZoneID, newZoneVersion)
- if err != nil {
- return err
- }
- err = d.setZone(authZone, newZoneID)
- if err != nil {
- return err
- }
- // save data necessary for CleanUp
- d.inProgressFQDNs[fqdn] = inProgressInfo{
- zoneID: zoneID,
- newZoneID: newZoneID,
- authZone: authZone,
- }
- d.inProgressAuthZones[authZone] = struct{}{}
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified
-// parameters. It does this by restoring the old Gandi DNS zone and
-// removing the temporary one created by Present.
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
- // acquire lock and retrieve zoneID, newZoneID and authZone
- d.inProgressMu.Lock()
- defer d.inProgressMu.Unlock()
- if _, ok := d.inProgressFQDNs[fqdn]; !ok {
- // if there is no cleanup information then just return
- return nil
- }
- zoneID := d.inProgressFQDNs[fqdn].zoneID
- newZoneID := d.inProgressFQDNs[fqdn].newZoneID
- authZone := d.inProgressFQDNs[fqdn].authZone
- delete(d.inProgressFQDNs, fqdn)
- delete(d.inProgressAuthZones, authZone)
- // perform API actions to restore old gandi zone for authZone
- err := d.setZone(authZone, zoneID)
- if err != nil {
- return err
- }
- err = d.deleteZone(newZoneID)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Timeout returns the values (40*time.Minute, 60*time.Second) which
-// are used by the acme package as timeout and check interval values
-// when checking for DNS record propagation with Gandi.
-func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 40 * time.Minute, 60 * time.Second
-}
-
-// types for XML-RPC method calls and parameters
-
-type param interface {
- param()
-}
-type paramString struct {
- XMLName xml.Name `xml:"param"`
- Value string `xml:"value>string"`
-}
-type paramInt struct {
- XMLName xml.Name `xml:"param"`
- Value int `xml:"value>int"`
-}
-
-type structMember interface {
- structMember()
-}
-type structMemberString struct {
- Name string `xml:"name"`
- Value string `xml:"value>string"`
-}
-type structMemberInt struct {
- Name string `xml:"name"`
- Value int `xml:"value>int"`
-}
-type paramStruct struct {
- XMLName xml.Name `xml:"param"`
- StructMembers []structMember `xml:"value>struct>member"`
-}
-
-func (p paramString) param() {}
-func (p paramInt) param() {}
-func (m structMemberString) structMember() {}
-func (m structMemberInt) structMember() {}
-func (p paramStruct) param() {}
-
-type methodCall struct {
- XMLName xml.Name `xml:"methodCall"`
- MethodName string `xml:"methodName"`
- Params []param `xml:"params"`
-}
-
-// types for XML-RPC responses
-
-type response interface {
- faultCode() int
- faultString() string
-}
-
-type responseFault struct {
- FaultCode int `xml:"fault>value>struct>member>value>int"`
- FaultString string `xml:"fault>value>struct>member>value>string"`
-}
-
-func (r responseFault) faultCode() int { return r.FaultCode }
-func (r responseFault) faultString() string { return r.FaultString }
-
-type responseStruct struct {
- responseFault
- StructMembers []struct {
- Name string `xml:"name"`
- ValueInt int `xml:"value>int"`
- } `xml:"params>param>value>struct>member"`
-}
-
-type responseInt struct {
- responseFault
- Value int `xml:"params>param>value>int"`
-}
-
-type responseBool struct {
- responseFault
- Value bool `xml:"params>param>value>boolean"`
-}
-
-// POSTing/Marshalling/Unmarshalling
-
-type rpcError struct {
- faultCode int
- faultString string
-}
-
-func (e rpcError) Error() string {
- return fmt.Sprintf(
- "Gandi DNS: RPC Error: (%d) %s", e.faultCode, e.faultString)
-}
-
-func httpPost(url string, bodyType string, body io.Reader) ([]byte, error) {
- client := http.Client{Timeout: 60 * time.Second}
- resp, err := client.Post(url, bodyType, body)
- if err != nil {
- return nil, fmt.Errorf("Gandi DNS: HTTP Post Error: %v", err)
- }
- defer resp.Body.Close()
- b, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("Gandi DNS: HTTP Post Error: %v", err)
- }
- return b, nil
-}
-
-// rpcCall makes an XML-RPC call to Gandi's RPC endpoint by
-// marshalling the data given in the call argument to XML and sending
-// that via HTTP Post to Gandi. The response is then unmarshalled into
-// the resp argument.
-func rpcCall(call *methodCall, resp response) error {
- // marshal
- b, err := xml.MarshalIndent(call, "", " ")
- if err != nil {
- return fmt.Errorf("Gandi DNS: Marshal Error: %v", err)
- }
- // post
- b = append([]byte(`<?xml version="1.0"?>`+"\n"), b...)
- respBody, err := httpPost(endpoint, "text/xml", bytes.NewReader(b))
- if err != nil {
- return err
- }
- // unmarshal
- err = xml.Unmarshal(respBody, resp)
- if err != nil {
- return fmt.Errorf("Gandi DNS: Unmarshal Error: %v", err)
- }
- if resp.faultCode() != 0 {
- return rpcError{
- faultCode: resp.faultCode(), faultString: resp.faultString()}
- }
- return nil
-}
-
-// functions to perform API actions
-
-func (d *DNSProvider) getZoneID(domain string) (int, error) {
- resp := &responseStruct{}
- err := rpcCall(&methodCall{
- MethodName: "domain.info",
- Params: []param{
- paramString{Value: d.apiKey},
- paramString{Value: domain},
- },
- }, resp)
- if err != nil {
- return 0, err
- }
- var zoneID int
- for _, member := range resp.StructMembers {
- if member.Name == "zone_id" {
- zoneID = member.ValueInt
- }
- }
- if zoneID == 0 {
- return 0, fmt.Errorf(
- "Gandi DNS: Could not determine zone_id for %s", domain)
- }
- return zoneID, nil
-}
-
-func (d *DNSProvider) cloneZone(zoneID int, name string) (int, error) {
- resp := &responseStruct{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.clone",
- Params: []param{
- paramString{Value: d.apiKey},
- paramInt{Value: zoneID},
- paramInt{Value: 0},
- paramStruct{
- StructMembers: []structMember{
- structMemberString{
- Name: "name",
- Value: name,
- }},
- },
- },
- }, resp)
- if err != nil {
- return 0, err
- }
- var newZoneID int
- for _, member := range resp.StructMembers {
- if member.Name == "id" {
- newZoneID = member.ValueInt
- }
- }
- if newZoneID == 0 {
- return 0, fmt.Errorf("Gandi DNS: Could not determine cloned zone_id")
- }
- return newZoneID, nil
-}
-
-func (d *DNSProvider) newZoneVersion(zoneID int) (int, error) {
- resp := &responseInt{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.version.new",
- Params: []param{
- paramString{Value: d.apiKey},
- paramInt{Value: zoneID},
- },
- }, resp)
- if err != nil {
- return 0, err
- }
- if resp.Value == 0 {
- return 0, fmt.Errorf("Gandi DNS: Could not create new zone version")
- }
- return resp.Value, nil
-}
-
-func (d *DNSProvider) addTXTRecord(zoneID int, version int, name string, value string, ttl int) error {
- resp := &responseStruct{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.record.add",
- Params: []param{
- paramString{Value: d.apiKey},
- paramInt{Value: zoneID},
- paramInt{Value: version},
- paramStruct{
- StructMembers: []structMember{
- structMemberString{
- Name: "type",
- Value: "TXT",
- }, structMemberString{
- Name: "name",
- Value: name,
- }, structMemberString{
- Name: "value",
- Value: value,
- }, structMemberInt{
- Name: "ttl",
- Value: ttl,
- }},
- },
- },
- }, resp)
- if err != nil {
- return err
- }
- return nil
-}
-
-func (d *DNSProvider) setZoneVersion(zoneID int, version int) error {
- resp := &responseBool{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.version.set",
- Params: []param{
- paramString{Value: d.apiKey},
- paramInt{Value: zoneID},
- paramInt{Value: version},
- },
- }, resp)
- if err != nil {
- return err
- }
- if !resp.Value {
- return fmt.Errorf("Gandi DNS: could not set zone version")
- }
- return nil
-}
-
-func (d *DNSProvider) setZone(domain string, zoneID int) error {
- resp := &responseStruct{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.set",
- Params: []param{
- paramString{Value: d.apiKey},
- paramString{Value: domain},
- paramInt{Value: zoneID},
- },
- }, resp)
- if err != nil {
- return err
- }
- var respZoneID int
- for _, member := range resp.StructMembers {
- if member.Name == "zone_id" {
- respZoneID = member.ValueInt
- }
- }
- if respZoneID != zoneID {
- return fmt.Errorf(
- "Gandi DNS: Could not set new zone_id for %s", domain)
- }
- return nil
-}
-
-func (d *DNSProvider) deleteZone(zoneID int) error {
- resp := &responseBool{}
- err := rpcCall(&methodCall{
- MethodName: "domain.zone.delete",
- Params: []param{
- paramString{Value: d.apiKey},
- paramInt{Value: zoneID},
- },
- }, resp)
- if err != nil {
- return err
- }
- if !resp.Value {
- return fmt.Errorf("Gandi DNS: could not delete zone_id")
- }
- return nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi_test.go b/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi_test.go
deleted file mode 100644
index 451333ca1..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/gandi/gandi_test.go
+++ /dev/null
@@ -1,939 +0,0 @@
-package gandi
-
-import (
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- "io"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "os"
- "regexp"
- "strings"
- "testing"
-
- "github.com/xenolf/lego/acme"
-)
-
-// stagingServer is the Let's Encrypt staging server used by the live test
-const stagingServer = "https://acme-staging.api.letsencrypt.org/directory"
-
-// user implements acme.User and is used by the live test
-type user struct {
- Email string
- Registration *acme.RegistrationResource
- key crypto.PrivateKey
-}
-
-func (u *user) GetEmail() string {
- return u.Email
-}
-func (u *user) GetRegistration() *acme.RegistrationResource {
- return u.Registration
-}
-func (u *user) GetPrivateKey() crypto.PrivateKey {
- return u.key
-}
-
-// TestDNSProvider runs Present and CleanUp against a fake Gandi RPC
-// Server, whose responses are predetermined for particular requests.
-func TestDNSProvider(t *testing.T) {
- fakeAPIKey := "123412341234123412341234"
- fakeKeyAuth := "XXXX"
- provider, err := NewDNSProviderCredentials(fakeAPIKey)
- if err != nil {
- t.Fatal(err)
- }
- regexpDate, err := regexp.Compile(`\[ACME Challenge [^\]:]*:[^\]]*\]`)
- if err != nil {
- t.Fatal(err)
- }
- // start fake RPC server
- fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Header.Get("Content-Type") != "text/xml" {
- t.Fatalf("Content-Type: text/xml header not found")
- }
- req, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Fatal(err)
- }
- req = regexpDate.ReplaceAllLiteral(
- req, []byte(`[ACME Challenge 01 Jan 16 00:00 +0000]`))
- resp, ok := serverResponses[string(req)]
- if !ok {
- t.Fatalf("Server response for request not found")
- }
- _, err = io.Copy(w, strings.NewReader(resp))
- if err != nil {
- t.Fatal(err)
- }
- }))
- defer fakeServer.Close()
- // define function to override findZoneByFqdn with
- fakeFindZoneByFqdn := func(fqdn string, nameserver []string) (string, error) {
- return "example.com.", nil
- }
- // override gandi endpoint and findZoneByFqdn function
- savedEndpoint, savedFindZoneByFqdn := endpoint, findZoneByFqdn
- defer func() {
- endpoint, findZoneByFqdn = savedEndpoint, savedFindZoneByFqdn
- }()
- endpoint, findZoneByFqdn = fakeServer.URL+"/", fakeFindZoneByFqdn
- // run Present
- err = provider.Present("abc.def.example.com", "", fakeKeyAuth)
- if err != nil {
- t.Fatal(err)
- }
- // run CleanUp
- err = provider.CleanUp("abc.def.example.com", "", fakeKeyAuth)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-// TestDNSProviderLive performs a live test to obtain a certificate
-// using the Let's Encrypt staging server. It runs provided that both
-// the environment variables GANDI_API_KEY and GANDI_TEST_DOMAIN are
-// set. Otherwise the test is skipped.
-//
-// To complete this test, go test must be run with the -timeout=40m
-// flag, since the default timeout of 10m is insufficient.
-func TestDNSProviderLive(t *testing.T) {
- apiKey := os.Getenv("GANDI_API_KEY")
- domain := os.Getenv("GANDI_TEST_DOMAIN")
- if apiKey == "" || domain == "" {
- t.Skip("skipping live test")
- }
- // create a user.
- const rsaKeySize = 2048
- privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeySize)
- if err != nil {
- t.Fatal(err)
- }
- myUser := user{
- Email: "test@example.com",
- key: privateKey,
- }
- // create a client using staging server
- client, err := acme.NewClient(stagingServer, &myUser, acme.RSA2048)
- if err != nil {
- t.Fatal(err)
- }
- provider, err := NewDNSProviderCredentials(apiKey)
- if err != nil {
- t.Fatal(err)
- }
- err = client.SetChallengeProvider(acme.DNS01, provider)
- if err != nil {
- t.Fatal(err)
- }
- client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSSNI01})
- // register and agree tos
- reg, err := client.Register()
- if err != nil {
- t.Fatal(err)
- }
- myUser.Registration = reg
- err = client.AgreeToTOS()
- if err != nil {
- t.Fatal(err)
- }
- // complete the challenge
- bundle := false
- _, failures := client.ObtainCertificate([]string{domain}, bundle, nil, false)
- if len(failures) > 0 {
- t.Fatal(failures)
- }
-}
-
-// serverResponses is the XML-RPC Request->Response map used by the
-// fake RPC server. It was generated by recording a real RPC session
-// which resulted in the successful issue of a cert, and then
-// anonymizing the RPC data.
-var serverResponses = map[string]string{
- // Present Request->Response 1 (getZoneID)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.info</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <string>example.com.</string>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><struct>
-<member>
-<name>date_updated</name>
-<value><dateTime.iso8601>20160216T16:14:23</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_delete</name>
-<value><dateTime.iso8601>20170331T16:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>is_premium</name>
-<value><boolean>0</boolean></value>
-</member>
-<member>
-<name>date_hold_begin</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_registry_end</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>authinfo_expiration_date</name>
-<value><dateTime.iso8601>20161211T21:31:20</dateTime.iso8601></value>
-</member>
-<member>
-<name>contacts</name>
-<value><struct>
-<member>
-<name>owner</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>admin</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>bill</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>tech</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>reseller</name>
-<value><nil/></value></member>
-</struct></value>
-</member>
-<member>
-<name>nameservers</name>
-<value><array><data>
-<value><string>a.dns.gandi.net</string></value>
-<value><string>b.dns.gandi.net</string></value>
-<value><string>c.dns.gandi.net</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_restore_end</name>
-<value><dateTime.iso8601>20170501T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>id</name>
-<value><int>2222222</int></value>
-</member>
-<member>
-<name>authinfo</name>
-<value><string>ABCDABCDAB</string></value>
-</member>
-<member>
-<name>status</name>
-<value><array><data>
-<value><string>clientTransferProhibited</string></value>
-<value><string>serverTransferProhibited</string></value>
-</data></array></value>
-</member>
-<member>
-<name>tags</name>
-<value><array><data>
-</data></array></value>
-</member>
-<member>
-<name>date_hold_end</name>
-<value><dateTime.iso8601>20170401T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>services</name>
-<value><array><data>
-<value><string>gandidns</string></value>
-<value><string>gandimail</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_pending_delete_end</name>
-<value><dateTime.iso8601>20170506T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>zone_id</name>
-<value><int>1234567</int></value>
-</member>
-<member>
-<name>date_renew_begin</name>
-<value><dateTime.iso8601>20120101T00:00:00</dateTime.iso8601></value>
-</member>
-<member>
-<name>fqdn</name>
-<value><string>example.com</string></value>
-</member>
-<member>
-<name>autorenew</name>
-<value><nil/></value></member>
-<member>
-<name>date_registry_creation</name>
-<value><dateTime.iso8601>20150215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>tld</name>
-<value><string>org</string></value>
-</member>
-<member>
-<name>date_created</name>
-<value><dateTime.iso8601>20150215T03:04:06</dateTime.iso8601></value>
-</member>
-</struct></value>
-</param>
-</params>
-</methodResponse>
-`,
- // Present Request->Response 2 (cloneZone)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.clone</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <int>1234567</int>
- </value>
- </param>
- <param>
- <value>
- <int>0</int>
- </value>
- </param>
- <param>
- <value>
- <struct>
- <member>
- <name>name</name>
- <value>
- <string>example.com [ACME Challenge 01 Jan 16 00:00 +0000]</string>
- </value>
- </member>
- </struct>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><struct>
-<member>
-<name>name</name>
-<value><string>example.com [ACME Challenge 01 Jan 16 00:00 +0000]</string></value>
-</member>
-<member>
-<name>versions</name>
-<value><array><data>
-<value><int>1</int></value>
-</data></array></value>
-</member>
-<member>
-<name>date_updated</name>
-<value><dateTime.iso8601>20160216T16:24:29</dateTime.iso8601></value>
-</member>
-<member>
-<name>id</name>
-<value><int>7654321</int></value>
-</member>
-<member>
-<name>owner</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>version</name>
-<value><int>1</int></value>
-</member>
-<member>
-<name>domains</name>
-<value><int>0</int></value>
-</member>
-<member>
-<name>public</name>
-<value><boolean>0</boolean></value>
-</member>
-</struct></value>
-</param>
-</params>
-</methodResponse>
-`,
- // Present Request->Response 3 (newZoneVersion)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.version.new</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <int>7654321</int>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><int>2</int></value>
-</param>
-</params>
-</methodResponse>
-`,
- // Present Request->Response 4 (addTXTRecord)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.record.add</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <int>7654321</int>
- </value>
- </param>
- <param>
- <value>
- <int>2</int>
- </value>
- </param>
- <param>
- <value>
- <struct>
- <member>
- <name>type</name>
- <value>
- <string>TXT</string>
- </value>
- </member>
- <member>
- <name>name</name>
- <value>
- <string>_acme-challenge.abc.def</string>
- </value>
- </member>
- <member>
- <name>value</name>
- <value>
- <string>ezRpBPY8wH8djMLYjX2uCKPwiKDkFZ1SFMJ6ZXGlHrQ</string>
- </value>
- </member>
- <member>
- <name>ttl</name>
- <value>
- <int>300</int>
- </value>
- </member>
- </struct>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><struct>
-<member>
-<name>name</name>
-<value><string>_acme-challenge.abc.def</string></value>
-</member>
-<member>
-<name>type</name>
-<value><string>TXT</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>333333333</int></value>
-</member>
-<member>
-<name>value</name>
-<value><string>"ezRpBPY8wH8djMLYjX2uCKPwiKDkFZ1SFMJ6ZXGlHrQ"</string></value>
-</member>
-<member>
-<name>ttl</name>
-<value><int>300</int></value>
-</member>
-</struct></value>
-</param>
-</params>
-</methodResponse>
-`,
- // Present Request->Response 5 (setZoneVersion)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.version.set</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <int>7654321</int>
- </value>
- </param>
- <param>
- <value>
- <int>2</int>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><boolean>1</boolean></value>
-</param>
-</params>
-</methodResponse>
-`,
- // Present Request->Response 6 (setZone)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.set</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <string>example.com.</string>
- </value>
- </param>
- <param>
- <value>
- <int>7654321</int>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><struct>
-<member>
-<name>date_updated</name>
-<value><dateTime.iso8601>20160216T16:14:23</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_delete</name>
-<value><dateTime.iso8601>20170331T16:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>is_premium</name>
-<value><boolean>0</boolean></value>
-</member>
-<member>
-<name>date_hold_begin</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_registry_end</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>authinfo_expiration_date</name>
-<value><dateTime.iso8601>20161211T21:31:20</dateTime.iso8601></value>
-</member>
-<member>
-<name>contacts</name>
-<value><struct>
-<member>
-<name>owner</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>admin</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>bill</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>tech</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>reseller</name>
-<value><nil/></value></member>
-</struct></value>
-</member>
-<member>
-<name>nameservers</name>
-<value><array><data>
-<value><string>a.dns.gandi.net</string></value>
-<value><string>b.dns.gandi.net</string></value>
-<value><string>c.dns.gandi.net</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_restore_end</name>
-<value><dateTime.iso8601>20170501T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>id</name>
-<value><int>2222222</int></value>
-</member>
-<member>
-<name>authinfo</name>
-<value><string>ABCDABCDAB</string></value>
-</member>
-<member>
-<name>status</name>
-<value><array><data>
-<value><string>clientTransferProhibited</string></value>
-<value><string>serverTransferProhibited</string></value>
-</data></array></value>
-</member>
-<member>
-<name>tags</name>
-<value><array><data>
-</data></array></value>
-</member>
-<member>
-<name>date_hold_end</name>
-<value><dateTime.iso8601>20170401T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>services</name>
-<value><array><data>
-<value><string>gandidns</string></value>
-<value><string>gandimail</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_pending_delete_end</name>
-<value><dateTime.iso8601>20170506T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>zone_id</name>
-<value><int>7654321</int></value>
-</member>
-<member>
-<name>date_renew_begin</name>
-<value><dateTime.iso8601>20120101T00:00:00</dateTime.iso8601></value>
-</member>
-<member>
-<name>fqdn</name>
-<value><string>example.com</string></value>
-</member>
-<member>
-<name>autorenew</name>
-<value><nil/></value></member>
-<member>
-<name>date_registry_creation</name>
-<value><dateTime.iso8601>20150215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>tld</name>
-<value><string>org</string></value>
-</member>
-<member>
-<name>date_created</name>
-<value><dateTime.iso8601>20150215T03:04:06</dateTime.iso8601></value>
-</member>
-</struct></value>
-</param>
-</params>
-</methodResponse>
-`,
- // CleanUp Request->Response 1 (setZone)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.set</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <string>example.com.</string>
- </value>
- </param>
- <param>
- <value>
- <int>1234567</int>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><struct>
-<member>
-<name>date_updated</name>
-<value><dateTime.iso8601>20160216T16:24:38</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_delete</name>
-<value><dateTime.iso8601>20170331T16:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>is_premium</name>
-<value><boolean>0</boolean></value>
-</member>
-<member>
-<name>date_hold_begin</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>date_registry_end</name>
-<value><dateTime.iso8601>20170215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>authinfo_expiration_date</name>
-<value><dateTime.iso8601>20161211T21:31:20</dateTime.iso8601></value>
-</member>
-<member>
-<name>contacts</name>
-<value><struct>
-<member>
-<name>owner</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>admin</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>bill</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>tech</name>
-<value><struct>
-<member>
-<name>handle</name>
-<value><string>LEGO-GANDI</string></value>
-</member>
-<member>
-<name>id</name>
-<value><int>111111</int></value>
-</member>
-</struct></value>
-</member>
-<member>
-<name>reseller</name>
-<value><nil/></value></member>
-</struct></value>
-</member>
-<member>
-<name>nameservers</name>
-<value><array><data>
-<value><string>a.dns.gandi.net</string></value>
-<value><string>b.dns.gandi.net</string></value>
-<value><string>c.dns.gandi.net</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_restore_end</name>
-<value><dateTime.iso8601>20170501T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>id</name>
-<value><int>2222222</int></value>
-</member>
-<member>
-<name>authinfo</name>
-<value><string>ABCDABCDAB</string></value>
-</member>
-<member>
-<name>status</name>
-<value><array><data>
-<value><string>clientTransferProhibited</string></value>
-<value><string>serverTransferProhibited</string></value>
-</data></array></value>
-</member>
-<member>
-<name>tags</name>
-<value><array><data>
-</data></array></value>
-</member>
-<member>
-<name>date_hold_end</name>
-<value><dateTime.iso8601>20170401T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>services</name>
-<value><array><data>
-<value><string>gandidns</string></value>
-<value><string>gandimail</string></value>
-</data></array></value>
-</member>
-<member>
-<name>date_pending_delete_end</name>
-<value><dateTime.iso8601>20170506T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>zone_id</name>
-<value><int>1234567</int></value>
-</member>
-<member>
-<name>date_renew_begin</name>
-<value><dateTime.iso8601>20120101T00:00:00</dateTime.iso8601></value>
-</member>
-<member>
-<name>fqdn</name>
-<value><string>example.com</string></value>
-</member>
-<member>
-<name>autorenew</name>
-<value><nil/></value></member>
-<member>
-<name>date_registry_creation</name>
-<value><dateTime.iso8601>20150215T02:04:06</dateTime.iso8601></value>
-</member>
-<member>
-<name>tld</name>
-<value><string>org</string></value>
-</member>
-<member>
-<name>date_created</name>
-<value><dateTime.iso8601>20150215T03:04:06</dateTime.iso8601></value>
-</member>
-</struct></value>
-</param>
-</params>
-</methodResponse>
-`,
- // CleanUp Request->Response 2 (deleteZone)
- `<?xml version="1.0"?>
-<methodCall>
- <methodName>domain.zone.delete</methodName>
- <param>
- <value>
- <string>123412341234123412341234</string>
- </value>
- </param>
- <param>
- <value>
- <int>7654321</int>
- </value>
- </param>
-</methodCall>`: `<?xml version='1.0'?>
-<methodResponse>
-<params>
-<param>
-<value><boolean>1</boolean></value>
-</param>
-</params>
-</methodResponse>
-`,
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy.go b/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy.go
deleted file mode 100644
index 4112f6628..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Package godaddy implements a DNS provider for solving the DNS-01 challenge using godaddy DNS.
-package godaddy
-
-import (
- "fmt"
- "io"
- "net/http"
- "os"
- "time"
-
- "bytes"
- "encoding/json"
- "github.com/xenolf/lego/acme"
- "io/ioutil"
- "strings"
-)
-
-// GoDaddyAPIURL represents the API endpoint to call.
-const apiURL = "https://api.godaddy.com"
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-type DNSProvider struct {
- apiKey string
- apiSecret string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for godaddy.
-// Credentials must be passed in the environment variables: GODADDY_API_KEY
-// and GODADDY_API_SECRET.
-func NewDNSProvider() (*DNSProvider, error) {
- apikey := os.Getenv("GODADDY_API_KEY")
- secret := os.Getenv("GODADDY_API_SECRET")
- return NewDNSProviderCredentials(apikey, secret)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for godaddy.
-func NewDNSProviderCredentials(apiKey, apiSecret string) (*DNSProvider, error) {
- if apiKey == "" || apiSecret == "" {
- return nil, fmt.Errorf("GoDaddy credentials missing")
- }
-
- return &DNSProvider{apiKey, apiSecret}, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Adjusting here to cope with spikes in propagation times.
-func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 120 * time.Second, 2 * time.Second
-}
-
-func (c *DNSProvider) extractRecordName(fqdn, domain string) string {
- name := acme.UnFqdn(fqdn)
- if idx := strings.Index(name, "."+domain); idx != -1 {
- return name[:idx]
- }
- return name
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- domainZone, err := c.getZone(fqdn)
- if err != nil {
- return err
- }
-
- if ttl < 600 {
- ttl = 600
- }
-
- recordName := c.extractRecordName(fqdn, domainZone)
- rec := []DNSRecord{
- {
- Type: "TXT",
- Name: recordName,
- Data: value,
- Ttl: ttl,
- },
- }
-
- return c.updateRecords(rec, domainZone, recordName)
-}
-
-func (c *DNSProvider) updateRecords(records []DNSRecord, domainZone string, recordName string) error {
- body, err := json.Marshal(records)
- if err != nil {
- return err
- }
-
- var resp *http.Response
- resp, err = c.makeRequest("PUT", fmt.Sprintf("/v1/domains/%s/records/TXT/%s", domainZone, recordName), bytes.NewReader(body))
- if err != nil {
- return err
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- bodyBytes, _ := ioutil.ReadAll(resp.Body)
- return fmt.Errorf("Could not create record %v; Status: %v; Body: %s\n", string(body), resp.StatusCode, string(bodyBytes))
- }
- return nil
-}
-
-// CleanUp sets null value in the TXT DNS record as GoDaddy has no proper DELETE record method
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
- domainZone, err := c.getZone(fqdn)
- if err != nil {
- return err
- }
-
- recordName := c.extractRecordName(fqdn, domainZone)
- rec := []DNSRecord{
- {
- Type: "TXT",
- Name: recordName,
- Data: "null",
- },
- }
-
- return c.updateRecords(rec, domainZone, recordName)
-}
-
-func (c *DNSProvider) getZone(fqdn string) (string, error) {
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- return acme.UnFqdn(authZone), nil
-}
-
-func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (*http.Response, error) {
- req, err := http.NewRequest(method, fmt.Sprintf("%s%s", apiURL, uri), body)
- if err != nil {
- return nil, err
- }
-
- req.Header.Set("Accept", "application/json")
- req.Header.Set("Content-Type", "application/json")
- req.Header.Set("Authorization", fmt.Sprintf("sso-key %s:%s", c.apiKey, c.apiSecret))
-
- client := http.Client{Timeout: 30 * time.Second}
- return client.Do(req)
-}
-
-type DNSRecord struct {
- Type string `json:"type"`
- Name string `json:"name"`
- Data string `json:"data"`
- Priority int `json:"priority,omitempty"`
- Ttl int `json:"ttl,omitempty"`
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy_test.go b/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy_test.go
deleted file mode 100644
index de84d827e..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/godaddy/godaddy_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package godaddy
-
-import (
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- godaddyAPIKey string
- godaddyAPISecret string
- godaddyDomain string
- godaddyLiveTest bool
-)
-
-func init() {
- godaddyAPIKey = os.Getenv("GODADDY_API_KEY")
- godaddyAPISecret = os.Getenv("GODADDY_API_SECRET")
- godaddyDomain = os.Getenv("GODADDY_DOMAIN")
-
- if len(godaddyAPIKey) > 0 && len(godaddyAPISecret) > 0 && len(godaddyDomain) > 0 {
- godaddyLiveTest = true
- }
-}
-
-func TestNewDNSProvider(t *testing.T) {
- provider, err := NewDNSProvider()
-
- if !godaddyLiveTest {
- assert.Error(t, err)
- } else {
- assert.NotNil(t, provider)
- assert.NoError(t, err)
- }
-}
-
-func TestDNSProvider_Present(t *testing.T) {
- if !godaddyLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.Present(godaddyDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestDNSProvider_CleanUp(t *testing.T) {
- if !godaddyLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.CleanUp(godaddyDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go b/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go
deleted file mode 100644
index ba753f6dc..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Package googlecloud implements a DNS provider for solving the DNS-01
-// challenge using Google Cloud DNS.
-package googlecloud
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "time"
-
- "github.com/xenolf/lego/acme"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
-
- "google.golang.org/api/dns/v1"
-)
-
-// DNSProvider is an implementation of the DNSProvider interface.
-type DNSProvider struct {
- project string
- client *dns.Service
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Google Cloud
-// DNS. Project name must be passed in the environment variable: GCE_PROJECT.
-// A Service Account file can be passed in the environment variable:
-// GCE_SERVICE_ACCOUNT_FILE
-func NewDNSProvider() (*DNSProvider, error) {
- project := os.Getenv("GCE_PROJECT")
- if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok {
- return NewDNSProviderServiceAccount(project, saFile)
- }
- return NewDNSProviderCredentials(project)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Google Cloud DNS.
-func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
- if project == "" {
- return nil, fmt.Errorf("Google Cloud project name missing")
- }
-
- client, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
- if err != nil {
- return nil, fmt.Errorf("Unable to get Google Cloud client: %v", err)
- }
- svc, err := dns.New(client)
- if err != nil {
- return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err)
- }
- return &DNSProvider{
- project: project,
- client: svc,
- }, nil
-}
-
-// NewDNSProviderServiceAccount uses the supplied service account JSON file to
-// return a DNSProvider instance configured for Google Cloud DNS.
-func NewDNSProviderServiceAccount(project string, saFile string) (*DNSProvider, error) {
- if project == "" {
- return nil, fmt.Errorf("Google Cloud project name missing")
- }
- if saFile == "" {
- return nil, fmt.Errorf("Google Cloud Service Account file missing")
- }
-
- dat, err := ioutil.ReadFile(saFile)
- if err != nil {
- return nil, fmt.Errorf("Unable to read Service Account file: %v", err)
- }
- conf, err := google.JWTConfigFromJSON(dat, dns.NdevClouddnsReadwriteScope)
- if err != nil {
- return nil, fmt.Errorf("Unable to acquire config: %v", err)
- }
- client := conf.Client(oauth2.NoContext)
-
- svc, err := dns.New(client)
- if err != nil {
- return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err)
- }
- return &DNSProvider{
- project: project,
- client: svc,
- }, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- rec := &dns.ResourceRecordSet{
- Name: fqdn,
- Rrdatas: []string{value},
- Ttl: int64(ttl),
- Type: "TXT",
- }
- change := &dns.Change{
- Additions: []*dns.ResourceRecordSet{rec},
- }
-
- // Look for existing records.
- list, err := c.client.ResourceRecordSets.List(c.project, zone).Name(fqdn).Type("TXT").Do()
- if err != nil {
- return err
- }
- if len(list.Rrsets) > 0 {
- // Attempt to delete the existing records when adding our new one.
- change.Deletions = list.Rrsets
- }
-
- chg, err := c.client.Changes.Create(c.project, zone, change).Do()
- if err != nil {
- return err
- }
-
- // wait for change to be acknowledged
- for chg.Status == "pending" {
- time.Sleep(time.Second)
-
- chg, err = c.client.Changes.Get(c.project, zone, chg.Id).Do()
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- records, err := c.findTxtRecords(zone, fqdn)
- if err != nil {
- return err
- }
-
- for _, rec := range records {
- change := &dns.Change{
- Deletions: []*dns.ResourceRecordSet{rec},
- }
- _, err = c.client.Changes.Create(c.project, zone, change).Do()
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// Timeout customizes the timeout values used by the ACME package for checking
-// DNS record validity.
-func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 180 * time.Second, 5 * time.Second
-}
-
-// getHostedZone returns the managed-zone
-func (c *DNSProvider) getHostedZone(domain string) (string, error) {
- authZone, err := acme.FindZoneByFqdn(acme.ToFqdn(domain), acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- zones, err := c.client.ManagedZones.
- List(c.project).
- DnsName(authZone).
- Do()
- if err != nil {
- return "", fmt.Errorf("GoogleCloud API call failed: %v", err)
- }
-
- if len(zones.ManagedZones) == 0 {
- return "", fmt.Errorf("No matching GoogleCloud domain found for domain %s", authZone)
- }
-
- return zones.ManagedZones[0].Name, nil
-}
-
-func (c *DNSProvider) findTxtRecords(zone, fqdn string) ([]*dns.ResourceRecordSet, error) {
-
- recs, err := c.client.ResourceRecordSets.List(c.project, zone).Do()
- if err != nil {
- return nil, err
- }
-
- found := []*dns.ResourceRecordSet{}
- for _, r := range recs.Rrsets {
- if r.Type == "TXT" && r.Name == fqdn {
- found = append(found, r)
- }
- }
-
- return found, nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud_test.go b/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud_test.go
deleted file mode 100644
index 75a10d9a4..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud_test.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package googlecloud
-
-import (
- "os"
- "testing"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/google"
- "google.golang.org/api/dns/v1"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- gcloudLiveTest bool
- gcloudProject string
- gcloudDomain string
-)
-
-func init() {
- gcloudProject = os.Getenv("GCE_PROJECT")
- gcloudDomain = os.Getenv("GCE_DOMAIN")
- _, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
- if err == nil && len(gcloudProject) > 0 && len(gcloudDomain) > 0 {
- gcloudLiveTest = true
- }
-}
-
-func restoreGCloudEnv() {
- os.Setenv("GCE_PROJECT", gcloudProject)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- if !gcloudLiveTest {
- t.Skip("skipping live test (requires credentials)")
- }
- os.Setenv("GCE_PROJECT", "")
- _, err := NewDNSProviderCredentials("my-project")
- assert.NoError(t, err)
- restoreGCloudEnv()
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- if !gcloudLiveTest {
- t.Skip("skipping live test (requires credentials)")
- }
- os.Setenv("GCE_PROJECT", "my-project")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restoreGCloudEnv()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("GCE_PROJECT", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "Google Cloud project name missing")
- restoreGCloudEnv()
-}
-
-func TestLiveGoogleCloudPresent(t *testing.T) {
- if !gcloudLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(gcloudProject)
- assert.NoError(t, err)
-
- err = provider.Present(gcloudDomain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveGoogleCloudPresentMultiple(t *testing.T) {
- if !gcloudLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(gcloudProject)
- assert.NoError(t, err)
-
- // Check that we're able to create multiple entries
- err = provider.Present(gcloudDomain, "1", "123d==")
- err = provider.Present(gcloudDomain, "2", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveGoogleCloudCleanUp(t *testing.T) {
- if !gcloudLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProviderCredentials(gcloudProject)
- assert.NoError(t, err)
-
- err = provider.CleanUp(gcloudDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/linode/linode.go b/vendor/github.com/xenolf/lego/providers/dns/linode/linode.go
deleted file mode 100644
index a91d2b489..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/linode/linode.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Package linode implements a DNS provider for solving the DNS-01 challenge
-// using Linode DNS.
-package linode
-
-import (
- "errors"
- "os"
- "strings"
- "time"
-
- "github.com/timewasted/linode/dns"
- "github.com/xenolf/lego/acme"
-)
-
-const (
- dnsMinTTLSecs = 300
- dnsUpdateFreqMins = 15
- dnsUpdateFudgeSecs = 120
-)
-
-type hostedZoneInfo struct {
- domainId int
- resourceName string
-}
-
-// DNSProvider implements the acme.ChallengeProvider interface.
-type DNSProvider struct {
- linode *dns.DNS
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Linode.
-// Credentials must be passed in the environment variable: LINODE_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- apiKey := os.Getenv("LINODE_API_KEY")
- return NewDNSProviderCredentials(apiKey)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Linode.
-func NewDNSProviderCredentials(apiKey string) (*DNSProvider, error) {
- if len(apiKey) == 0 {
- return nil, errors.New("Linode credentials missing")
- }
-
- return &DNSProvider{
- linode: dns.New(apiKey),
- }, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Adjusting here to cope with spikes in propagation times.
-func (p *DNSProvider) Timeout() (timeout, interval time.Duration) {
- // Since Linode only updates their zone files every X minutes, we need
- // to figure out how many minutes we have to wait until we hit the next
- // interval of X. We then wait another couple of minutes, just to be
- // safe. Hopefully at some point during all of this, the record will
- // have propagated throughout Linode's network.
- minsRemaining := dnsUpdateFreqMins - (time.Now().Minute() % dnsUpdateFreqMins)
-
- timeout = (time.Duration(minsRemaining) * time.Minute) +
- (dnsMinTTLSecs * time.Second) +
- (dnsUpdateFudgeSecs * time.Second)
- interval = 15 * time.Second
- return
-}
-
-// Present creates a TXT record using the specified parameters.
-func (p *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zone, err := p.getHostedZoneInfo(fqdn)
- if err != nil {
- return err
- }
-
- if _, err = p.linode.CreateDomainResourceTXT(zone.domainId, acme.UnFqdn(fqdn), value, 60); err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (p *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zone, err := p.getHostedZoneInfo(fqdn)
- if err != nil {
- return err
- }
-
- // Get all TXT records for the specified domain.
- resources, err := p.linode.GetResourcesByType(zone.domainId, "TXT")
- if err != nil {
- return err
- }
-
- // Remove the specified resource, if it exists.
- for _, resource := range resources {
- if resource.Name == zone.resourceName && resource.Target == value {
- resp, err := p.linode.DeleteDomainResource(resource.DomainID, resource.ResourceID)
- if err != nil {
- return err
- }
- if resp.ResourceID != resource.ResourceID {
- return errors.New("Error deleting resource: resource IDs do not match!")
- }
- break
- }
- }
-
- return nil
-}
-
-func (p *DNSProvider) getHostedZoneInfo(fqdn string) (*hostedZoneInfo, error) {
- // Lookup the zone that handles the specified FQDN.
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return nil, err
- }
- resourceName := strings.TrimSuffix(fqdn, "."+authZone)
-
- // Query the authority zone.
- domain, err := p.linode.GetDomain(acme.UnFqdn(authZone))
- if err != nil {
- return nil, err
- }
-
- return &hostedZoneInfo{
- domainId: domain.DomainID,
- resourceName: resourceName,
- }, nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/linode/linode_test.go b/vendor/github.com/xenolf/lego/providers/dns/linode/linode_test.go
deleted file mode 100644
index d9713a275..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/linode/linode_test.go
+++ /dev/null
@@ -1,317 +0,0 @@
-package linode
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
- "net/http/httptest"
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/timewasted/linode"
- "github.com/timewasted/linode/dns"
-)
-
-type (
- LinodeResponse struct {
- Action string `json:"ACTION"`
- Data interface{} `json:"DATA"`
- Errors []linode.ResponseError `json:"ERRORARRAY"`
- }
- MockResponse struct {
- Response interface{}
- Errors []linode.ResponseError
- }
- MockResponseMap map[string]MockResponse
-)
-
-var (
- apiKey string
- isTestLive bool
-)
-
-func init() {
- apiKey = os.Getenv("LINODE_API_KEY")
- isTestLive = len(apiKey) != 0
-}
-
-func restoreEnv() {
- os.Setenv("LINODE_API_KEY", apiKey)
-}
-
-func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server {
- srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- // Ensure that we support the requested action.
- action := r.URL.Query().Get("api_action")
- resp, ok := responses[action]
- if !ok {
- msg := fmt.Sprintf("Unsupported mock action: %s", action)
- require.FailNow(t, msg)
- }
-
- // Build the response that the server will return.
- linodeResponse := LinodeResponse{
- Action: action,
- Data: resp.Response,
- Errors: resp.Errors,
- }
- rawResponse, err := json.Marshal(linodeResponse)
- if err != nil {
- msg := fmt.Sprintf("Failed to JSON encode response: %v", err)
- require.FailNow(t, msg)
- }
-
- // Send the response.
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusOK)
- w.Write(rawResponse)
- }))
-
- time.Sleep(100 * time.Millisecond)
- return srv
-}
-
-func TestNewDNSProviderWithEnv(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderWithoutEnv(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "Linode credentials missing")
-}
-
-func TestNewDNSProviderCredentialsWithKey(t *testing.T) {
- _, err := NewDNSProviderCredentials("testing")
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderCredentialsWithoutKey(t *testing.T) {
- _, err := NewDNSProviderCredentials("")
- assert.EqualError(t, err, "Linode credentials missing")
-}
-
-func TestDNSProvider_Present(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: domain,
- DomainID: 1234,
- },
- },
- },
- "domain.resource.create": MockResponse{
- Response: dns.ResourceResponse{
- ResourceID: 1234,
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.Present(domain, "", keyAuth)
- assert.NoError(t, err)
-}
-
-func TestDNSProvider_PresentNoDomain(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: "foobar.com",
- DomainID: 1234,
- },
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.Present(domain, "", keyAuth)
- assert.EqualError(t, err, "dns: requested domain not found")
-}
-
-func TestDNSProvider_PresentCreateFailed(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: domain,
- DomainID: 1234,
- },
- },
- },
- "domain.resource.create": MockResponse{
- Response: nil,
- Errors: []linode.ResponseError{
- linode.ResponseError{
- Code: 1234,
- Message: "Failed to create domain resource",
- },
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.Present(domain, "", keyAuth)
- assert.EqualError(t, err, "Failed to create domain resource")
-}
-
-func TestDNSProvider_PresentLive(t *testing.T) {
- if !isTestLive {
- t.Skip("Skipping live test")
- }
-}
-
-func TestDNSProvider_CleanUp(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: domain,
- DomainID: 1234,
- },
- },
- },
- "domain.resource.list": MockResponse{
- Response: []dns.Resource{
- dns.Resource{
- DomainID: 1234,
- Name: "_acme-challenge",
- ResourceID: 1234,
- Target: "ElbOJKOkFWiZLQeoxf-wb3IpOsQCdvoM0y_wn0TEkxM",
- Type: "TXT",
- },
- },
- },
- "domain.resource.delete": MockResponse{
- Response: dns.ResourceResponse{
- ResourceID: 1234,
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.CleanUp(domain, "", keyAuth)
- assert.NoError(t, err)
-}
-
-func TestDNSProvider_CleanUpNoDomain(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: "foobar.com",
- DomainID: 1234,
- },
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.CleanUp(domain, "", keyAuth)
- assert.EqualError(t, err, "dns: requested domain not found")
-}
-
-func TestDNSProvider_CleanUpDeleteFailed(t *testing.T) {
- os.Setenv("LINODE_API_KEY", "testing")
- defer restoreEnv()
- p, err := NewDNSProvider()
- assert.NoError(t, err)
-
- domain := "example.com"
- keyAuth := "dGVzdGluZw=="
- mockResponses := MockResponseMap{
- "domain.list": MockResponse{
- Response: []dns.Domain{
- dns.Domain{
- Domain: domain,
- DomainID: 1234,
- },
- },
- },
- "domain.resource.list": MockResponse{
- Response: []dns.Resource{
- dns.Resource{
- DomainID: 1234,
- Name: "_acme-challenge",
- ResourceID: 1234,
- Target: "ElbOJKOkFWiZLQeoxf-wb3IpOsQCdvoM0y_wn0TEkxM",
- Type: "TXT",
- },
- },
- },
- "domain.resource.delete": MockResponse{
- Response: nil,
- Errors: []linode.ResponseError{
- linode.ResponseError{
- Code: 1234,
- Message: "Failed to delete domain resource",
- },
- },
- },
- }
- mockSrv := newMockServer(t, mockResponses)
- defer mockSrv.Close()
- p.linode.ToLinode().SetEndpoint(mockSrv.URL)
-
- err = p.CleanUp(domain, "", keyAuth)
- assert.EqualError(t, err, "Failed to delete domain resource")
-}
-
-func TestDNSProvider_CleanUpLive(t *testing.T) {
- if !isTestLive {
- t.Skip("Skipping live test")
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go b/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go
deleted file mode 100644
index d7eb40935..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap.go
+++ /dev/null
@@ -1,416 +0,0 @@
-// Package namecheap implements a DNS provider for solving the DNS-01
-// challenge using namecheap DNS.
-package namecheap
-
-import (
- "encoding/xml"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/url"
- "os"
- "strings"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// Notes about namecheap's tool API:
-// 1. Using the API requires registration. Once registered, use your account
-// name and API key to access the API.
-// 2. There is no API to add or modify a single DNS record. Instead you must
-// read the entire list of records, make modifications, and then write the
-// entire updated list of records. (Yuck.)
-// 3. Namecheap's DNS updates can be slow to propagate. I've seen them take
-// as long as an hour.
-// 4. Namecheap requires you to whitelist the IP address from which you call
-// its APIs. It also requires all API calls to include the whitelisted IP
-// address as a form or query string value. This code uses a namecheap
-// service to query the client's IP address.
-
-var (
- debug = false
- defaultBaseURL = "https://api.namecheap.com/xml.response"
- getIPURL = "https://dynamicdns.park-your-domain.com/getip"
- httpClient = http.Client{Timeout: 60 * time.Second}
-)
-
-// DNSProvider is an implementation of the ChallengeProviderTimeout interface
-// that uses Namecheap's tool API to manage TXT records for a domain.
-type DNSProvider struct {
- baseURL string
- apiUser string
- apiKey string
- clientIP string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for namecheap.
-// Credentials must be passed in the environment variables: NAMECHEAP_API_USER
-// and NAMECHEAP_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- apiUser := os.Getenv("NAMECHEAP_API_USER")
- apiKey := os.Getenv("NAMECHEAP_API_KEY")
- return NewDNSProviderCredentials(apiUser, apiKey)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for namecheap.
-func NewDNSProviderCredentials(apiUser, apiKey string) (*DNSProvider, error) {
- if apiUser == "" || apiKey == "" {
- return nil, fmt.Errorf("Namecheap credentials missing")
- }
-
- clientIP, err := getClientIP()
- if err != nil {
- return nil, err
- }
-
- return &DNSProvider{
- baseURL: defaultBaseURL,
- apiUser: apiUser,
- apiKey: apiKey,
- clientIP: clientIP,
- }, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Namecheap can sometimes take a long time to complete an
-// update, so wait up to 60 minutes for the update to propagate.
-func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 60 * time.Minute, 15 * time.Second
-}
-
-// host describes a DNS record returned by the Namecheap DNS gethosts API.
-// Namecheap uses the term "host" to refer to all DNS records that include
-// a host field (A, AAAA, CNAME, NS, TXT, URL).
-type host struct {
- Type string `xml:",attr"`
- Name string `xml:",attr"`
- Address string `xml:",attr"`
- MXPref string `xml:",attr"`
- TTL string `xml:",attr"`
-}
-
-// apierror describes an error record in a namecheap API response.
-type apierror struct {
- Number int `xml:",attr"`
- Description string `xml:",innerxml"`
-}
-
-// getClientIP returns the client's public IP address. It uses namecheap's
-// IP discovery service to perform the lookup.
-func getClientIP() (addr string, err error) {
- resp, err := httpClient.Get(getIPURL)
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
-
- clientIP, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return "", err
- }
-
- if debug {
- fmt.Println("Client IP:", string(clientIP))
- }
- return string(clientIP), nil
-}
-
-// A challenge repesents all the data needed to specify a dns-01 challenge
-// to lets-encrypt.
-type challenge struct {
- domain string
- key string
- keyFqdn string
- keyValue string
- tld string
- sld string
- host string
-}
-
-// newChallenge builds a challenge record from a domain name, a challenge
-// authentication key, and a map of available TLDs.
-func newChallenge(domain, keyAuth string, tlds map[string]string) (*challenge, error) {
- domain = acme.UnFqdn(domain)
- parts := strings.Split(domain, ".")
-
- // Find the longest matching TLD.
- longest := -1
- for i := len(parts); i > 0; i-- {
- t := strings.Join(parts[i-1:], ".")
- if _, found := tlds[t]; found {
- longest = i - 1
- }
- }
- if longest < 1 {
- return nil, fmt.Errorf("Invalid domain name '%s'", domain)
- }
-
- tld := strings.Join(parts[longest:], ".")
- sld := parts[longest-1]
-
- var host string
- if longest >= 1 {
- host = strings.Join(parts[:longest-1], ".")
- }
-
- key, keyValue, _ := acme.DNS01Record(domain, keyAuth)
-
- return &challenge{
- domain: domain,
- key: "_acme-challenge." + host,
- keyFqdn: key,
- keyValue: keyValue,
- tld: tld,
- sld: sld,
- host: host,
- }, nil
-}
-
-// setGlobalParams adds the namecheap global parameters to the provided url
-// Values record.
-func (d *DNSProvider) setGlobalParams(v *url.Values, cmd string) {
- v.Set("ApiUser", d.apiUser)
- v.Set("ApiKey", d.apiKey)
- v.Set("UserName", d.apiUser)
- v.Set("ClientIp", d.clientIP)
- v.Set("Command", cmd)
-}
-
-// getTLDs requests the list of available TLDs from namecheap.
-func (d *DNSProvider) getTLDs() (tlds map[string]string, err error) {
- values := make(url.Values)
- d.setGlobalParams(&values, "namecheap.domains.getTldList")
-
- reqURL, _ := url.Parse(d.baseURL)
- reqURL.RawQuery = values.Encode()
-
- resp, err := httpClient.Get(reqURL.String())
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return nil, fmt.Errorf("getHosts HTTP error %d", resp.StatusCode)
- }
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
-
- type GetTldsResponse struct {
- XMLName xml.Name `xml:"ApiResponse"`
- Errors []apierror `xml:"Errors>Error"`
- Result []struct {
- Name string `xml:",attr"`
- } `xml:"CommandResponse>Tlds>Tld"`
- }
-
- var gtr GetTldsResponse
- if err := xml.Unmarshal(body, &gtr); err != nil {
- return nil, err
- }
- if len(gtr.Errors) > 0 {
- return nil, fmt.Errorf("Namecheap error: %s [%d]",
- gtr.Errors[0].Description, gtr.Errors[0].Number)
- }
-
- tlds = make(map[string]string)
- for _, t := range gtr.Result {
- tlds[t.Name] = t.Name
- }
- return tlds, nil
-}
-
-// getHosts reads the full list of DNS host records using the Namecheap API.
-func (d *DNSProvider) getHosts(ch *challenge) (hosts []host, err error) {
- values := make(url.Values)
- d.setGlobalParams(&values, "namecheap.domains.dns.getHosts")
- values.Set("SLD", ch.sld)
- values.Set("TLD", ch.tld)
-
- reqURL, _ := url.Parse(d.baseURL)
- reqURL.RawQuery = values.Encode()
-
- resp, err := httpClient.Get(reqURL.String())
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return nil, fmt.Errorf("getHosts HTTP error %d", resp.StatusCode)
- }
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
-
- type GetHostsResponse struct {
- XMLName xml.Name `xml:"ApiResponse"`
- Status string `xml:"Status,attr"`
- Errors []apierror `xml:"Errors>Error"`
- Hosts []host `xml:"CommandResponse>DomainDNSGetHostsResult>host"`
- }
-
- var ghr GetHostsResponse
- if err = xml.Unmarshal(body, &ghr); err != nil {
- return nil, err
- }
- if len(ghr.Errors) > 0 {
- return nil, fmt.Errorf("Namecheap error: %s [%d]",
- ghr.Errors[0].Description, ghr.Errors[0].Number)
- }
-
- return ghr.Hosts, nil
-}
-
-// setHosts writes the full list of DNS host records using the Namecheap API.
-func (d *DNSProvider) setHosts(ch *challenge, hosts []host) error {
- values := make(url.Values)
- d.setGlobalParams(&values, "namecheap.domains.dns.setHosts")
- values.Set("SLD", ch.sld)
- values.Set("TLD", ch.tld)
-
- for i, h := range hosts {
- ind := fmt.Sprintf("%d", i+1)
- values.Add("HostName"+ind, h.Name)
- values.Add("RecordType"+ind, h.Type)
- values.Add("Address"+ind, h.Address)
- values.Add("MXPref"+ind, h.MXPref)
- values.Add("TTL"+ind, h.TTL)
- }
-
- resp, err := httpClient.PostForm(d.baseURL, values)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return fmt.Errorf("setHosts HTTP error %d", resp.StatusCode)
- }
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return err
- }
-
- type SetHostsResponse struct {
- XMLName xml.Name `xml:"ApiResponse"`
- Status string `xml:"Status,attr"`
- Errors []apierror `xml:"Errors>Error"`
- Result struct {
- IsSuccess string `xml:",attr"`
- } `xml:"CommandResponse>DomainDNSSetHostsResult"`
- }
-
- var shr SetHostsResponse
- if err := xml.Unmarshal(body, &shr); err != nil {
- return err
- }
- if len(shr.Errors) > 0 {
- return fmt.Errorf("Namecheap error: %s [%d]",
- shr.Errors[0].Description, shr.Errors[0].Number)
- }
- if shr.Result.IsSuccess != "true" {
- return fmt.Errorf("Namecheap setHosts failed.")
- }
-
- return nil
-}
-
-// addChallengeRecord adds a DNS challenge TXT record to a list of namecheap
-// host records.
-func (d *DNSProvider) addChallengeRecord(ch *challenge, hosts *[]host) {
- host := host{
- Name: ch.key,
- Type: "TXT",
- Address: ch.keyValue,
- MXPref: "10",
- TTL: "120",
- }
-
- // If there's already a TXT record with the same name, replace it.
- for i, h := range *hosts {
- if h.Name == ch.key && h.Type == "TXT" {
- (*hosts)[i] = host
- return
- }
- }
-
- // No record was replaced, so add a new one.
- *hosts = append(*hosts, host)
-}
-
-// removeChallengeRecord removes a DNS challenge TXT record from a list of
-// namecheap host records. Return true if a record was removed.
-func (d *DNSProvider) removeChallengeRecord(ch *challenge, hosts *[]host) bool {
- // Find the challenge TXT record and remove it if found.
- for i, h := range *hosts {
- if h.Name == ch.key && h.Type == "TXT" {
- *hosts = append((*hosts)[:i], (*hosts)[i+1:]...)
- return true
- }
- }
-
- return false
-}
-
-// Present installs a TXT record for the DNS challenge.
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
- tlds, err := d.getTLDs()
- if err != nil {
- return err
- }
-
- ch, err := newChallenge(domain, keyAuth, tlds)
- if err != nil {
- return err
- }
-
- hosts, err := d.getHosts(ch)
- if err != nil {
- return err
- }
-
- d.addChallengeRecord(ch, &hosts)
-
- if debug {
- for _, h := range hosts {
- fmt.Printf(
- "%-5.5s %-30.30s %-6s %-70.70s\n",
- h.Type, h.Name, h.TTL, h.Address)
- }
- }
-
- return d.setHosts(ch, hosts)
-}
-
-// CleanUp removes a TXT record used for a previous DNS challenge.
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- tlds, err := d.getTLDs()
- if err != nil {
- return err
- }
-
- ch, err := newChallenge(domain, keyAuth, tlds)
- if err != nil {
- return err
- }
-
- hosts, err := d.getHosts(ch)
- if err != nil {
- return err
- }
-
- if removed := d.removeChallengeRecord(ch, &hosts); !removed {
- return nil
- }
-
- return d.setHosts(ch, hosts)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap_test.go b/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap_test.go
deleted file mode 100644
index 0631d4a3e..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/namecheap/namecheap_test.go
+++ /dev/null
@@ -1,402 +0,0 @@
-package namecheap
-
-import (
- "fmt"
- "net/http"
- "net/http/httptest"
- "net/url"
- "testing"
-)
-
-var (
- fakeUser = "foo"
- fakeKey = "bar"
- fakeClientIP = "10.0.0.1"
-
- tlds = map[string]string{
- "com.au": "com.au",
- "com": "com",
- "co.uk": "co.uk",
- "uk": "uk",
- "edu": "edu",
- "co.com": "co.com",
- "za.com": "za.com",
- }
-)
-
-func assertEq(t *testing.T, variable, got, want string) {
- if got != want {
- t.Errorf("Expected %s to be '%s' but got '%s'", variable, want, got)
- }
-}
-
-func assertHdr(tc *testcase, t *testing.T, values *url.Values) {
- ch, _ := newChallenge(tc.domain, "", tlds)
-
- assertEq(t, "ApiUser", values.Get("ApiUser"), fakeUser)
- assertEq(t, "ApiKey", values.Get("ApiKey"), fakeKey)
- assertEq(t, "UserName", values.Get("UserName"), fakeUser)
- assertEq(t, "ClientIp", values.Get("ClientIp"), fakeClientIP)
- assertEq(t, "SLD", values.Get("SLD"), ch.sld)
- assertEq(t, "TLD", values.Get("TLD"), ch.tld)
-}
-
-func mockServer(tc *testcase, t *testing.T, w http.ResponseWriter, r *http.Request) {
- switch r.Method {
-
- case "GET":
- values := r.URL.Query()
- cmd := values.Get("Command")
- switch cmd {
- case "namecheap.domains.dns.getHosts":
- assertHdr(tc, t, &values)
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, tc.getHostsResponse)
- case "namecheap.domains.getTldList":
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, responseGetTlds)
- default:
- t.Errorf("Unexpected GET command: %s", cmd)
- }
-
- case "POST":
- r.ParseForm()
- values := r.Form
- cmd := values.Get("Command")
- switch cmd {
- case "namecheap.domains.dns.setHosts":
- assertHdr(tc, t, &values)
- w.WriteHeader(http.StatusOK)
- fmt.Fprint(w, tc.setHostsResponse)
- default:
- t.Errorf("Unexpected POST command: %s", cmd)
- }
-
- default:
- t.Errorf("Unexpected http method: %s", r.Method)
-
- }
-}
-
-func testGetHosts(tc *testcase, t *testing.T) {
- mock := httptest.NewServer(http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- mockServer(tc, t, w, r)
- }))
- defer mock.Close()
-
- prov := &DNSProvider{
- baseURL: mock.URL,
- apiUser: fakeUser,
- apiKey: fakeKey,
- clientIP: fakeClientIP,
- }
-
- ch, _ := newChallenge(tc.domain, "", tlds)
- hosts, err := prov.getHosts(ch)
- if tc.errString != "" {
- if err == nil || err.Error() != tc.errString {
- t.Errorf("Namecheap getHosts case %s expected error", tc.name)
- }
- } else {
- if err != nil {
- t.Errorf("Namecheap getHosts case %s failed\n%v", tc.name, err)
- }
- }
-
-next1:
- for _, h := range hosts {
- for _, th := range tc.hosts {
- if h == th {
- continue next1
- }
- }
- t.Errorf("getHosts case %s unexpected record [%s:%s:%s]",
- tc.name, h.Type, h.Name, h.Address)
- }
-
-next2:
- for _, th := range tc.hosts {
- for _, h := range hosts {
- if h == th {
- continue next2
- }
- }
- t.Errorf("getHosts case %s missing record [%s:%s:%s]",
- tc.name, th.Type, th.Name, th.Address)
- }
-}
-
-func mockDNSProvider(url string) *DNSProvider {
- return &DNSProvider{
- baseURL: url,
- apiUser: fakeUser,
- apiKey: fakeKey,
- clientIP: fakeClientIP,
- }
-}
-
-func testSetHosts(tc *testcase, t *testing.T) {
- mock := httptest.NewServer(http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- mockServer(tc, t, w, r)
- }))
- defer mock.Close()
-
- prov := mockDNSProvider(mock.URL)
- ch, _ := newChallenge(tc.domain, "", tlds)
- hosts, err := prov.getHosts(ch)
- if tc.errString != "" {
- if err == nil || err.Error() != tc.errString {
- t.Errorf("Namecheap getHosts case %s expected error", tc.name)
- }
- } else {
- if err != nil {
- t.Errorf("Namecheap getHosts case %s failed\n%v", tc.name, err)
- }
- }
- if err != nil {
- return
- }
-
- err = prov.setHosts(ch, hosts)
- if err != nil {
- t.Errorf("Namecheap setHosts case %s failed", tc.name)
- }
-}
-
-func testPresent(tc *testcase, t *testing.T) {
- mock := httptest.NewServer(http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- mockServer(tc, t, w, r)
- }))
- defer mock.Close()
-
- prov := mockDNSProvider(mock.URL)
- err := prov.Present(tc.domain, "", "dummyKey")
- if tc.errString != "" {
- if err == nil || err.Error() != tc.errString {
- t.Errorf("Namecheap Present case %s expected error", tc.name)
- }
- } else {
- if err != nil {
- t.Errorf("Namecheap Present case %s failed\n%v", tc.name, err)
- }
- }
-}
-
-func testCleanUp(tc *testcase, t *testing.T) {
- mock := httptest.NewServer(http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- mockServer(tc, t, w, r)
- }))
- defer mock.Close()
-
- prov := mockDNSProvider(mock.URL)
- err := prov.CleanUp(tc.domain, "", "dummyKey")
- if tc.errString != "" {
- if err == nil || err.Error() != tc.errString {
- t.Errorf("Namecheap CleanUp case %s expected error", tc.name)
- }
- } else {
- if err != nil {
- t.Errorf("Namecheap CleanUp case %s failed\n%v", tc.name, err)
- }
- }
-}
-
-func TestNamecheap(t *testing.T) {
- for _, tc := range testcases {
- testGetHosts(&tc, t)
- testSetHosts(&tc, t)
- testPresent(&tc, t)
- testCleanUp(&tc, t)
- }
-}
-
-func TestNamecheapDomainSplit(t *testing.T) {
- tests := []struct {
- domain string
- valid bool
- tld string
- sld string
- host string
- }{
- {"a.b.c.test.co.uk", true, "co.uk", "test", "a.b.c"},
- {"test.co.uk", true, "co.uk", "test", ""},
- {"test.com", true, "com", "test", ""},
- {"test.co.com", true, "co.com", "test", ""},
- {"www.test.com.au", true, "com.au", "test", "www"},
- {"www.za.com", true, "za.com", "www", ""},
- {"", false, "", "", ""},
- {"a", false, "", "", ""},
- {"com", false, "", "", ""},
- {"co.com", false, "", "", ""},
- {"co.uk", false, "", "", ""},
- {"test.au", false, "", "", ""},
- {"za.com", false, "", "", ""},
- {"www.za", false, "", "", ""},
- {"www.test.au", false, "", "", ""},
- {"www.test.unk", false, "", "", ""},
- }
-
- for _, test := range tests {
- valid := true
- ch, err := newChallenge(test.domain, "", tlds)
- if err != nil {
- valid = false
- }
-
- if test.valid && !valid {
- t.Errorf("Expected '%s' to split", test.domain)
- } else if !test.valid && valid {
- t.Errorf("Expected '%s' to produce error", test.domain)
- }
-
- if test.valid && valid {
- assertEq(t, "domain", ch.domain, test.domain)
- assertEq(t, "tld", ch.tld, test.tld)
- assertEq(t, "sld", ch.sld, test.sld)
- assertEq(t, "host", ch.host, test.host)
- }
- }
-}
-
-type testcase struct {
- name string
- domain string
- hosts []host
- errString string
- getHostsResponse string
- setHostsResponse string
-}
-
-var testcases = []testcase{
- {
- "Test:Success:1",
- "test.example.com",
- []host{
- {"A", "home", "10.0.0.1", "10", "1799"},
- {"A", "www", "10.0.0.2", "10", "1200"},
- {"AAAA", "a", "::0", "10", "1799"},
- {"CNAME", "*", "example.com.", "10", "1799"},
- {"MXE", "example.com", "10.0.0.5", "10", "1800"},
- {"URL", "xyz", "https://google.com", "10", "1799"},
- },
- "",
- responseGetHostsSuccess1,
- responseSetHostsSuccess1,
- },
- {
- "Test:Success:2",
- "example.com",
- []host{
- {"A", "@", "10.0.0.2", "10", "1200"},
- {"A", "www", "10.0.0.3", "10", "60"},
- },
- "",
- responseGetHostsSuccess2,
- responseSetHostsSuccess2,
- },
- {
- "Test:Error:BadApiKey:1",
- "test.example.com",
- nil,
- "Namecheap error: API Key is invalid or API access has not been enabled [1011102]",
- responseGetHostsErrorBadAPIKey1,
- "",
- },
-}
-
-var responseGetHostsSuccess1 = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
- <Errors />
- <Warnings />
- <RequestedCommand>namecheap.domains.dns.getHosts</RequestedCommand>
- <CommandResponse Type="namecheap.domains.dns.getHosts">
- <DomainDNSGetHostsResult Domain="example.com" EmailType="MXE" IsUsingOurDNS="true">
- <host HostId="217076" Name="www" Type="A" Address="10.0.0.2" MXPref="10" TTL="1200" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217069" Name="home" Type="A" Address="10.0.0.1" MXPref="10" TTL="1799" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217071" Name="a" Type="AAAA" Address="::0" MXPref="10" TTL="1799" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217075" Name="*" Type="CNAME" Address="example.com." MXPref="10" TTL="1799" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217073" Name="example.com" Type="MXE" Address="10.0.0.5" MXPref="10" TTL="1800" AssociatedAppTitle="MXE" FriendlyName="MXE1" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217077" Name="xyz" Type="URL" Address="https://google.com" MXPref="10" TTL="1799" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- </DomainDNSGetHostsResult>
- </CommandResponse>
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>3.338</ExecutionTime>
-</ApiResponse>`
-
-var responseSetHostsSuccess1 = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
- <Errors />
- <Warnings />
- <RequestedCommand>namecheap.domains.dns.setHosts</RequestedCommand>
- <CommandResponse Type="namecheap.domains.dns.setHosts">
- <DomainDNSSetHostsResult Domain="example.com" IsSuccess="true">
- <Warnings />
- </DomainDNSSetHostsResult>
- </CommandResponse>
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>2.347</ExecutionTime>
-</ApiResponse>`
-
-var responseGetHostsSuccess2 = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
- <Errors />
- <Warnings />
- <RequestedCommand>namecheap.domains.dns.getHosts</RequestedCommand>
- <CommandResponse Type="namecheap.domains.dns.getHosts">
- <DomainDNSGetHostsResult Domain="example.com" EmailType="MXE" IsUsingOurDNS="true">
- <host HostId="217076" Name="@" Type="A" Address="10.0.0.2" MXPref="10" TTL="1200" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- <host HostId="217069" Name="www" Type="A" Address="10.0.0.3" MXPref="10" TTL="60" AssociatedAppTitle="" FriendlyName="" IsActive="true" IsDDNSEnabled="false" />
- </DomainDNSGetHostsResult>
- </CommandResponse>
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>3.338</ExecutionTime>
-</ApiResponse>`
-
-var responseSetHostsSuccess2 = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
- <Errors />
- <Warnings />
- <RequestedCommand>namecheap.domains.dns.setHosts</RequestedCommand>
- <CommandResponse Type="namecheap.domains.dns.setHosts">
- <DomainDNSSetHostsResult Domain="example.com" IsSuccess="true">
- <Warnings />
- </DomainDNSSetHostsResult>
- </CommandResponse>
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>2.347</ExecutionTime>
-</ApiResponse>`
-
-var responseGetHostsErrorBadAPIKey1 = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
- <Errors>
- <Error Number="1011102">API Key is invalid or API access has not been enabled</Error>
- </Errors>
- <Warnings />
- <RequestedCommand />
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>0</ExecutionTime>
-</ApiResponse>`
-
-var responseGetTlds = `<?xml version="1.0" encoding="utf-8"?>
-<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
- <Errors />
- <Warnings />
- <RequestedCommand>namecheap.domains.getTldList</RequestedCommand>
- <CommandResponse Type="namecheap.domains.getTldList">
- <Tlds>
- <Tld Name="com" NonRealTime="false" MinRegisterYears="1" MaxRegisterYears="10" MinRenewYears="1" MaxRenewYears="10" RenewalMinDays="0" RenewalMaxDays="4000" ReactivateMaxDays="27" MinTransferYears="1" MaxTransferYears="1" IsApiRegisterable="true" IsApiRenewable="true" IsApiTransferable="true" IsEppRequired="true" IsDisableModContact="false" IsDisableWGAllot="false" IsIncludeInExtendedSearchOnly="false" SequenceNumber="10" Type="GTLD" SubType="" IsSupportsIDN="true" Category="A" SupportsRegistrarLock="true" AddGracePeriodDays="5" WhoisVerification="false" ProviderApiDelete="true" TldState="" SearchGroup="" Registry="">Most recognized top level domain<Categories><TldCategory Name="popular" SequenceNumber="10" /></Categories></Tld>
- </Tlds>
- </CommandResponse>
- <Server>PHX01SBAPI01</Server>
- <GMTTimeDifference>--5:00</GMTTimeDifference>
- <ExecutionTime>0.004</ExecutionTime>
-</ApiResponse>`
diff --git a/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1.go b/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1.go
deleted file mode 100644
index 105d73f89..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Package ns1 implements a DNS provider for solving the DNS-01 challenge
-// using NS1 DNS.
-package ns1
-
-import (
- "fmt"
- "net/http"
- "os"
- "time"
-
- "github.com/xenolf/lego/acme"
- "gopkg.in/ns1/ns1-go.v2/rest"
- "gopkg.in/ns1/ns1-go.v2/rest/model/dns"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface.
-type DNSProvider struct {
- client *rest.Client
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for NS1.
-// Credentials must be passed in the environment variables: NS1_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- key := os.Getenv("NS1_API_KEY")
- if key == "" {
- return nil, fmt.Errorf("NS1 credentials missing")
- }
- return NewDNSProviderCredentials(key)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for NS1.
-func NewDNSProviderCredentials(key string) (*DNSProvider, error) {
- if key == "" {
- return nil, fmt.Errorf("NS1 credentials missing")
- }
-
- httpClient := &http.Client{Timeout: time.Second * 10}
- client := rest.NewClient(httpClient, rest.SetAPIKey(key))
-
- return &DNSProvider{client}, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- record := c.newTxtRecord(zone, fqdn, value, ttl)
- _, err = c.client.Records.Create(record)
- if err != nil && err != rest.ErrRecordExists {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- name := acme.UnFqdn(fqdn)
- _, err = c.client.Records.Delete(zone.Zone, name, "TXT")
- return err
-}
-
-func (c *DNSProvider) getHostedZone(domain string) (*dns.Zone, error) {
- zone, _, err := c.client.Zones.Get(domain)
- if err != nil {
- return nil, err
- }
-
- return zone, nil
-}
-
-func (c *DNSProvider) newTxtRecord(zone *dns.Zone, fqdn, value string, ttl int) *dns.Record {
- name := acme.UnFqdn(fqdn)
-
- return &dns.Record{
- Type: "TXT",
- Zone: zone.Zone,
- Domain: name,
- TTL: ttl,
- Answers: []*dns.Answer{
- {Rdata: []string{value}},
- },
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1_test.go b/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1_test.go
deleted file mode 100644
index eb9150dde..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/ns1/ns1_test.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package ns1
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- liveTest bool
- apiKey string
- domain string
-)
-
-func init() {
- apiKey = os.Getenv("NS1_API_KEY")
- domain = os.Getenv("NS1_DOMAIN")
- if len(apiKey) > 0 && len(domain) > 0 {
- liveTest = true
- }
-}
-
-func restoreNS1Env() {
- os.Setenv("NS1_API_KEY", apiKey)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- os.Setenv("NS1_API_KEY", "")
- _, err := NewDNSProviderCredentials("123")
- assert.NoError(t, err)
- restoreNS1Env()
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("NS1_API_KEY", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "NS1 credentials missing")
- restoreNS1Env()
-}
-
-func TestLivePresent(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(apiKey)
- assert.NoError(t, err)
-
- err = provider.Present(domain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveCleanUp(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProviderCredentials(apiKey)
- assert.NoError(t, err)
-
- err = provider.CleanUp(domain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/otc/mock.go b/vendor/github.com/xenolf/lego/providers/dns/otc/mock.go
deleted file mode 100644
index 0f2acb4b4..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/otc/mock.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package otc
-
-import (
- "fmt"
- "github.com/stretchr/testify/assert"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-var fakeOTCUserName = "test"
-var fakeOTCPassword = "test"
-var fakeOTCDomainName = "test"
-var fakeOTCProjectName = "test"
-var fakeOTCToken = "62244bc21da68d03ebac94e6636ff01f"
-
-type DNSMock struct {
- t *testing.T
- Server *httptest.Server
- Mux *http.ServeMux
-}
-
-func NewDNSMock(t *testing.T) *DNSMock {
- return &DNSMock{
- t: t,
- }
-}
-
-// Setup creates the mock server
-func (m *DNSMock) Setup() {
- m.Mux = http.NewServeMux()
- m.Server = httptest.NewServer(m.Mux)
-}
-
-// ShutdownServer creates the mock server
-func (m *DNSMock) ShutdownServer() {
- m.Server.Close()
-}
-
-func (m *DNSMock) HandleAuthSuccessfully() {
- m.Mux.HandleFunc("/v3/auth/token", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Subject-Token", fakeOTCToken)
-
- fmt.Fprintf(w, `{
- "token": {
- "catalog": [
- {
- "type": "dns",
- "id": "56cd81db1f8445d98652479afe07c5ba",
- "name": "",
- "endpoints": [
- {
- "url": "%s",
- "region": "eu-de",
- "region_id": "eu-de",
- "interface": "public",
- "id": "0047a06690484d86afe04877074efddf"
- }
- ]
- }
- ]
- }}`, m.Server.URL)
- })
-}
-
-func (m *DNSMock) HandleListZonesSuccessfully() {
- m.Mux.HandleFunc("/v2/zones", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, `{
- "zones":[{
- "id":"123123"
- }]}
- `)
-
- assert.Equal(m.t, r.Method, "GET")
- assert.Equal(m.t, r.URL.Path, "/v2/zones")
- assert.Equal(m.t, r.URL.RawQuery, "name=example.com.")
- assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
- })
-}
-
-func (m *DNSMock) HandleListZonesEmpty() {
- m.Mux.HandleFunc("/v2/zones", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, `{
- "zones":[
- ]}
- `)
-
- assert.Equal(m.t, r.Method, "GET")
- assert.Equal(m.t, r.URL.Path, "/v2/zones")
- assert.Equal(m.t, r.URL.RawQuery, "name=example.com.")
- assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
- })
-}
-
-func (m *DNSMock) HandleDeleteRecordsetsSuccessfully() {
- m.Mux.HandleFunc("/v2/zones/123123/recordsets/321321", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, `{
- "zones":[{
- "id":"123123"
- }]}
- `)
-
- assert.Equal(m.t, r.Method, "DELETE")
- assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets/321321")
- assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
- })
-}
-
-func (m *DNSMock) HandleListRecordsetsEmpty() {
- m.Mux.HandleFunc("/v2/zones/123123/recordsets", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, `{
- "recordsets":[
- ]}
- `)
-
- assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets")
- assert.Equal(m.t, r.URL.RawQuery, "type=TXT&name=_acme-challenge.example.com.")
- })
-}
-func (m *DNSMock) HandleListRecordsetsSuccessfully() {
- m.Mux.HandleFunc("/v2/zones/123123/recordsets", func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "GET" {
- fmt.Fprintf(w, `{
- "recordsets":[{
- "id":"321321"
- }]}
- `)
-
- assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets")
- assert.Equal(m.t, r.URL.RawQuery, "type=TXT&name=_acme-challenge.example.com.")
-
- } else if r.Method == "POST" {
- body, err := ioutil.ReadAll(r.Body)
-
- assert.Nil(m.t, err)
- exceptedString := "{\"name\":\"_acme-challenge.example.com.\",\"description\":\"Added TXT record for ACME dns-01 challenge using lego client\",\"type\":\"TXT\",\"ttl\":300,\"records\":[\"\\\"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI\\\"\"]}"
- assert.Equal(m.t, string(body), exceptedString)
-
- fmt.Fprintf(w, `{
- "recordsets":[{
- "id":"321321"
- }]}
- `)
-
- } else {
- m.t.Errorf("Expected method to be 'GET' or 'POST' but got '%s'", r.Method)
- }
-
- assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
- })
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/otc/otc.go b/vendor/github.com/xenolf/lego/providers/dns/otc/otc.go
deleted file mode 100644
index 86bcaa9b7..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/otc/otc.go
+++ /dev/null
@@ -1,388 +0,0 @@
-// Package otc implements a DNS provider for solving the DNS-01 challenge
-// using Open Telekom Cloud Managed DNS.
-package otc
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "os"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses
-// OTC's Managed DNS API to manage TXT records for a domain.
-type DNSProvider struct {
- identityEndpoint string
- otcBaseURL string
- domainName string
- projectName string
- userName string
- password string
- token string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for OTC DNS.
-// Credentials must be passed in the environment variables: OTC_USER_NAME,
-// OTC_DOMAIN_NAME, OTC_PASSWORD OTC_PROJECT_NAME and OTC_IDENTITY_ENDPOINT.
-func NewDNSProvider() (*DNSProvider, error) {
- domainName := os.Getenv("OTC_DOMAIN_NAME")
- userName := os.Getenv("OTC_USER_NAME")
- password := os.Getenv("OTC_PASSWORD")
- projectName := os.Getenv("OTC_PROJECT_NAME")
- identityEndpoint := os.Getenv("OTC_IDENTITY_ENDPOINT")
- return NewDNSProviderCredentials(domainName, userName, password, projectName, identityEndpoint)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for OTC DNS.
-func NewDNSProviderCredentials(domainName, userName, password, projectName, identityEndpoint string) (*DNSProvider, error) {
- if domainName == "" || userName == "" || password == "" || projectName == "" {
- return nil, fmt.Errorf("OTC credentials missing")
- }
-
- if identityEndpoint == "" {
- identityEndpoint = "https://iam.eu-de.otc.t-systems.com:443/v3/auth/tokens"
- }
-
- return &DNSProvider{
- identityEndpoint: identityEndpoint,
- domainName: domainName,
- userName: userName,
- password: password,
- projectName: projectName,
- }, nil
-}
-
-func (d *DNSProvider) SendRequest(method, resource string, payload interface{}) (io.Reader, error) {
- url := fmt.Sprintf("%s/%s", d.otcBaseURL, resource)
-
- body, err := json.Marshal(payload)
- if err != nil {
- return nil, err
- }
-
- req, err := http.NewRequest(method, url, bytes.NewReader(body))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "application/json")
- if len(d.token) > 0 {
- req.Header.Set("X-Auth-Token", d.token)
- }
-
- // Workaround for keep alive bug in otc api
- tr := http.DefaultTransport.(*http.Transport)
- tr.DisableKeepAlives = true
-
- client := &http.Client{
- Timeout: time.Duration(10 * time.Second),
- Transport: tr,
- }
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return nil, fmt.Errorf("OTC API request %s failed with HTTP status code %d", url, resp.StatusCode)
- }
-
- body1, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
-
- return bytes.NewReader(body1), nil
-}
-
-func (d *DNSProvider) loginRequest() error {
- type nameResponse struct {
- Name string `json:"name"`
- }
-
- type userResponse struct {
- Name string `json:"name"`
- Password string `json:"password"`
- Domain nameResponse `json:"domain"`
- }
-
- type passwordResponse struct {
- User userResponse `json:"user"`
- }
- type identityResponse struct {
- Methods []string `json:"methods"`
- Password passwordResponse `json:"password"`
- }
-
- type scopeResponse struct {
- Project nameResponse `json:"project"`
- }
-
- type authResponse struct {
- Identity identityResponse `json:"identity"`
- Scope scopeResponse `json:"scope"`
- }
-
- type loginResponse struct {
- Auth authResponse `json:"auth"`
- }
-
- userResp := userResponse{
- Name: d.userName,
- Password: d.password,
- Domain: nameResponse{
- Name: d.domainName,
- },
- }
-
- loginResp := loginResponse{
- Auth: authResponse{
- Identity: identityResponse{
- Methods: []string{"password"},
- Password: passwordResponse{
- User: userResp,
- },
- },
- Scope: scopeResponse{
- Project: nameResponse{
- Name: d.projectName,
- },
- },
- },
- }
-
- body, err := json.Marshal(loginResp)
- if err != nil {
- return err
- }
- req, err := http.NewRequest("POST", d.identityEndpoint, bytes.NewReader(body))
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
-
- client := &http.Client{Timeout: time.Duration(10 * time.Second)}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode >= 400 {
- return fmt.Errorf("OTC API request failed with HTTP status code %d", resp.StatusCode)
- }
-
- d.token = resp.Header.Get("X-Subject-Token")
-
- if d.token == "" {
- return fmt.Errorf("unable to get auth token")
- }
-
- type endpointResponse struct {
- Token struct {
- Catalog []struct {
- Type string `json:"type"`
- Endpoints []struct {
- URL string `json:"url"`
- } `json:"endpoints"`
- } `json:"catalog"`
- } `json:"token"`
- }
- var endpointResp endpointResponse
-
- err = json.NewDecoder(resp.Body).Decode(&endpointResp)
- if err != nil {
- return err
- }
-
- for _, v := range endpointResp.Token.Catalog {
- if v.Type == "dns" {
- for _, endpoint := range v.Endpoints {
- d.otcBaseURL = fmt.Sprintf("%s/v2", endpoint.URL)
- continue
- }
- }
- }
-
- if d.otcBaseURL == "" {
- return fmt.Errorf("unable to get dns endpoint")
- }
-
- return nil
-}
-
-// Starts a new OTC API Session. Authenticates using userName, password
-// and receives a token to be used in for subsequent requests.
-func (d *DNSProvider) login() error {
- err := d.loginRequest()
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *DNSProvider) getZoneID(zone string) (string, error) {
- type zoneItem struct {
- ID string `json:"id"`
- }
-
- type zonesResponse struct {
- Zones []zoneItem `json:"zones"`
- }
-
- resource := fmt.Sprintf("zones?name=%s", zone)
- resp, err := d.SendRequest("GET", resource, nil)
- if err != nil {
- return "", err
- }
-
- var zonesRes zonesResponse
- err = json.NewDecoder(resp).Decode(&zonesRes)
- if err != nil {
- return "", err
- }
-
- if len(zonesRes.Zones) < 1 {
- return "", fmt.Errorf("zone %s not found", zone)
- }
-
- if len(zonesRes.Zones) > 1 {
- return "", fmt.Errorf("to many zones found")
- }
-
- if zonesRes.Zones[0].ID == "" {
- return "", fmt.Errorf("id not found")
- }
-
- return zonesRes.Zones[0].ID, nil
-}
-
-func (d *DNSProvider) getRecordSetID(zoneID string, fqdn string) (string, error) {
- type recordSet struct {
- ID string `json:"id"`
- }
-
- type recordSetsResponse struct {
- RecordSets []recordSet `json:"recordsets"`
- }
-
- resource := fmt.Sprintf("zones/%s/recordsets?type=TXT&name=%s", zoneID, fqdn)
- resp, err := d.SendRequest("GET", resource, nil)
- if err != nil {
- return "", err
- }
-
- var recordSetsRes recordSetsResponse
- err = json.NewDecoder(resp).Decode(&recordSetsRes)
- if err != nil {
- return "", err
- }
-
- if len(recordSetsRes.RecordSets) < 1 {
- return "", fmt.Errorf("record not found")
- }
-
- if len(recordSetsRes.RecordSets) > 1 {
- return "", fmt.Errorf("to many records found")
- }
-
- if recordSetsRes.RecordSets[0].ID == "" {
- return "", fmt.Errorf("id not found")
- }
-
- return recordSetsRes.RecordSets[0].ID, nil
-}
-
-func (d *DNSProvider) deleteRecordSet(zoneID, recordID string) error {
- resource := fmt.Sprintf("zones/%s/recordsets/%s", zoneID, recordID)
-
- _, err := d.SendRequest("DELETE", resource, nil)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Present creates a TXT record using the specified parameters
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- if ttl < 300 {
- ttl = 300 // 300 is otc minimum value for ttl
- }
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- err = d.login()
- if err != nil {
- return err
- }
-
- zoneID, err := d.getZoneID(authZone)
- if err != nil {
- return fmt.Errorf("unable to get zone: %s", err)
- }
-
- resource := fmt.Sprintf("zones/%s/recordsets", zoneID)
-
- type recordset struct {
- Name string `json:"name"`
- Description string `json:"description"`
- Type string `json:"type"`
- Ttl int `json:"ttl"`
- Records []string `json:"records"`
- }
-
- r1 := &recordset{
- Name: fqdn,
- Description: "Added TXT record for ACME dns-01 challenge using lego client",
- Type: "TXT",
- Ttl: 300,
- Records: []string{fmt.Sprintf("\"%s\"", value)},
- }
- _, err = d.SendRequest("POST", resource, r1)
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return err
- }
-
- err = d.login()
- if err != nil {
- return err
- }
-
- zoneID, err := d.getZoneID(authZone)
-
- if err != nil {
- return err
- }
-
- recordID, err := d.getRecordSetID(zoneID, fqdn)
- if err != nil {
- return fmt.Errorf("unable go get record %s for zone %s: %s", fqdn, domain, err)
- }
- return d.deleteRecordSet(zoneID, recordID)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/otc/otc_test.go b/vendor/github.com/xenolf/lego/providers/dns/otc/otc_test.go
deleted file mode 100644
index 0c05334a9..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/otc/otc_test.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package otc
-
-import (
- "fmt"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/suite"
- "os"
- "testing"
-)
-
-type OTCDNSTestSuite struct {
- suite.Suite
- Mock *DNSMock
-}
-
-func (s *OTCDNSTestSuite) TearDownSuite() {
- s.Mock.ShutdownServer()
-}
-
-func (s *OTCDNSTestSuite) SetupTest() {
- s.Mock = NewDNSMock(s.T())
- s.Mock.Setup()
- s.Mock.HandleAuthSuccessfully()
-
-}
-
-func TestOTCDNSTestSuite(t *testing.T) {
- suite.Run(t, new(OTCDNSTestSuite))
-}
-
-func (s *OTCDNSTestSuite) createDNSProvider() (*DNSProvider, error) {
- url := fmt.Sprintf("%s/v3/auth/token", s.Mock.Server.URL)
- return NewDNSProviderCredentials(fakeOTCUserName, fakeOTCPassword, fakeOTCDomainName, fakeOTCProjectName, url)
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() {
- os.Setenv("OTC_DOMAIN_NAME", "unittest1")
- os.Setenv("OTC_USER_NAME", "unittest2")
- os.Setenv("OTC_PASSWORD", "unittest3")
- os.Setenv("OTC_PROJECT_NAME", "unittest4")
- os.Setenv("OTC_IDENTITY_ENDPOINT", "unittest5")
-
- provider, err := NewDNSProvider()
- assert.Nil(s.T(), err)
- assert.Equal(s.T(), provider.domainName, "unittest1")
- assert.Equal(s.T(), provider.userName, "unittest2")
- assert.Equal(s.T(), provider.password, "unittest3")
- assert.Equal(s.T(), provider.projectName, "unittest4")
- assert.Equal(s.T(), provider.identityEndpoint, "unittest5")
-
- os.Setenv("OTC_IDENTITY_ENDPOINT", "")
-
- provider, err = NewDNSProvider()
- assert.Nil(s.T(), err)
- assert.Equal(s.T(), provider.identityEndpoint, "https://iam.eu-de.otc.t-systems.com:443/v3/auth/tokens")
-
- os.Clearenv()
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSLoginEnvEmpty() {
- _, err := NewDNSProvider()
- assert.Equal(s.T(), "OTC credentials missing", err.Error())
-
- os.Clearenv()
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSLogin() {
- otcProvider, err := s.createDNSProvider()
-
- assert.Nil(s.T(), err)
- err = otcProvider.loginRequest()
- assert.Nil(s.T(), err)
- assert.Equal(s.T(), otcProvider.otcBaseURL, fmt.Sprintf("%s/v2", s.Mock.Server.URL))
- assert.Equal(s.T(), fakeOTCToken, otcProvider.token)
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSEmptyZone() {
- s.Mock.HandleListZonesEmpty()
- s.Mock.HandleListRecordsetsSuccessfully()
-
- otcProvider, _ := s.createDNSProvider()
- err := otcProvider.Present("example.com", "", "foobar")
- assert.NotNil(s.T(), err)
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSEmptyRecordset() {
- s.Mock.HandleListZonesSuccessfully()
- s.Mock.HandleListRecordsetsEmpty()
-
- otcProvider, _ := s.createDNSProvider()
- err := otcProvider.CleanUp("example.com", "", "foobar")
- assert.NotNil(s.T(), err)
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSPresent() {
- s.Mock.HandleListZonesSuccessfully()
- s.Mock.HandleListRecordsetsSuccessfully()
-
- otcProvider, _ := s.createDNSProvider()
- err := otcProvider.Present("example.com", "", "foobar")
- assert.Nil(s.T(), err)
-}
-
-func (s *OTCDNSTestSuite) TestOTCDNSCleanup() {
- s.Mock.HandleListZonesSuccessfully()
- s.Mock.HandleListRecordsetsSuccessfully()
- s.Mock.HandleDeleteRecordsetsSuccessfully()
-
- otcProvider, _ := s.createDNSProvider()
- err := otcProvider.CleanUp("example.com", "", "foobar")
- assert.Nil(s.T(), err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh.go b/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh.go
deleted file mode 100644
index 290a8d7df..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Package OVH implements a DNS provider for solving the DNS-01
-// challenge using OVH DNS.
-package ovh
-
-import (
- "fmt"
- "os"
- "strings"
- "sync"
-
- "github.com/ovh/go-ovh/ovh"
- "github.com/xenolf/lego/acme"
-)
-
-// OVH API reference: https://eu.api.ovh.com/
-// Create a Token: https://eu.api.ovh.com/createToken/
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-// that uses OVH's REST API to manage TXT records for a domain.
-type DNSProvider struct {
- client *ovh.Client
- recordIDs map[string]int
- recordIDsMu sync.Mutex
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for OVH
-// Credentials must be passed in the environment variable:
-// OVH_ENDPOINT : it must be ovh-eu or ovh-ca
-// OVH_APPLICATION_KEY
-// OVH_APPLICATION_SECRET
-// OVH_CONSUMER_KEY
-func NewDNSProvider() (*DNSProvider, error) {
- apiEndpoint := os.Getenv("OVH_ENDPOINT")
- applicationKey := os.Getenv("OVH_APPLICATION_KEY")
- applicationSecret := os.Getenv("OVH_APPLICATION_SECRET")
- consumerKey := os.Getenv("OVH_CONSUMER_KEY")
- return NewDNSProviderCredentials(apiEndpoint, applicationKey, applicationSecret, consumerKey)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for OVH.
-func NewDNSProviderCredentials(apiEndpoint, applicationKey, applicationSecret, consumerKey string) (*DNSProvider, error) {
- if apiEndpoint == "" || applicationKey == "" || applicationSecret == "" || consumerKey == "" {
- return nil, fmt.Errorf("OVH credentials missing")
- }
-
- ovhClient, _ := ovh.NewClient(
- apiEndpoint,
- applicationKey,
- applicationSecret,
- consumerKey,
- )
-
- return &DNSProvider{
- client: ovhClient,
- recordIDs: make(map[string]int),
- }, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge.
-func (d *DNSProvider) Present(domain, token, keyAuth string) error {
-
- // txtRecordRequest represents the request body to DO's API to make a TXT record
- type txtRecordRequest struct {
- FieldType string `json:"fieldType"`
- SubDomain string `json:"subDomain"`
- Target string `json:"target"`
- TTL int `json:"ttl"`
- }
-
- // txtRecordResponse represents a response from DO's API after making a TXT record
- type txtRecordResponse struct {
- ID int `json:"id"`
- FieldType string `json:"fieldType"`
- SubDomain string `json:"subDomain"`
- Target string `json:"target"`
- TTL int `json:"ttl"`
- Zone string `json:"zone"`
- }
-
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- // Parse domain name
- 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)
- subDomain := d.extractRecordName(fqdn, authZone)
-
- reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone)
- reqData := txtRecordRequest{FieldType: "TXT", SubDomain: subDomain, Target: value, TTL: ttl}
- var respData txtRecordResponse
-
- // Create TXT record
- err = d.client.Post(reqURL, reqData, &respData)
- if err != nil {
- fmt.Printf("Error when call OVH api to add record : %q \n", err)
- return err
- }
-
- // Apply the change
- reqURL = fmt.Sprintf("/domain/zone/%s/refresh", authZone)
- err = d.client.Post(reqURL, nil, nil)
- if err != nil {
- fmt.Printf("Error when call OVH api to refresh zone : %q \n", err)
- return err
- }
-
- d.recordIDsMu.Lock()
- d.recordIDs[fqdn] = respData.ID
- d.recordIDsMu.Unlock()
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- // get the record's unique ID from when we created it
- d.recordIDsMu.Lock()
- recordID, ok := d.recordIDs[fqdn]
- d.recordIDsMu.Unlock()
- if !ok {
- return fmt.Errorf("unknown record ID 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)
-
- reqURL := fmt.Sprintf("/domain/zone/%s/record/%d", authZone, recordID)
-
- err = d.client.Delete(reqURL, nil)
- if err != nil {
- fmt.Printf("Error when call OVH api to delete challenge record : %q \n", err)
- return err
- }
-
- // Delete record ID from map
- d.recordIDsMu.Lock()
- delete(d.recordIDs, fqdn)
- d.recordIDsMu.Unlock()
-
- return nil
-}
-
-func (d *DNSProvider) extractRecordName(fqdn, domain string) string {
- name := acme.UnFqdn(fqdn)
- if idx := strings.Index(name, "."+domain); idx != -1 {
- return name[:idx]
- }
- return name
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh_test.go b/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh_test.go
deleted file mode 100644
index 47da60e57..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/ovh/ovh_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package ovh
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- liveTest bool
- apiEndpoint string
- applicationKey string
- applicationSecret string
- consumerKey string
- domain string
-)
-
-func init() {
- apiEndpoint = os.Getenv("OVH_ENDPOINT")
- applicationKey = os.Getenv("OVH_APPLICATION_KEY")
- applicationSecret = os.Getenv("OVH_APPLICATION_SECRET")
- consumerKey = os.Getenv("OVH_CONSUMER_KEY")
- liveTest = len(apiEndpoint) > 0 && len(applicationKey) > 0 && len(applicationSecret) > 0 && len(consumerKey) > 0
-}
-
-func restoreEnv() {
- os.Setenv("OVH_ENDPOINT", apiEndpoint)
- os.Setenv("OVH_APPLICATION_KEY", applicationKey)
- os.Setenv("OVH_APPLICATION_SECRET", applicationSecret)
- os.Setenv("OVH_CONSUMER_KEY", consumerKey)
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("OVH_ENDPOINT", "ovh-eu")
- os.Setenv("OVH_APPLICATION_KEY", "1234")
- os.Setenv("OVH_APPLICATION_SECRET", "5678")
- os.Setenv("OVH_CONSUMER_KEY", "abcde")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("OVH_ENDPOINT", "")
- os.Setenv("OVH_APPLICATION_KEY", "1234")
- os.Setenv("OVH_APPLICATION_SECRET", "5678")
- os.Setenv("OVH_CONSUMER_KEY", "abcde")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "OVH credentials missing")
-
- os.Setenv("OVH_ENDPOINT", "ovh-eu")
- os.Setenv("OVH_APPLICATION_KEY", "")
- os.Setenv("OVH_APPLICATION_SECRET", "5678")
- os.Setenv("OVH_CONSUMER_KEY", "abcde")
- defer restoreEnv()
- _, err = NewDNSProvider()
- assert.EqualError(t, err, "OVH credentials missing")
-
- os.Setenv("OVH_ENDPOINT", "ovh-eu")
- os.Setenv("OVH_APPLICATION_KEY", "1234")
- os.Setenv("OVH_APPLICATION_SECRET", "")
- os.Setenv("OVH_CONSUMER_KEY", "abcde")
- defer restoreEnv()
- _, err = NewDNSProvider()
- assert.EqualError(t, err, "OVH credentials missing")
-
- os.Setenv("OVH_ENDPOINT", "ovh-eu")
- os.Setenv("OVH_APPLICATION_KEY", "1234")
- os.Setenv("OVH_APPLICATION_SECRET", "5678")
- os.Setenv("OVH_CONSUMER_KEY", "")
- defer restoreEnv()
- _, err = NewDNSProvider()
- assert.EqualError(t, err, "OVH credentials missing")
-}
-
-func TestLivePresent(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.Present(domain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveCleanUp(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.CleanUp(domain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/pdns/README.md b/vendor/github.com/xenolf/lego/providers/dns/pdns/README.md
deleted file mode 100644
index 23abb7669..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/pdns/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## PowerDNS provider
-
-Tested and confirmed to work with PowerDNS authoratative server 3.4.8 and 4.0.1. Refer to [PowerDNS documentation](https://doc.powerdns.com/md/httpapi/README/) instructions on how to enable the built-in API interface.
-
-PowerDNS Notes:
-- PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc.
-- In order to have the SOA serial automatically increment each time the `_acme-challenge` record is added/modified via the API, set `SOA-API-EDIT` to `INCEPTION-INCREMENT` for the zone in the `domainmetadata` table
diff --git a/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go b/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go
deleted file mode 100644
index a4fd22b0c..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go
+++ /dev/null
@@ -1,343 +0,0 @@
-// Package pdns implements a DNS provider for solving the DNS-01
-// challenge using PowerDNS nameserver.
-package pdns
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "net/url"
- "os"
- "strconv"
- "strings"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-type DNSProvider struct {
- apiKey string
- host *url.URL
- apiVersion int
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for pdns.
-// Credentials must be passed in the environment variable:
-// PDNS_API_URL and PDNS_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- key := os.Getenv("PDNS_API_KEY")
- hostUrl, err := url.Parse(os.Getenv("PDNS_API_URL"))
- if err != nil {
- return nil, err
- }
-
- return NewDNSProviderCredentials(hostUrl, key)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for pdns.
-func NewDNSProviderCredentials(host *url.URL, key string) (*DNSProvider, error) {
- if key == "" {
- return nil, fmt.Errorf("PDNS API key missing")
- }
-
- if host == nil || host.Host == "" {
- return nil, fmt.Errorf("PDNS API URL missing")
- }
-
- provider := &DNSProvider{
- host: host,
- apiKey: key,
- }
- provider.getAPIVersion()
-
- return provider, nil
-}
-
-// Timeout returns the timeout and interval to use when checking for DNS
-// propagation. Adjusting here to cope with spikes in propagation times.
-func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return 120 * time.Second, 2 * time.Second
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zone, err := c.getHostedZone(fqdn)
- if err != nil {
- return err
- }
-
- name := fqdn
-
- // pre-v1 API wants non-fqdn
- if c.apiVersion == 0 {
- name = acme.UnFqdn(fqdn)
- }
-
- rec := pdnsRecord{
- Content: "\"" + value + "\"",
- Disabled: false,
-
- // pre-v1 API
- Type: "TXT",
- Name: name,
- TTL: 120,
- }
-
- rrsets := rrSets{
- RRSets: []rrSet{
- rrSet{
- Name: name,
- ChangeType: "REPLACE",
- Type: "TXT",
- Kind: "Master",
- TTL: 120,
- Records: []pdnsRecord{rec},
- },
- },
- }
-
- body, err := json.Marshal(rrsets)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("PATCH", zone.URL, bytes.NewReader(body))
- if err != nil {
- fmt.Println("here")
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- zone, err := c.getHostedZone(fqdn)
- if err != nil {
- return err
- }
-
- set, err := c.findTxtRecord(fqdn)
- if err != nil {
- return err
- }
-
- rrsets := rrSets{
- RRSets: []rrSet{
- rrSet{
- Name: set.Name,
- Type: set.Type,
- ChangeType: "DELETE",
- },
- },
- }
- body, err := json.Marshal(rrsets)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("PATCH", zone.URL, bytes.NewReader(body))
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (c *DNSProvider) getHostedZone(fqdn string) (*hostedZone, error) {
- var zone hostedZone
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return nil, err
- }
-
- url := "/servers/localhost/zones"
- result, err := c.makeRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
-
- zones := []hostedZone{}
- err = json.Unmarshal(result, &zones)
- if err != nil {
- return nil, err
- }
-
- url = ""
- for _, zone := range zones {
- if acme.UnFqdn(zone.Name) == acme.UnFqdn(authZone) {
- url = zone.URL
- }
- }
-
- result, err = c.makeRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
-
- err = json.Unmarshal(result, &zone)
- if err != nil {
- return nil, err
- }
-
- // convert pre-v1 API result
- if len(zone.Records) > 0 {
- zone.RRSets = []rrSet{}
- for _, record := range zone.Records {
- set := rrSet{
- Name: record.Name,
- Type: record.Type,
- Records: []pdnsRecord{record},
- }
- zone.RRSets = append(zone.RRSets, set)
- }
- }
-
- return &zone, nil
-}
-
-func (c *DNSProvider) findTxtRecord(fqdn string) (*rrSet, error) {
- zone, err := c.getHostedZone(fqdn)
- if err != nil {
- return nil, err
- }
-
- _, err = c.makeRequest("GET", zone.URL, nil)
- if err != nil {
- return nil, err
- }
-
- for _, set := range zone.RRSets {
- if (set.Name == acme.UnFqdn(fqdn) || set.Name == fqdn) && set.Type == "TXT" {
- return &set, nil
- }
- }
-
- return nil, fmt.Errorf("No existing record found for %s", fqdn)
-}
-
-func (c *DNSProvider) getAPIVersion() {
- type APIVersion struct {
- URL string `json:"url"`
- Version int `json:"version"`
- }
-
- result, err := c.makeRequest("GET", "/api", nil)
- if err != nil {
- return
- }
-
- var versions []APIVersion
- err = json.Unmarshal(result, &versions)
- if err != nil {
- return
- }
-
- latestVersion := 0
- for _, v := range versions {
- if v.Version > latestVersion {
- latestVersion = v.Version
- }
- }
- c.apiVersion = latestVersion
-}
-
-func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) {
- type APIError struct {
- Error string `json:"error"`
- }
- var path = ""
- if c.host.Path != "/" {
- path = c.host.Path
- }
- if c.apiVersion > 0 {
- if !strings.HasPrefix(uri, "api/v") {
- uri = "/api/v" + strconv.Itoa(c.apiVersion) + uri
- } else {
- uri = "/" + uri
- }
- }
- url := c.host.Scheme + "://" + c.host.Host + path + uri
- req, err := http.NewRequest(method, url, body)
- if err != nil {
- return nil, err
- }
-
- req.Header.Set("X-API-Key", c.apiKey)
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("Error talking to PDNS API -> %v", err)
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != 422 && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
- return nil, fmt.Errorf("Unexpected HTTP status code %d when fetching '%s'", resp.StatusCode, url)
- }
-
- var msg json.RawMessage
- err = json.NewDecoder(resp.Body).Decode(&msg)
- switch {
- case err == io.EOF:
- // empty body
- return nil, nil
- case err != nil:
- // other error
- return nil, err
- }
-
- // check for PowerDNS error message
- if len(msg) > 0 && msg[0] == '{' {
- var apiError APIError
- err = json.Unmarshal(msg, &apiError)
- if err != nil {
- return nil, err
- }
- if apiError.Error != "" {
- return nil, fmt.Errorf("Error talking to PDNS API -> %v", apiError.Error)
- }
- }
- return msg, nil
-}
-
-type pdnsRecord struct {
- Content string `json:"content"`
- Disabled bool `json:"disabled"`
-
- // pre-v1 API
- Name string `json:"name"`
- Type string `json:"type"`
- TTL int `json:"ttl,omitempty"`
-}
-
-type hostedZone struct {
- ID string `json:"id"`
- Name string `json:"name"`
- URL string `json:"url"`
- RRSets []rrSet `json:"rrsets"`
-
- // pre-v1 API
- Records []pdnsRecord `json:"records"`
-}
-
-type rrSet struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Kind string `json:"kind"`
- ChangeType string `json:"changetype"`
- Records []pdnsRecord `json:"records"`
- TTL int `json:"ttl,omitempty"`
-}
-
-type rrSets struct {
- RRSets []rrSet `json:"rrsets"`
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns_test.go b/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns_test.go
deleted file mode 100644
index 70e7670ed..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/pdns/pdns_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package pdns
-
-import (
- "net/url"
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- pdnsLiveTest bool
- pdnsURL *url.URL
- pdnsURLStr string
- pdnsAPIKey string
- pdnsDomain string
-)
-
-func init() {
- pdnsURLStr = os.Getenv("PDNS_API_URL")
- pdnsURL, _ = url.Parse(pdnsURLStr)
- pdnsAPIKey = os.Getenv("PDNS_API_KEY")
- pdnsDomain = os.Getenv("PDNS_DOMAIN")
- if len(pdnsURLStr) > 0 && len(pdnsAPIKey) > 0 && len(pdnsDomain) > 0 {
- pdnsLiveTest = true
- }
-}
-
-func restorePdnsEnv() {
- os.Setenv("PDNS_API_URL", pdnsURLStr)
- os.Setenv("PDNS_API_KEY", pdnsAPIKey)
-}
-
-func TestNewDNSProviderValid(t *testing.T) {
- os.Setenv("PDNS_API_URL", "")
- os.Setenv("PDNS_API_KEY", "")
- tmpURL, _ := url.Parse("http://localhost:8081")
- _, err := NewDNSProviderCredentials(tmpURL, "123")
- assert.NoError(t, err)
- restorePdnsEnv()
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("PDNS_API_URL", "http://localhost:8081")
- os.Setenv("PDNS_API_KEY", "123")
- _, err := NewDNSProvider()
- assert.NoError(t, err)
- restorePdnsEnv()
-}
-
-func TestNewDNSProviderMissingHostErr(t *testing.T) {
- os.Setenv("PDNS_API_URL", "")
- os.Setenv("PDNS_API_KEY", "123")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "PDNS API URL missing")
- restorePdnsEnv()
-}
-
-func TestNewDNSProviderMissingKeyErr(t *testing.T) {
- os.Setenv("PDNS_API_URL", pdnsURLStr)
- os.Setenv("PDNS_API_KEY", "")
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "PDNS API key missing")
- restorePdnsEnv()
-}
-
-func TestPdnsPresentAndCleanup(t *testing.T) {
- if !pdnsLiveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProviderCredentials(pdnsURL, pdnsAPIKey)
- assert.NoError(t, err)
-
- err = provider.Present(pdnsDomain, "", "123d==")
- assert.NoError(t, err)
-
- err = provider.CleanUp(pdnsDomain, "", "123d==")
- assert.NoError(t, err)
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go b/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go
deleted file mode 100644
index 13daa8c8a..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go
+++ /dev/null
@@ -1,284 +0,0 @@
-// Package rackspace implements a DNS provider for solving the DNS-01
-// challenge using rackspace DNS.
-package rackspace
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "os"
- "time"
-
- "github.com/xenolf/lego/acme"
-)
-
-// rackspaceAPIURL represents the Identity API endpoint to call
-var rackspaceAPIURL = "https://identity.api.rackspacecloud.com/v2.0/tokens"
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface
-// used to store the reusable token and DNS API endpoint
-type DNSProvider struct {
- token string
- cloudDNSEndpoint string
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for Rackspace.
-// Credentials must be passed in the environment variables: RACKSPACE_USER
-// and RACKSPACE_API_KEY.
-func NewDNSProvider() (*DNSProvider, error) {
- user := os.Getenv("RACKSPACE_USER")
- key := os.Getenv("RACKSPACE_API_KEY")
- return NewDNSProviderCredentials(user, key)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for Rackspace. It authenticates against
-// the API, also grabbing the DNS Endpoint.
-func NewDNSProviderCredentials(user, key string) (*DNSProvider, error) {
- if user == "" || key == "" {
- return nil, fmt.Errorf("Rackspace credentials missing")
- }
-
- type APIKeyCredentials struct {
- Username string `json:"username"`
- APIKey string `json:"apiKey"`
- }
-
- type Auth struct {
- APIKeyCredentials `json:"RAX-KSKEY:apiKeyCredentials"`
- }
-
- type RackspaceAuthData struct {
- Auth `json:"auth"`
- }
-
- type RackspaceIdentity struct {
- Access struct {
- ServiceCatalog []struct {
- Endpoints []struct {
- PublicURL string `json:"publicURL"`
- TenantID string `json:"tenantId"`
- } `json:"endpoints"`
- Name string `json:"name"`
- } `json:"serviceCatalog"`
- Token struct {
- ID string `json:"id"`
- } `json:"token"`
- } `json:"access"`
- }
-
- authData := RackspaceAuthData{
- Auth: Auth{
- APIKeyCredentials: APIKeyCredentials{
- Username: user,
- APIKey: key,
- },
- },
- }
-
- body, err := json.Marshal(authData)
- if err != nil {
- return nil, err
- }
-
- req, err := http.NewRequest("POST", rackspaceAPIURL, bytes.NewReader(body))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "application/json")
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("Error querying Rackspace Identity API: %v", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- return nil, fmt.Errorf("Rackspace Authentication failed. Response code: %d", resp.StatusCode)
- }
-
- var rackspaceIdentity RackspaceIdentity
- err = json.NewDecoder(resp.Body).Decode(&rackspaceIdentity)
- if err != nil {
- return nil, err
- }
-
- // Iterate through the Service Catalog to get the DNS Endpoint
- var dnsEndpoint string
- for _, service := range rackspaceIdentity.Access.ServiceCatalog {
- if service.Name == "cloudDNS" {
- dnsEndpoint = service.Endpoints[0].PublicURL
- break
- }
- }
- if dnsEndpoint == "" {
- return nil, fmt.Errorf("Failed to populate DNS endpoint, check Rackspace API for changes.")
- }
-
- return &DNSProvider{
- token: rackspaceIdentity.Access.Token.ID,
- cloudDNSEndpoint: dnsEndpoint,
- }, nil
-}
-
-// Present creates a TXT record to fulfil the dns-01 challenge
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- zoneID, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return err
- }
-
- rec := RackspaceRecords{
- RackspaceRecord: []RackspaceRecord{{
- Name: acme.UnFqdn(fqdn),
- Type: "TXT",
- Data: value,
- TTL: 300,
- }},
- }
-
- body, err := json.Marshal(rec)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("POST", fmt.Sprintf("/domains/%d/records", zoneID), bytes.NewReader(body))
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
- zoneID, err := c.getHostedZoneID(fqdn)
- if err != nil {
- return err
- }
-
- record, err := c.findTxtRecord(fqdn, zoneID)
- if err != nil {
- return err
- }
-
- _, err = c.makeRequest("DELETE", fmt.Sprintf("/domains/%d/records?id=%s", zoneID, record.ID), nil)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// getHostedZoneID performs a lookup to get the DNS zone which needs
-// modifying for a given FQDN
-func (c *DNSProvider) getHostedZoneID(fqdn string) (int, error) {
- // HostedZones represents the response when querying Rackspace DNS zones
- type ZoneSearchResponse struct {
- TotalEntries int `json:"totalEntries"`
- HostedZones []struct {
- ID int `json:"id"`
- Name string `json:"name"`
- } `json:"domains"`
- }
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return 0, err
- }
-
- result, err := c.makeRequest("GET", fmt.Sprintf("/domains?name=%s", acme.UnFqdn(authZone)), nil)
- if err != nil {
- return 0, err
- }
-
- var zoneSearchResponse ZoneSearchResponse
- err = json.Unmarshal(result, &zoneSearchResponse)
- if err != nil {
- return 0, err
- }
-
- // If nothing was returned, or for whatever reason more than 1 was returned (the search uses exact match, so should not occur)
- if zoneSearchResponse.TotalEntries != 1 {
- return 0, fmt.Errorf("Found %d zones for %s in Rackspace for domain %s", zoneSearchResponse.TotalEntries, authZone, fqdn)
- }
-
- return zoneSearchResponse.HostedZones[0].ID, nil
-}
-
-// findTxtRecord searches a DNS zone for a TXT record with a specific name
-func (c *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*RackspaceRecord, error) {
- result, err := c.makeRequest("GET", fmt.Sprintf("/domains/%d/records?type=TXT&name=%s", zoneID, acme.UnFqdn(fqdn)), nil)
- if err != nil {
- return nil, err
- }
-
- var records RackspaceRecords
- err = json.Unmarshal(result, &records)
- if err != nil {
- return nil, err
- }
-
- recordsLength := len(records.RackspaceRecord)
- switch recordsLength {
- case 1:
- break
- case 0:
- return nil, fmt.Errorf("No TXT record found for %s", fqdn)
- default:
- return nil, fmt.Errorf("More than 1 TXT record found for %s", fqdn)
- }
-
- return &records.RackspaceRecord[0], nil
-}
-
-// makeRequest is a wrapper function used for making DNS API requests
-func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) {
- url := c.cloudDNSEndpoint + uri
- req, err := http.NewRequest(method, url, body)
- if err != nil {
- return nil, err
- }
-
- req.Header.Set("X-Auth-Token", c.token)
- req.Header.Set("Content-Type", "application/json")
-
- client := http.Client{Timeout: 30 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("Error querying DNS API: %v", err)
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {
- return nil, fmt.Errorf("Request failed for %s %s. Response code: %d", method, url, resp.StatusCode)
- }
-
- var r json.RawMessage
- err = json.NewDecoder(resp.Body).Decode(&r)
- if err != nil {
- return nil, fmt.Errorf("JSON decode failed for %s %s. Response code: %d", method, url, resp.StatusCode)
- }
-
- return r, nil
-}
-
-// RackspaceRecords is the list of records sent/received from the DNS API
-type RackspaceRecords struct {
- RackspaceRecord []RackspaceRecord `json:"records"`
-}
-
-// RackspaceRecord represents a Rackspace DNS record
-type RackspaceRecord struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Data string `json:"data"`
- TTL int `json:"ttl,omitempty"`
- ID string `json:"id,omitempty"`
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace_test.go b/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace_test.go
deleted file mode 100644
index 22c979cad..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace_test.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package rackspace
-
-import (
- "fmt"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "os"
- "strings"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- rackspaceLiveTest bool
- rackspaceUser string
- rackspaceAPIKey string
- rackspaceDomain string
- testAPIURL string
-)
-
-func init() {
- rackspaceUser = os.Getenv("RACKSPACE_USER")
- rackspaceAPIKey = os.Getenv("RACKSPACE_API_KEY")
- rackspaceDomain = os.Getenv("RACKSPACE_DOMAIN")
- if len(rackspaceUser) > 0 && len(rackspaceAPIKey) > 0 && len(rackspaceDomain) > 0 {
- rackspaceLiveTest = true
- }
-}
-
-func testRackspaceEnv() {
- rackspaceAPIURL = testAPIURL
- os.Setenv("RACKSPACE_USER", "testUser")
- os.Setenv("RACKSPACE_API_KEY", "testKey")
-}
-
-func liveRackspaceEnv() {
- rackspaceAPIURL = "https://identity.api.rackspacecloud.com/v2.0/tokens"
- os.Setenv("RACKSPACE_USER", rackspaceUser)
- os.Setenv("RACKSPACE_API_KEY", rackspaceAPIKey)
-}
-
-func startTestServers() (identityAPI, dnsAPI *httptest.Server) {
- dnsAPI = httptest.NewServer(dnsMux())
- dnsEndpoint := dnsAPI.URL + "/123456"
-
- identityAPI = httptest.NewServer(identityHandler(dnsEndpoint))
- testAPIURL = identityAPI.URL + "/"
- return
-}
-
-func closeTestServers(identityAPI, dnsAPI *httptest.Server) {
- identityAPI.Close()
- dnsAPI.Close()
-}
-
-func identityHandler(dnsEndpoint string) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- reqBody, err := ioutil.ReadAll(r.Body)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
- resp, found := jsonMap[string(reqBody)]
- if !found {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
- resp = strings.Replace(resp, "https://dns.api.rackspacecloud.com/v1.0/123456", dnsEndpoint, 1)
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, resp)
- })
-}
-
-func dnsMux() *http.ServeMux {
- mux := http.NewServeMux()
-
- // Used by `getHostedZoneID()` finding `zoneID` "?name=example.com"
- mux.HandleFunc("/123456/domains", func(w http.ResponseWriter, r *http.Request) {
- if r.URL.Query().Get("name") == "example.com" {
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, jsonMap["zoneDetails"])
- return
- }
- w.WriteHeader(http.StatusBadRequest)
- return
- })
-
- mux.HandleFunc("/123456/domains/112233/records", func(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- // Used by `Present()` creating the TXT record
- case http.MethodPost:
- reqBody, err := ioutil.ReadAll(r.Body)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
- resp, found := jsonMap[string(reqBody)]
- if !found {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
- w.WriteHeader(http.StatusAccepted)
- fmt.Fprintf(w, resp)
- // Used by `findTxtRecord()` finding `record.ID` "?type=TXT&name=_acme-challenge.example.com"
- case http.MethodGet:
- if r.URL.Query().Get("type") == "TXT" && r.URL.Query().Get("name") == "_acme-challenge.example.com" {
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, jsonMap["recordDetails"])
- return
- }
- w.WriteHeader(http.StatusBadRequest)
- return
- // Used by `CleanUp()` deleting the TXT record "?id=445566"
- case http.MethodDelete:
- if r.URL.Query().Get("id") == "TXT-654321" {
- w.WriteHeader(http.StatusOK)
- fmt.Fprintf(w, jsonMap["recordDelete"])
- return
- }
- w.WriteHeader(http.StatusBadRequest)
- }
- })
-
- mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusNotFound)
- fmt.Printf("Not Found for Request: (%+v)\n\n", r)
- })
-
- return mux
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- testRackspaceEnv()
- _, err := NewDNSProviderCredentials("", "")
- assert.EqualError(t, err, "Rackspace credentials missing")
-}
-
-func TestOfflineRackspaceValid(t *testing.T) {
- testRackspaceEnv()
- provider, err := NewDNSProviderCredentials(os.Getenv("RACKSPACE_USER"), os.Getenv("RACKSPACE_API_KEY"))
-
- assert.NoError(t, err)
- assert.Equal(t, provider.token, "testToken", "The token should match")
-}
-
-func TestOfflineRackspacePresent(t *testing.T) {
- testRackspaceEnv()
- provider, err := NewDNSProvider()
-
- if assert.NoError(t, err) {
- err = provider.Present("example.com", "token", "keyAuth")
- assert.NoError(t, err)
- }
-}
-
-func TestOfflineRackspaceCleanUp(t *testing.T) {
- testRackspaceEnv()
- provider, err := NewDNSProvider()
-
- if assert.NoError(t, err) {
- err = provider.CleanUp("example.com", "token", "keyAuth")
- assert.NoError(t, err)
- }
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- if !rackspaceLiveTest {
- t.Skip("skipping live test")
- }
-
- liveRackspaceEnv()
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
- assert.Contains(t, provider.cloudDNSEndpoint, "https://dns.api.rackspacecloud.com/v1.0/", "The endpoint URL should contain the base")
-}
-
-func TestRackspacePresent(t *testing.T) {
- if !rackspaceLiveTest {
- t.Skip("skipping live test")
- }
-
- liveRackspaceEnv()
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.Present(rackspaceDomain, "", "112233445566==")
- assert.NoError(t, err)
-}
-
-func TestRackspaceCleanUp(t *testing.T) {
- if !rackspaceLiveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 15)
-
- liveRackspaceEnv()
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.CleanUp(rackspaceDomain, "", "112233445566==")
- assert.NoError(t, err)
-}
-
-func TestMain(m *testing.M) {
- identityAPI, dnsAPI := startTestServers()
- defer closeTestServers(identityAPI, dnsAPI)
- os.Exit(m.Run())
-}
-
-var jsonMap = map[string]string{
- `{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"testUser","apiKey":"testKey"}}}`: `{"access":{"token":{"id":"testToken","expires":"1970-01-01T00:00:00.000Z","tenant":{"id":"123456","name":"123456"},"RAX-AUTH:authenticatedBy":["APIKEY"]},"serviceCatalog":[{"type":"rax:dns","endpoints":[{"publicURL":"https://dns.api.rackspacecloud.com/v1.0/123456","tenantId":"123456"}],"name":"cloudDNS"}],"user":{"id":"fakeUseID","name":"testUser"}}}`,
- "zoneDetails": `{"domains":[{"name":"example.com","id":112233,"emailAddress":"hostmaster@example.com","updated":"1970-01-01T00:00:00.000+0000","created":"1970-01-01T00:00:00.000+0000"}],"totalEntries":1}`,
- `{"records":[{"name":"_acme-challenge.example.com","type":"TXT","data":"pW9ZKG0xz_PCriK-nCMOjADy9eJcgGWIzkkj2fN4uZM","ttl":300}]}`: `{"request":"{\"records\":[{\"name\":\"_acme-challenge.example.com\",\"type\":\"TXT\",\"data\":\"pW9ZKG0xz_PCriK-nCMOjADy9eJcgGWIzkkj2fN4uZM\",\"ttl\":300}]}","status":"RUNNING","verb":"POST","jobId":"00000000-0000-0000-0000-0000000000","callbackUrl":"https://dns.api.rackspacecloud.com/v1.0/123456/status/00000000-0000-0000-0000-0000000000","requestUrl":"https://dns.api.rackspacecloud.com/v1.0/123456/domains/112233/records"}`,
- "recordDetails": `{"records":[{"name":"_acme-challenge.example.com","id":"TXT-654321","type":"TXT","data":"pW9ZKG0xz_PCriK-nCMOjADy9eJcgGWIzkkj2fN4uZM","ttl":300,"updated":"1970-01-01T00:00:00.000+0000","created":"1970-01-01T00:00:00.000+0000"}]}`,
- "recordDelete": `{"status":"RUNNING","verb":"DELETE","jobId":"00000000-0000-0000-0000-0000000000","callbackUrl":"https://dns.api.rackspacecloud.com/v1.0/123456/status/00000000-0000-0000-0000-0000000000","requestUrl":"https://dns.api.rackspacecloud.com/v1.0/123456/domains/112233/recordsid=TXT-654321"}`,
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go b/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go
deleted file mode 100644
index dde42ddf1..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Package rfc2136 implements a DNS provider for solving the DNS-01 challenge
-// using the rfc2136 dynamic update.
-package rfc2136
-
-import (
- "fmt"
- "net"
- "os"
- "strings"
- "time"
-
- "github.com/miekg/dns"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface that
-// uses dynamic DNS updates (RFC 2136) to create TXT records on a nameserver.
-type DNSProvider struct {
- nameserver string
- tsigAlgorithm string
- tsigKey string
- tsigSecret string
- timeout time.Duration
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for rfc2136
-// dynamic update. Configured with environment variables:
-// RFC2136_NAMESERVER: Network address in the form "host" or "host:port".
-// RFC2136_TSIG_ALGORITHM: Defaults to hmac-md5.sig-alg.reg.int. (HMAC-MD5).
-// See https://github.com/miekg/dns/blob/master/tsig.go for supported values.
-// RFC2136_TSIG_KEY: Name of the secret key as defined in DNS server configuration.
-// RFC2136_TSIG_SECRET: Secret key payload.
-// RFC2136_TIMEOUT: DNS propagation timeout in time.ParseDuration format. (60s)
-// To disable TSIG authentication, leave the RFC2136_TSIG* variables unset.
-func NewDNSProvider() (*DNSProvider, error) {
- nameserver := os.Getenv("RFC2136_NAMESERVER")
- tsigAlgorithm := os.Getenv("RFC2136_TSIG_ALGORITHM")
- tsigKey := os.Getenv("RFC2136_TSIG_KEY")
- tsigSecret := os.Getenv("RFC2136_TSIG_SECRET")
- timeout := os.Getenv("RFC2136_TIMEOUT")
- return NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret, timeout)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a
-// DNSProvider instance configured for rfc2136 dynamic update. To disable TSIG
-// authentication, leave the TSIG parameters as empty strings.
-// nameserver must be a network address in the form "host" or "host:port".
-func NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret, timeout string) (*DNSProvider, error) {
- if nameserver == "" {
- return nil, fmt.Errorf("RFC2136 nameserver missing")
- }
-
- // Append the default DNS port if none is specified.
- if _, _, err := net.SplitHostPort(nameserver); err != nil {
- if strings.Contains(err.Error(), "missing port") {
- nameserver = net.JoinHostPort(nameserver, "53")
- } else {
- return nil, err
- }
- }
- d := &DNSProvider{
- nameserver: nameserver,
- }
- if tsigAlgorithm == "" {
- tsigAlgorithm = dns.HmacMD5
- }
- d.tsigAlgorithm = tsigAlgorithm
- if len(tsigKey) > 0 && len(tsigSecret) > 0 {
- d.tsigKey = tsigKey
- d.tsigSecret = tsigSecret
- }
-
- if timeout == "" {
- d.timeout = 60 * time.Second
- } else {
- t, err := time.ParseDuration(timeout)
- if err != nil {
- return nil, err
- } else if t < 0 {
- return nil, fmt.Errorf("Invalid/negative RFC2136_TIMEOUT: %v", timeout)
- } else {
- d.timeout = t
- }
- }
-
- return d, nil
-}
-
-// Returns the timeout configured with RFC2136_TIMEOUT, or 60s.
-func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
- return d.timeout, 2 * time.Second
-}
-
-// Present creates a TXT record using the specified parameters
-func (r *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- return r.changeRecord("INSERT", fqdn, value, ttl)
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
- return r.changeRecord("REMOVE", fqdn, value, ttl)
-}
-
-func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
- // Find the zone for the given fqdn
- zone, err := acme.FindZoneByFqdn(fqdn, []string{r.nameserver})
- if err != nil {
- return err
- }
-
- // Create RR
- rr := new(dns.TXT)
- rr.Hdr = dns.RR_Header{Name: fqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: uint32(ttl)}
- rr.Txt = []string{value}
- rrs := []dns.RR{rr}
-
- // Create dynamic update packet
- m := new(dns.Msg)
- m.SetUpdate(zone)
- switch action {
- case "INSERT":
- // Always remove old challenge left over from who knows what.
- m.RemoveRRset(rrs)
- m.Insert(rrs)
- case "REMOVE":
- m.Remove(rrs)
- default:
- return fmt.Errorf("Unexpected action: %s", action)
- }
-
- // Setup client
- c := new(dns.Client)
- c.SingleInflight = true
- // TSIG authentication / msg signing
- if len(r.tsigKey) > 0 && len(r.tsigSecret) > 0 {
- m.SetTsig(dns.Fqdn(r.tsigKey), r.tsigAlgorithm, 300, time.Now().Unix())
- c.TsigSecret = map[string]string{dns.Fqdn(r.tsigKey): r.tsigSecret}
- }
-
- // Send the query
- reply, _, err := c.Exchange(m, r.nameserver)
- if err != nil {
- return fmt.Errorf("DNS update failed: %v", err)
- }
- if reply != nil && reply.Rcode != dns.RcodeSuccess {
- return fmt.Errorf("DNS update failed. Server replied: %s", dns.RcodeToString[reply.Rcode])
- }
-
- return nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go b/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go
deleted file mode 100644
index f3ca65b31..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go
+++ /dev/null
@@ -1,244 +0,0 @@
-package rfc2136
-
-import (
- "bytes"
- "fmt"
- "net"
- "strings"
- "sync"
- "testing"
- "time"
-
- "github.com/miekg/dns"
- "github.com/xenolf/lego/acme"
-)
-
-var (
- rfc2136TestDomain = "123456789.www.example.com"
- rfc2136TestKeyAuth = "123d=="
- rfc2136TestValue = "Now36o-3BmlB623-0c1qCIUmgWVVmDJb88KGl24pqpo"
- rfc2136TestFqdn = "_acme-challenge.123456789.www.example.com."
- rfc2136TestZone = "example.com."
- rfc2136TestTTL = 120
- rfc2136TestTsigKey = "example.com."
- rfc2136TestTsigSecret = "IwBTJx9wrDp4Y1RyC3H0gA=="
-)
-
-var reqChan = make(chan *dns.Msg, 10)
-
-func TestRFC2136CanaryLocalTestServer(t *testing.T) {
- acme.ClearFqdnCache()
- dns.HandleFunc("example.com.", serverHandlerHello)
- defer dns.HandleRemove("example.com.")
-
- server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false)
- if err != nil {
- t.Fatalf("Failed to start test server: %v", err)
- }
- defer server.Shutdown()
-
- c := new(dns.Client)
- m := new(dns.Msg)
- m.SetQuestion("example.com.", dns.TypeTXT)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil || len(r.Extra) == 0 {
- t.Fatalf("Failed to communicate with test server: %v", err)
- }
- txt := r.Extra[0].(*dns.TXT).Txt[0]
- if txt != "Hello world" {
- t.Error("Expected test server to return 'Hello world' but got: ", txt)
- }
-}
-
-func TestRFC2136ServerSuccess(t *testing.T) {
- acme.ClearFqdnCache()
- dns.HandleFunc(rfc2136TestZone, serverHandlerReturnSuccess)
- defer dns.HandleRemove(rfc2136TestZone)
-
- server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false)
- if err != nil {
- t.Fatalf("Failed to start test server: %v", err)
- }
- defer server.Shutdown()
-
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
- if err != nil {
- t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
- }
- if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
- t.Errorf("Expected Present() to return no error but the error was -> %v", err)
- }
-}
-
-func TestRFC2136ServerError(t *testing.T) {
- acme.ClearFqdnCache()
- dns.HandleFunc(rfc2136TestZone, serverHandlerReturnErr)
- defer dns.HandleRemove(rfc2136TestZone)
-
- server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false)
- if err != nil {
- t.Fatalf("Failed to start test server: %v", err)
- }
- defer server.Shutdown()
-
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
- if err != nil {
- t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
- }
- if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err == nil {
- t.Errorf("Expected Present() to return an error but it did not.")
- } else if !strings.Contains(err.Error(), "NOTZONE") {
- t.Errorf("Expected Present() to return an error with the 'NOTZONE' rcode string but it did not.")
- }
-}
-
-func TestRFC2136TsigClient(t *testing.T) {
- acme.ClearFqdnCache()
- dns.HandleFunc(rfc2136TestZone, serverHandlerReturnSuccess)
- defer dns.HandleRemove(rfc2136TestZone)
-
- server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", true)
- if err != nil {
- t.Fatalf("Failed to start test server: %v", err)
- }
- defer server.Shutdown()
-
- provider, err := NewDNSProviderCredentials(addrstr, "", rfc2136TestTsigKey, rfc2136TestTsigSecret, "")
- if err != nil {
- t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
- }
- if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
- t.Errorf("Expected Present() to return no error but the error was -> %v", err)
- }
-}
-
-func TestRFC2136ValidUpdatePacket(t *testing.T) {
- acme.ClearFqdnCache()
- dns.HandleFunc(rfc2136TestZone, serverHandlerPassBackRequest)
- defer dns.HandleRemove(rfc2136TestZone)
-
- server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false)
- if err != nil {
- t.Fatalf("Failed to start test server: %v", err)
- }
- defer server.Shutdown()
-
- txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", rfc2136TestFqdn, rfc2136TestTTL, rfc2136TestValue))
- rrs := []dns.RR{txtRR}
- m := new(dns.Msg)
- m.SetUpdate(rfc2136TestZone)
- m.RemoveRRset(rrs)
- m.Insert(rrs)
- expectstr := m.String()
- expect, err := m.Pack()
- if err != nil {
- t.Fatalf("Error packing expect msg: %v", err)
- }
-
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
- if err != nil {
- t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
- }
-
- if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil {
- t.Errorf("Expected Present() to return no error but the error was -> %v", err)
- }
-
- rcvMsg := <-reqChan
- rcvMsg.Id = m.Id
- actual, err := rcvMsg.Pack()
- if err != nil {
- t.Fatalf("Error packing actual msg: %v", err)
- }
-
- if !bytes.Equal(actual, expect) {
- tmp := new(dns.Msg)
- if err := tmp.Unpack(actual); err != nil {
- t.Fatalf("Error unpacking actual msg: %v", err)
- }
- t.Errorf("Expected msg:\n%s", expectstr)
- t.Errorf("Actual msg:\n%v", tmp)
- }
-}
-
-func runLocalDNSTestServer(listenAddr string, tsig bool) (*dns.Server, string, error) {
- pc, err := net.ListenPacket("udp", listenAddr)
- if err != nil {
- return nil, "", err
- }
- server := &dns.Server{PacketConn: pc, ReadTimeout: time.Hour, WriteTimeout: time.Hour}
- if tsig {
- server.TsigSecret = map[string]string{rfc2136TestTsigKey: rfc2136TestTsigSecret}
- }
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
-
- go func() {
- server.ActivateAndServe()
- pc.Close()
- }()
-
- waitLock.Lock()
- return server, pc.LocalAddr().String(), nil
-}
-
-func serverHandlerHello(w dns.ResponseWriter, req *dns.Msg) {
- m := new(dns.Msg)
- m.SetReply(req)
- m.Extra = make([]dns.RR, 1)
- m.Extra[0] = &dns.TXT{
- Hdr: dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0},
- Txt: []string{"Hello world"},
- }
- w.WriteMsg(m)
-}
-
-func serverHandlerReturnSuccess(w dns.ResponseWriter, req *dns.Msg) {
- m := new(dns.Msg)
- m.SetReply(req)
- if req.Opcode == dns.OpcodeQuery && req.Question[0].Qtype == dns.TypeSOA && req.Question[0].Qclass == dns.ClassINET {
- // Return SOA to appease findZoneByFqdn()
- soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", rfc2136TestZone, rfc2136TestTTL, rfc2136TestZone, rfc2136TestZone))
- m.Answer = []dns.RR{soaRR}
- }
-
- if t := req.IsTsig(); t != nil {
- if w.TsigStatus() == nil {
- // Validated
- m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix())
- }
- }
-
- w.WriteMsg(m)
-}
-
-func serverHandlerReturnErr(w dns.ResponseWriter, req *dns.Msg) {
- m := new(dns.Msg)
- m.SetRcode(req, dns.RcodeNotZone)
- w.WriteMsg(m)
-}
-
-func serverHandlerPassBackRequest(w dns.ResponseWriter, req *dns.Msg) {
- m := new(dns.Msg)
- m.SetReply(req)
- if req.Opcode == dns.OpcodeQuery && req.Question[0].Qtype == dns.TypeSOA && req.Question[0].Qclass == dns.ClassINET {
- // Return SOA to appease findZoneByFqdn()
- soaRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN SOA ns1.%s admin.%s 2016022801 28800 7200 2419200 1200", rfc2136TestZone, rfc2136TestTTL, rfc2136TestZone, rfc2136TestZone))
- m.Answer = []dns.RR{soaRR}
- }
-
- if t := req.IsTsig(); t != nil {
- if w.TsigStatus() == nil {
- // Validated
- m.SetTsig(rfc2136TestZone, dns.HmacMD5, 300, time.Now().Unix())
- }
- }
-
- w.WriteMsg(m)
- if req.Opcode != dns.OpcodeQuery || req.Question[0].Qtype != dns.TypeSOA || req.Question[0].Qclass != dns.ClassINET {
- // Only talk back when it is not the SOA RR.
- reqChan <- req
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/fixtures_test.go b/vendor/github.com/xenolf/lego/providers/dns/route53/fixtures_test.go
deleted file mode 100644
index a5cc9c878..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/fixtures_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package route53
-
-var ChangeResourceRecordSetsResponse = `<?xml version="1.0" encoding="UTF-8"?>
-<ChangeResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
-<ChangeInfo>
- <Id>/change/123456</Id>
- <Status>PENDING</Status>
- <SubmittedAt>2016-02-10T01:36:41.958Z</SubmittedAt>
-</ChangeInfo>
-</ChangeResourceRecordSetsResponse>`
-
-var ListHostedZonesByNameResponse = `<?xml version="1.0" encoding="UTF-8"?>
-<ListHostedZonesByNameResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
- <HostedZones>
- <HostedZone>
- <Id>/hostedzone/ABCDEFG</Id>
- <Name>example.com.</Name>
- <CallerReference>D2224C5B-684A-DB4A-BB9A-E09E3BAFEA7A</CallerReference>
- <Config>
- <Comment>Test comment</Comment>
- <PrivateZone>false</PrivateZone>
- </Config>
- <ResourceRecordSetCount>10</ResourceRecordSetCount>
- </HostedZone>
- </HostedZones>
- <IsTruncated>true</IsTruncated>
- <NextDNSName>example2.com</NextDNSName>
- <NextHostedZoneId>ZLT12321321124</NextHostedZoneId>
- <MaxItems>1</MaxItems>
-</ListHostedZonesByNameResponse>`
-
-var GetChangeResponse = `<?xml version="1.0" encoding="UTF-8"?>
-<GetChangeResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
- <ChangeInfo>
- <Id>123456</Id>
- <Status>INSYNC</Status>
- <SubmittedAt>2016-02-10T01:36:41.958Z</SubmittedAt>
- </ChangeInfo>
-</GetChangeResponse>`
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go b/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go
deleted file mode 100644
index 934f0a2d4..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Package route53 implements a DNS provider for solving the DNS-01 challenge
-// using AWS Route 53 DNS.
-package route53
-
-import (
- "fmt"
- "math/rand"
- "os"
- "strings"
- "time"
-
- "github.com/aws/aws-sdk-go/aws"
- "github.com/aws/aws-sdk-go/aws/client"
- "github.com/aws/aws-sdk-go/aws/request"
- "github.com/aws/aws-sdk-go/aws/session"
- "github.com/aws/aws-sdk-go/service/route53"
- "github.com/xenolf/lego/acme"
-)
-
-const (
- maxRetries = 5
- route53TTL = 10
-)
-
-// DNSProvider implements the acme.ChallengeProvider interface
-type DNSProvider struct {
- client *route53.Route53
- hostedZoneID string
-}
-
-// customRetryer implements the client.Retryer interface by composing the
-// DefaultRetryer. It controls the logic for retrying recoverable request
-// errors (e.g. when rate limits are exceeded).
-type customRetryer struct {
- client.DefaultRetryer
-}
-
-// RetryRules overwrites the DefaultRetryer's method.
-// It uses a basic exponential backoff algorithm that returns an initial
-// delay of ~400ms with an upper limit of ~30 seconds which should prevent
-// causing a high number of consecutive throttling errors.
-// For reference: Route 53 enforces an account-wide(!) 5req/s query limit.
-func (d customRetryer) RetryRules(r *request.Request) time.Duration {
- retryCount := r.RetryCount
- if retryCount > 7 {
- retryCount = 7
- }
-
- delay := (1 << uint(retryCount)) * (rand.Intn(50) + 200)
- return time.Duration(delay) * time.Millisecond
-}
-
-// NewDNSProvider returns a DNSProvider instance configured for the AWS
-// Route 53 service.
-//
-// AWS Credentials are automatically detected in the following locations
-// and prioritized in the following order:
-// 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
-// AWS_REGION, [AWS_SESSION_TOKEN]
-// 2. Shared credentials file (defaults to ~/.aws/credentials)
-// 3. Amazon EC2 IAM role
-//
-// If AWS_HOSTED_ZONE_ID is not set, Lego tries to determine the correct
-// public hosted zone via the FQDN.
-//
-// See also: https://github.com/aws/aws-sdk-go/wiki/configuring-sdk
-func NewDNSProvider() (*DNSProvider, error) {
- hostedZoneID := os.Getenv("AWS_HOSTED_ZONE_ID")
-
- r := customRetryer{}
- r.NumMaxRetries = maxRetries
- config := request.WithRetryer(aws.NewConfig(), r)
- client := route53.New(session.New(config))
-
- return &DNSProvider{
- client: client,
- hostedZoneID: hostedZoneID,
- }, nil
-}
-
-// Present creates a TXT record using the specified parameters
-func (r *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- value = `"` + value + `"`
- return r.changeRecord("UPSERT", fqdn, value, route53TTL)
-}
-
-// CleanUp removes the TXT record matching the specified parameters
-func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
- value = `"` + value + `"`
- return r.changeRecord("DELETE", fqdn, value, route53TTL)
-}
-
-func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
- hostedZoneID, err := r.getHostedZoneID(fqdn)
- if err != nil {
- return fmt.Errorf("Failed to determine Route 53 hosted zone ID: %v", err)
- }
-
- recordSet := newTXTRecordSet(fqdn, value, ttl)
- reqParams := &route53.ChangeResourceRecordSetsInput{
- HostedZoneId: aws.String(hostedZoneID),
- ChangeBatch: &route53.ChangeBatch{
- Comment: aws.String("Managed by Lego"),
- Changes: []*route53.Change{
- {
- Action: aws.String(action),
- ResourceRecordSet: recordSet,
- },
- },
- },
- }
-
- resp, err := r.client.ChangeResourceRecordSets(reqParams)
- if err != nil {
- return fmt.Errorf("Failed to change Route 53 record set: %v", err)
- }
-
- statusID := resp.ChangeInfo.Id
-
- return acme.WaitFor(120*time.Second, 4*time.Second, func() (bool, error) {
- reqParams := &route53.GetChangeInput{
- Id: statusID,
- }
- resp, err := r.client.GetChange(reqParams)
- if err != nil {
- return false, fmt.Errorf("Failed to query Route 53 change status: %v", err)
- }
- if *resp.ChangeInfo.Status == route53.ChangeStatusInsync {
- return true, nil
- }
- return false, nil
- })
-}
-
-func (r *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
- if r.hostedZoneID != "" {
- return r.hostedZoneID, nil
- }
-
- authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
- if err != nil {
- return "", err
- }
-
- // .DNSName should not have a trailing dot
- reqParams := &route53.ListHostedZonesByNameInput{
- DNSName: aws.String(acme.UnFqdn(authZone)),
- }
- resp, err := r.client.ListHostedZonesByName(reqParams)
- if err != nil {
- return "", err
- }
-
- var hostedZoneID string
- for _, hostedZone := range resp.HostedZones {
- // .Name has a trailing dot
- if !*hostedZone.Config.PrivateZone && *hostedZone.Name == authZone {
- hostedZoneID = *hostedZone.Id
- break
- }
- }
-
- if len(hostedZoneID) == 0 {
- return "", fmt.Errorf("Zone %s not found in Route 53 for domain %s", authZone, fqdn)
- }
-
- if strings.HasPrefix(hostedZoneID, "/hostedzone/") {
- hostedZoneID = strings.TrimPrefix(hostedZoneID, "/hostedzone/")
- }
-
- return hostedZoneID, nil
-}
-
-func newTXTRecordSet(fqdn, value string, ttl int) *route53.ResourceRecordSet {
- return &route53.ResourceRecordSet{
- Name: aws.String(fqdn),
- Type: aws.String("TXT"),
- TTL: aws.Int64(int64(ttl)),
- ResourceRecords: []*route53.ResourceRecord{
- {Value: aws.String(value)},
- },
- }
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/route53_integration_test.go b/vendor/github.com/xenolf/lego/providers/dns/route53/route53_integration_test.go
deleted file mode 100644
index 17ba4a08a..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/route53_integration_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package route53
-
-import (
- "fmt"
- "os"
- "testing"
-
- "github.com/aws/aws-sdk-go/aws"
- "github.com/aws/aws-sdk-go/aws/session"
- "github.com/aws/aws-sdk-go/service/route53"
-)
-
-func TestRoute53TTL(t *testing.T) {
-
- m, err := testGetAndPreCheck()
- if err != nil {
- t.Skip(err.Error())
- }
-
- provider, err := NewDNSProvider()
- if err != nil {
- t.Fatalf("Fatal: %s", err.Error())
- }
-
- err = provider.Present(m["route53Domain"], "foo", "bar")
- if err != nil {
- t.Fatalf("Fatal: %s", err.Error())
- }
- // we need a separate R53 client here as the one in the DNS provider is
- // unexported.
- fqdn := "_acme-challenge." + m["route53Domain"] + "."
- svc := route53.New(session.New())
- zoneID, err := provider.getHostedZoneID(fqdn)
- if err != nil {
- provider.CleanUp(m["route53Domain"], "foo", "bar")
- t.Fatalf("Fatal: %s", err.Error())
- }
- params := &route53.ListResourceRecordSetsInput{
- HostedZoneId: aws.String(zoneID),
- }
- resp, err := svc.ListResourceRecordSets(params)
- if err != nil {
- provider.CleanUp(m["route53Domain"], "foo", "bar")
- t.Fatalf("Fatal: %s", err.Error())
- }
-
- for _, v := range resp.ResourceRecordSets {
- if *v.Name == fqdn && *v.Type == "TXT" && *v.TTL == 10 {
- provider.CleanUp(m["route53Domain"], "foo", "bar")
- return
- }
- }
- provider.CleanUp(m["route53Domain"], "foo", "bar")
- t.Fatalf("Could not find a TXT record for _acme-challenge.%s with a TTL of 10", m["route53Domain"])
-}
-
-func testGetAndPreCheck() (map[string]string, error) {
- m := map[string]string{
- "route53Key": os.Getenv("AWS_ACCESS_KEY_ID"),
- "route53Secret": os.Getenv("AWS_SECRET_ACCESS_KEY"),
- "route53Region": os.Getenv("AWS_REGION"),
- "route53Domain": os.Getenv("R53_DOMAIN"),
- }
- for _, v := range m {
- if v == "" {
- return nil, fmt.Errorf("AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, and R53_DOMAIN are needed to run this test")
- }
- }
- return m, nil
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go b/vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go
deleted file mode 100644
index de4e28f3d..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package route53
-
-import (
- "net/http/httptest"
- "os"
- "testing"
-
- "github.com/aws/aws-sdk-go/aws"
- "github.com/aws/aws-sdk-go/aws/credentials"
- "github.com/aws/aws-sdk-go/aws/session"
- "github.com/aws/aws-sdk-go/service/route53"
- "github.com/stretchr/testify/assert"
-)
-
-var (
- route53Secret string
- route53Key string
- route53Region string
- route53Zone string
-)
-
-func init() {
- route53Key = os.Getenv("AWS_ACCESS_KEY_ID")
- route53Secret = os.Getenv("AWS_SECRET_ACCESS_KEY")
- route53Region = os.Getenv("AWS_REGION")
- route53Zone = os.Getenv("AWS_HOSTED_ZONE_ID")
-}
-
-func restoreRoute53Env() {
- os.Setenv("AWS_ACCESS_KEY_ID", route53Key)
- os.Setenv("AWS_SECRET_ACCESS_KEY", route53Secret)
- os.Setenv("AWS_REGION", route53Region)
- os.Setenv("AWS_HOSTED_ZONE_ID", route53Zone)
-}
-
-func makeRoute53Provider(ts *httptest.Server) *DNSProvider {
- config := &aws.Config{
- Credentials: credentials.NewStaticCredentials("abc", "123", " "),
- Endpoint: aws.String(ts.URL),
- Region: aws.String("mock-region"),
- MaxRetries: aws.Int(1),
- }
-
- client := route53.New(session.New(config))
- return &DNSProvider{client: client}
-}
-
-func TestCredentialsFromEnv(t *testing.T) {
- os.Setenv("AWS_ACCESS_KEY_ID", "123")
- os.Setenv("AWS_SECRET_ACCESS_KEY", "123")
- os.Setenv("AWS_REGION", "us-east-1")
-
- config := &aws.Config{
- CredentialsChainVerboseErrors: aws.Bool(true),
- }
-
- sess := session.New(config)
- _, err := sess.Config.Credentials.Get()
- assert.NoError(t, err, "Expected credentials to be set from environment")
-
- restoreRoute53Env()
-}
-
-func TestRegionFromEnv(t *testing.T) {
- os.Setenv("AWS_REGION", "us-east-1")
-
- sess := session.New(aws.NewConfig())
- assert.Equal(t, "us-east-1", *sess.Config.Region, "Expected Region to be set from environment")
-
- restoreRoute53Env()
-}
-
-func TestHostedZoneIDFromEnv(t *testing.T) {
- const testZoneID = "testzoneid"
-
- defer restoreRoute53Env()
- os.Setenv("AWS_HOSTED_ZONE_ID", testZoneID)
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err, "Expected no error constructing DNSProvider")
-
- fqdn, err := provider.getHostedZoneID("whatever")
- assert.NoError(t, err, "Expected FQDN to be resolved to environment variable value")
-
- assert.Equal(t, testZoneID, fqdn)
-}
-
-func TestRoute53Present(t *testing.T) {
- mockResponses := MockResponseMap{
- "/2013-04-01/hostedzonesbyname": MockResponse{StatusCode: 200, Body: ListHostedZonesByNameResponse},
- "/2013-04-01/hostedzone/ABCDEFG/rrset/": MockResponse{StatusCode: 200, Body: ChangeResourceRecordSetsResponse},
- "/2013-04-01/change/123456": MockResponse{StatusCode: 200, Body: GetChangeResponse},
- }
-
- ts := newMockServer(t, mockResponses)
- defer ts.Close()
-
- provider := makeRoute53Provider(ts)
-
- domain := "example.com"
- keyAuth := "123456d=="
-
- err := provider.Present(domain, "", keyAuth)
- assert.NoError(t, err, "Expected Present to return no error")
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/testutil_test.go b/vendor/github.com/xenolf/lego/providers/dns/route53/testutil_test.go
deleted file mode 100644
index e448a6858..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/testutil_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package route53
-
-import (
- "fmt"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-)
-
-// MockResponse represents a predefined response used by a mock server
-type MockResponse struct {
- StatusCode int
- Body string
-}
-
-// MockResponseMap maps request paths to responses
-type MockResponseMap map[string]MockResponse
-
-func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- path := r.URL.Path
- resp, ok := responses[path]
- if !ok {
- msg := fmt.Sprintf("Requested path not found in response map: %s", path)
- require.FailNow(t, msg)
- }
-
- w.Header().Set("Content-Type", "application/xml")
- w.WriteHeader(resp.StatusCode)
- w.Write([]byte(resp.Body))
- }))
-
- time.Sleep(100 * time.Millisecond)
- return ts
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go b/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go
deleted file mode 100644
index bc2067579..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Package vultr implements a DNS provider for solving the DNS-01 challenge using
-// the vultr DNS.
-// See https://www.vultr.com/api/#dns
-package vultr
-
-import (
- "fmt"
- "os"
- "strings"
-
- vultr "github.com/JamesClonk/vultr/lib"
- "github.com/xenolf/lego/acme"
-)
-
-// DNSProvider is an implementation of the acme.ChallengeProvider interface.
-type DNSProvider struct {
- client *vultr.Client
-}
-
-// NewDNSProvider returns a DNSProvider instance with a configured Vultr client.
-// Authentication uses the VULTR_API_KEY environment variable.
-func NewDNSProvider() (*DNSProvider, error) {
- apiKey := os.Getenv("VULTR_API_KEY")
- return NewDNSProviderCredentials(apiKey)
-}
-
-// NewDNSProviderCredentials uses the supplied credentials to return a DNSProvider
-// instance configured for Vultr.
-func NewDNSProviderCredentials(apiKey string) (*DNSProvider, error) {
- if apiKey == "" {
- return nil, fmt.Errorf("Vultr credentials missing")
- }
-
- c := &DNSProvider{
- client: vultr.NewClient(apiKey, nil),
- }
-
- return c, nil
-}
-
-// Present creates a TXT record to fulfil the DNS-01 challenge.
-func (c *DNSProvider) Present(domain, token, keyAuth string) error {
- fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
-
- zoneDomain, err := c.getHostedZone(domain)
- if err != nil {
- return err
- }
-
- name := c.extractRecordName(fqdn, zoneDomain)
-
- err = c.client.CreateDNSRecord(zoneDomain, name, "TXT", `"`+value+`"`, 0, ttl)
- if err != nil {
- return fmt.Errorf("Vultr API call failed: %v", err)
- }
-
- return nil
-}
-
-// CleanUp removes the TXT record matching the specified parameters.
-func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
- fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
-
- zoneDomain, records, err := c.findTxtRecords(domain, fqdn)
- if err != nil {
- return err
- }
-
- for _, rec := range records {
- err := c.client.DeleteDNSRecord(zoneDomain, rec.RecordID)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (c *DNSProvider) getHostedZone(domain string) (string, error) {
- domains, err := c.client.GetDNSDomains()
- if err != nil {
- return "", fmt.Errorf("Vultr API call failed: %v", err)
- }
-
- var hostedDomain vultr.DNSDomain
- for _, d := range domains {
- if strings.HasSuffix(domain, d.Domain) {
- if len(d.Domain) > len(hostedDomain.Domain) {
- hostedDomain = d
- }
- }
- }
- if hostedDomain.Domain == "" {
- return "", fmt.Errorf("No matching Vultr domain found for domain %s", domain)
- }
-
- return hostedDomain.Domain, nil
-}
-
-func (c *DNSProvider) findTxtRecords(domain, fqdn string) (string, []vultr.DNSRecord, error) {
- zoneDomain, err := c.getHostedZone(domain)
- if err != nil {
- return "", nil, err
- }
-
- var records []vultr.DNSRecord
- result, err := c.client.GetDNSRecords(zoneDomain)
- if err != nil {
- return "", records, fmt.Errorf("Vultr API call has failed: %v", err)
- }
-
- recordName := c.extractRecordName(fqdn, zoneDomain)
- for _, record := range result {
- if record.Type == "TXT" && record.Name == recordName {
- records = append(records, record)
- }
- }
-
- return zoneDomain, records, nil
-}
-
-func (c *DNSProvider) extractRecordName(fqdn, domain string) string {
- name := acme.UnFqdn(fqdn)
- if idx := strings.Index(name, "."+domain); idx != -1 {
- return name[:idx]
- }
- return name
-}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr_test.go b/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr_test.go
deleted file mode 100644
index 7c8cdaf1e..000000000
--- a/vendor/github.com/xenolf/lego/providers/dns/vultr/vultr_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package vultr
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- liveTest bool
- apiKey string
- domain string
-)
-
-func init() {
- apiKey = os.Getenv("VULTR_API_KEY")
- domain = os.Getenv("VULTR_TEST_DOMAIN")
- liveTest = len(apiKey) > 0 && len(domain) > 0
-}
-
-func restoreEnv() {
- os.Setenv("VULTR_API_KEY", apiKey)
-}
-
-func TestNewDNSProviderValidEnv(t *testing.T) {
- os.Setenv("VULTR_API_KEY", "123")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.NoError(t, err)
-}
-
-func TestNewDNSProviderMissingCredErr(t *testing.T) {
- os.Setenv("VULTR_API_KEY", "")
- defer restoreEnv()
- _, err := NewDNSProvider()
- assert.EqualError(t, err, "Vultr credentials missing")
-}
-
-func TestLivePresent(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.Present(domain, "", "123d==")
- assert.NoError(t, err)
-}
-
-func TestLiveCleanUp(t *testing.T) {
- if !liveTest {
- t.Skip("skipping live test")
- }
-
- time.Sleep(time.Second * 1)
-
- provider, err := NewDNSProvider()
- assert.NoError(t, err)
-
- err = provider.CleanUp(domain, "", "123d==")
- assert.NoError(t, err)
-}