forked from TrueCloudLab/lego
Make DNS provider credential-handling more consistent.
Different DNS providers were handling credentials in different ways. Some were reading credential environment variables in cli_handlers.go and then passing them into the NewDNSProvider function, while others were reading the environment variables within their NewDNSProvider functions. This change replaces each DNS challenge's NewDNSProvider function with two new functions: (1) a NewDNSProvider function that takes no parameters and uses the environment to read credentials, and (2) a NewDNSProviderCredentials that takes credentials as parameters.
This commit is contained in:
parent
43c55a690f
commit
47219adc00
18 changed files with 214 additions and 160 deletions
|
@ -14,12 +14,12 @@ import (
|
||||||
"github.com/xenolf/lego/providers/dns/cloudflare"
|
"github.com/xenolf/lego/providers/dns/cloudflare"
|
||||||
"github.com/xenolf/lego/providers/dns/digitalocean"
|
"github.com/xenolf/lego/providers/dns/digitalocean"
|
||||||
"github.com/xenolf/lego/providers/dns/dnsimple"
|
"github.com/xenolf/lego/providers/dns/dnsimple"
|
||||||
|
"github.com/xenolf/lego/providers/dns/dyn"
|
||||||
"github.com/xenolf/lego/providers/dns/gandi"
|
"github.com/xenolf/lego/providers/dns/gandi"
|
||||||
"github.com/xenolf/lego/providers/dns/googlecloud"
|
"github.com/xenolf/lego/providers/dns/googlecloud"
|
||||||
"github.com/xenolf/lego/providers/dns/namecheap"
|
"github.com/xenolf/lego/providers/dns/namecheap"
|
||||||
"github.com/xenolf/lego/providers/dns/rfc2136"
|
"github.com/xenolf/lego/providers/dns/rfc2136"
|
||||||
"github.com/xenolf/lego/providers/dns/route53"
|
"github.com/xenolf/lego/providers/dns/route53"
|
||||||
"github.com/xenolf/lego/providers/dns/dyn"
|
|
||||||
"github.com/xenolf/lego/providers/http/webroot"
|
"github.com/xenolf/lego/providers/http/webroot"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -89,38 +89,25 @@ func setup(c *cli.Context) (*Configuration, *Account, *acme.Client) {
|
||||||
var provider acme.ChallengeProvider
|
var provider acme.ChallengeProvider
|
||||||
switch c.GlobalString("dns") {
|
switch c.GlobalString("dns") {
|
||||||
case "cloudflare":
|
case "cloudflare":
|
||||||
provider, err = cloudflare.NewDNSProvider("", "")
|
provider, err = cloudflare.NewDNSProvider()
|
||||||
case "digitalocean":
|
case "digitalocean":
|
||||||
authToken := os.Getenv("DO_AUTH_TOKEN")
|
provider, err = digitalocean.NewDNSProvider()
|
||||||
|
|
||||||
provider, err = digitalocean.NewDNSProvider(authToken)
|
|
||||||
case "dnsimple":
|
case "dnsimple":
|
||||||
provider, err = dnsimple.NewDNSProvider("", "")
|
provider, err = dnsimple.NewDNSProvider()
|
||||||
case "gandi":
|
|
||||||
apiKey := os.Getenv("GANDI_API_KEY")
|
|
||||||
provider, err = gandi.NewDNSProvider(apiKey)
|
|
||||||
case "gcloud":
|
|
||||||
provider, err = googlecloud.NewDNSProvider("")
|
|
||||||
case "namecheap":
|
|
||||||
provider, err = namecheap.NewDNSProvider("", "")
|
|
||||||
case "route53":
|
|
||||||
awsRegion := os.Getenv("AWS_REGION")
|
|
||||||
provider, err = route53.NewDNSProvider("", "", awsRegion)
|
|
||||||
case "rfc2136":
|
|
||||||
nameserver := os.Getenv("RFC2136_NAMESERVER")
|
|
||||||
tsigAlgorithm := os.Getenv("RFC2136_TSIG_ALGORITHM")
|
|
||||||
tsigKey := os.Getenv("RFC2136_TSIG_KEY")
|
|
||||||
tsigSecret := os.Getenv("RFC2136_TSIG_SECRET")
|
|
||||||
|
|
||||||
provider, err = rfc2136.NewDNSProvider(nameserver, tsigAlgorithm, tsigKey, tsigSecret)
|
|
||||||
case "dyn":
|
case "dyn":
|
||||||
dynCustomerName := os.Getenv("DYN_CUSTOMER_NAME")
|
provider, err = dyn.NewDNSProvider()
|
||||||
dynUserName := os.Getenv("DYN_USER_NAME")
|
case "gandi":
|
||||||
dynPassword := os.Getenv("DYN_PASSWORD")
|
provider, err = gandi.NewDNSProvider()
|
||||||
|
case "gcloud":
|
||||||
provider, err = dyn.NewDNSProvider(dynCustomerName, dynUserName, dynPassword)
|
provider, err = googlecloud.NewDNSProvider()
|
||||||
case "manual":
|
case "manual":
|
||||||
provider, err = acme.NewDNSProviderManual()
|
provider, err = acme.NewDNSProviderManual()
|
||||||
|
case "namecheap":
|
||||||
|
provider, err = namecheap.NewDNSProvider()
|
||||||
|
case "route53":
|
||||||
|
provider, err = route53.NewDNSProvider()
|
||||||
|
case "rfc2136":
|
||||||
|
provider, err = rfc2136.NewDNSProvider()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Package cloudflare implements a DNS provider for solving the DNS-01 challenge using cloudflare DNS.
|
// Package cloudflare implements a DNS provider for solving the DNS-01
|
||||||
|
// challenge using cloudflare DNS.
|
||||||
package cloudflare
|
package cloudflare
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -24,19 +25,25 @@ type DNSProvider struct {
|
||||||
authKey string
|
authKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance with a configured cloudflare client.
|
// NewDNSProvider returns a DNSProvider instance configured for cloudflare.
|
||||||
// Credentials can either be passed as arguments or through CLOUDFLARE_EMAIL and CLOUDFLARE_API_KEY env vars.
|
// Credentials must be passed in the environment variables: CLOUDFLARE_EMAIL
|
||||||
func NewDNSProvider(cloudflareEmail, cloudflareKey string) (*DNSProvider, error) {
|
// and CLOUDFLARE_API_KEY.
|
||||||
if cloudflareEmail == "" || cloudflareKey == "" {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
cloudflareEmail, cloudflareKey = cloudflareEnvAuth()
|
email := os.Getenv("CLOUDFLARE_EMAIL")
|
||||||
if cloudflareEmail == "" || cloudflareKey == "" {
|
key := os.Getenv("CLOUDFLARE_API_KEY")
|
||||||
return nil, fmt.Errorf("CloudFlare credentials missing")
|
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{
|
return &DNSProvider{
|
||||||
authEmail: cloudflareEmail,
|
authEmail: email,
|
||||||
authKey: cloudflareKey,
|
authKey: key,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,15 +199,6 @@ func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM
|
||||||
return r.Result, nil
|
return r.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloudflareEnvAuth() (email, apiKey string) {
|
|
||||||
email = os.Getenv("CLOUDFLARE_EMAIL")
|
|
||||||
apiKey = os.Getenv("CLOUDFLARE_API_KEY")
|
|
||||||
if len(email) == 0 || len(apiKey) == 0 {
|
|
||||||
return "", ""
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// cloudFlareRecord represents a CloudFlare DNS record
|
// cloudFlareRecord represents a CloudFlare DNS record
|
||||||
type cloudFlareRecord struct {
|
type cloudFlareRecord struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
|
@ -32,7 +32,7 @@ func restoreCloudFlareEnv() {
|
||||||
func TestNewDNSProviderValid(t *testing.T) {
|
func TestNewDNSProviderValid(t *testing.T) {
|
||||||
os.Setenv("CLOUDFLARE_EMAIL", "")
|
os.Setenv("CLOUDFLARE_EMAIL", "")
|
||||||
os.Setenv("CLOUDFLARE_API_KEY", "")
|
os.Setenv("CLOUDFLARE_API_KEY", "")
|
||||||
_, err := NewDNSProvider("123", "123")
|
_, err := NewDNSProviderCredentials("123", "123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreCloudFlareEnv()
|
restoreCloudFlareEnv()
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func TestNewDNSProviderValid(t *testing.T) {
|
||||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
os.Setenv("CLOUDFLARE_EMAIL", "test@example.com")
|
os.Setenv("CLOUDFLARE_EMAIL", "test@example.com")
|
||||||
os.Setenv("CLOUDFLARE_API_KEY", "123")
|
os.Setenv("CLOUDFLARE_API_KEY", "123")
|
||||||
_, err := NewDNSProvider("", "")
|
_, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreCloudFlareEnv()
|
restoreCloudFlareEnv()
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||||
os.Setenv("CLOUDFLARE_EMAIL", "")
|
os.Setenv("CLOUDFLARE_EMAIL", "")
|
||||||
os.Setenv("CLOUDFLARE_API_KEY", "")
|
os.Setenv("CLOUDFLARE_API_KEY", "")
|
||||||
_, err := NewDNSProvider("", "")
|
_, err := NewDNSProvider()
|
||||||
assert.EqualError(t, err, "CloudFlare credentials missing")
|
assert.EqualError(t, err, "CloudFlare credentials missing")
|
||||||
restoreCloudFlareEnv()
|
restoreCloudFlareEnv()
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ func TestCloudFlarePresent(t *testing.T) {
|
||||||
t.Skip("skipping live test")
|
t.Skip("skipping live test")
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := NewDNSProvider(cflareEmail, cflareAPIKey)
|
provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.Present(cflareDomain, "", "123d==")
|
err = provider.Present(cflareDomain, "", "123d==")
|
||||||
|
@ -72,7 +72,7 @@ func TestCloudFlareCleanUp(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(time.Second * 2)
|
time.Sleep(time.Second * 2)
|
||||||
|
|
||||||
provider, err := NewDNSProvider(cflareEmail, cflareAPIKey)
|
provider, err := NewDNSProviderCredentials(cflareEmail, cflareAPIKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.CleanUp(cflareDomain, "", "123d==")
|
err = provider.CleanUp(cflareDomain, "", "123d==")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Package digitalocean implements a DNS provider for solving the DNS-01 challenge using digitalocean DNS.
|
// Package digitalocean implements a DNS provider for solving the DNS-01
|
||||||
|
// challenge using digitalocean DNS.
|
||||||
package digitalocean
|
package digitalocean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -6,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -20,10 +22,20 @@ type DNSProvider struct {
|
||||||
recordIDsMu sync.Mutex
|
recordIDsMu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a new DNSProvider instance.
|
// NewDNSProvider returns a DNSProvider instance configured for Digital
|
||||||
// apiAuthToken is the personal access token created in the DigitalOcean account
|
// Ocean. Credentials must be passed in the environment variable:
|
||||||
// control panel, and it will be sent in bearer authorization headers.
|
// DO_AUTH_TOKEN.
|
||||||
func NewDNSProvider(apiAuthToken string) (*DNSProvider, error) {
|
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{
|
return &DNSProvider{
|
||||||
apiAuthToken: apiAuthToken,
|
apiAuthToken: apiAuthToken,
|
||||||
recordIDs: make(map[string]int),
|
recordIDs: make(map[string]int),
|
||||||
|
|
|
@ -53,7 +53,7 @@ func TestDigitalOceanPresent(t *testing.T) {
|
||||||
defer mock.Close()
|
defer mock.Close()
|
||||||
digitalOceanBaseURL = mock.URL
|
digitalOceanBaseURL = mock.URL
|
||||||
|
|
||||||
doprov, err := NewDNSProvider(fakeDigitalOceanAuth)
|
doprov, err := NewDNSProviderCredentials(fakeDigitalOceanAuth)
|
||||||
if doprov == nil {
|
if doprov == nil {
|
||||||
t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
|
t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ func TestDigitalOceanCleanUp(t *testing.T) {
|
||||||
defer mock.Close()
|
defer mock.Close()
|
||||||
digitalOceanBaseURL = mock.URL
|
digitalOceanBaseURL = mock.URL
|
||||||
|
|
||||||
doprov, err := NewDNSProvider(fakeDigitalOceanAuth)
|
doprov, err := NewDNSProviderCredentials(fakeDigitalOceanAuth)
|
||||||
if doprov == nil {
|
if doprov == nil {
|
||||||
t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
|
t.Fatal("Expected non-nil DigitalOcean provider, but was nil")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Package dnsimple implements a DNS provider for solving the DNS-01 challenge using dnsimple DNS.
|
// Package dnsimple implements a DNS provider for solving the DNS-01 challenge
|
||||||
|
// using dnsimple DNS.
|
||||||
package dnsimple
|
package dnsimple
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -15,22 +16,25 @@ type DNSProvider struct {
|
||||||
client *dnsimple.Client
|
client *dnsimple.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance with a configured dnsimple client.
|
// NewDNSProvider returns a DNSProvider instance configured for dnsimple.
|
||||||
// Authentication is either done using the passed credentials or - when empty - using the environment
|
// Credentials must be passed in the environment variables: DNSIMPLE_EMAIL
|
||||||
// variables DNSIMPLE_EMAIL and DNSIMPLE_API_KEY.
|
// and DNSIMPLE_API_KEY.
|
||||||
func NewDNSProvider(dnsimpleEmail, dnsimpleAPIKey string) (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
if dnsimpleEmail == "" || dnsimpleAPIKey == "" {
|
email := os.Getenv("DNSIMPLE_EMAIL")
|
||||||
dnsimpleEmail, dnsimpleAPIKey = dnsimpleEnvAuth()
|
key := os.Getenv("DNSIMPLE_API_KEY")
|
||||||
if dnsimpleEmail == "" || dnsimpleAPIKey == "" {
|
return NewDNSProviderCredentials(email, key)
|
||||||
return nil, fmt.Errorf("DNSimple credentials missing")
|
}
|
||||||
}
|
|
||||||
|
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||||
|
// DNSProvider instance configured for dnsimple.
|
||||||
|
func NewDNSProviderCredentials(email, key string) (*DNSProvider, error) {
|
||||||
|
if email == "" || key == "" {
|
||||||
|
return nil, fmt.Errorf("DNSimple credentials missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &DNSProvider{
|
return &DNSProvider{
|
||||||
client: dnsimple.NewClient(dnsimpleAPIKey, dnsimpleEmail),
|
client: dnsimple.NewClient(key, email),
|
||||||
}
|
}, nil
|
||||||
|
|
||||||
return c, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present creates a TXT record to fulfil the dns-01 challenge.
|
// Present creates a TXT record to fulfil the dns-01 challenge.
|
||||||
|
@ -130,12 +134,3 @@ func (c *DNSProvider) extractRecordName(fqdn, domain string) string {
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func dnsimpleEnvAuth() (email, apiKey string) {
|
|
||||||
email = os.Getenv("DNSIMPLE_EMAIL")
|
|
||||||
apiKey = os.Getenv("DNSIMPLE_API_KEY")
|
|
||||||
if len(email) == 0 || len(apiKey) == 0 {
|
|
||||||
return "", ""
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,14 +32,14 @@ func restoreDNSimpleEnv() {
|
||||||
func TestNewDNSProviderValid(t *testing.T) {
|
func TestNewDNSProviderValid(t *testing.T) {
|
||||||
os.Setenv("DNSIMPLE_EMAIL", "")
|
os.Setenv("DNSIMPLE_EMAIL", "")
|
||||||
os.Setenv("DNSIMPLE_API_KEY", "")
|
os.Setenv("DNSIMPLE_API_KEY", "")
|
||||||
_, err := NewDNSProvider("example@example.com", "123")
|
_, err := NewDNSProviderCredentials("example@example.com", "123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreDNSimpleEnv()
|
restoreDNSimpleEnv()
|
||||||
}
|
}
|
||||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
os.Setenv("DNSIMPLE_EMAIL", "example@example.com")
|
os.Setenv("DNSIMPLE_EMAIL", "example@example.com")
|
||||||
os.Setenv("DNSIMPLE_API_KEY", "123")
|
os.Setenv("DNSIMPLE_API_KEY", "123")
|
||||||
_, err := NewDNSProvider("", "")
|
_, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreDNSimpleEnv()
|
restoreDNSimpleEnv()
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||||
os.Setenv("DNSIMPLE_EMAIL", "")
|
os.Setenv("DNSIMPLE_EMAIL", "")
|
||||||
os.Setenv("DNSIMPLE_API_KEY", "")
|
os.Setenv("DNSIMPLE_API_KEY", "")
|
||||||
_, err := NewDNSProvider("", "")
|
_, err := NewDNSProvider()
|
||||||
assert.EqualError(t, err, "DNSimple credentials missing")
|
assert.EqualError(t, err, "DNSimple credentials missing")
|
||||||
restoreDNSimpleEnv()
|
restoreDNSimpleEnv()
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func TestLiveDNSimplePresent(t *testing.T) {
|
||||||
t.Skip("skipping live test")
|
t.Skip("skipping live test")
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := NewDNSProvider(dnsimpleEmail, dnsimpleAPIKey)
|
provider, err := NewDNSProviderCredentials(dnsimpleEmail, dnsimpleAPIKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.Present(dnsimpleDomain, "", "123d==")
|
err = provider.Present(dnsimpleDomain, "", "123d==")
|
||||||
|
@ -71,7 +71,7 @@ func TestLiveDNSimpleCleanUp(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
|
|
||||||
provider, err := NewDNSProvider(dnsimpleEmail, dnsimpleAPIKey)
|
provider, err := NewDNSProviderCredentials(dnsimpleEmail, dnsimpleAPIKey)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.CleanUp(dnsimpleDomain, "", "123d==")
|
err = provider.CleanUp(dnsimpleDomain, "", "123d==")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Package dyn implements a DNS provider for solving the DNS-01 challenge using Dyn Managed DNS.
|
// Package dyn implements a DNS provider for solving the DNS-01 challenge
|
||||||
|
// using Dyn Managed DNS.
|
||||||
package dyn
|
package dyn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -6,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -37,10 +39,23 @@ type DNSProvider struct {
|
||||||
token string
|
token string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a new DNSProvider instance. customerName is
|
// NewDNSProvider returns a DNSProvider instance configured for Dyn DNS.
|
||||||
// the customer name of the Dyn account. userName is the user name. password is
|
// Credentials must be passed in the environment variables: DYN_CUSTOMER_NAME,
|
||||||
// the password.
|
// DYN_USER_NAME and DYN_PASSWORD.
|
||||||
func NewDNSProvider(customerName, userName, password string) (*DNSProvider, error) {
|
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{
|
return &DNSProvider{
|
||||||
customerName: customerName,
|
customerName: customerName,
|
||||||
userName: userName,
|
userName: userName,
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestLiveDynPresent(t *testing.T) {
|
||||||
t.Skip("skipping live test")
|
t.Skip("skipping live test")
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := NewDNSProvider(dynCustomerName, dynUserName, dynPassword)
|
provider, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.Present(dynDomain, "", "123d==")
|
err = provider.Present(dynDomain, "", "123d==")
|
||||||
|
@ -45,7 +45,7 @@ func TestLiveDynCleanUp(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
|
|
||||||
provider, err := NewDNSProvider(dynCustomerName, dynUserName, dynPassword)
|
provider, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.CleanUp(dynDomain, "", "123d==")
|
err = provider.CleanUp(dynDomain, "", "123d==")
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -35,9 +36,16 @@ type DNSProvider struct {
|
||||||
inProgressMu sync.Mutex
|
inProgressMu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a new DNSProvider instance. apiKey is the
|
// NewDNSProvider returns a DNSProvider instance configured for Gandi.
|
||||||
// API access key obtained from the Gandi account control panel.
|
// Credentials must be passed in the environment variable: GANDI_API_KEY.
|
||||||
func NewDNSProvider(apiKey string) (*DNSProvider, error) {
|
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 == "" {
|
if apiKey == "" {
|
||||||
return nil, fmt.Errorf("No Gandi API Key given")
|
return nil, fmt.Errorf("No Gandi API Key given")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package gandi_test
|
package gandi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
@ -8,8 +8,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/xenolf/lego/providers/dns/gandi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestDNSProvider runs Present and CleanUp against a fake Gandi RPC
|
// TestDNSProvider runs Present and CleanUp against a fake Gandi RPC
|
||||||
|
@ -17,7 +15,7 @@ import (
|
||||||
func TestDNSProvider(t *testing.T) {
|
func TestDNSProvider(t *testing.T) {
|
||||||
fakeAPIKey := "123412341234123412341234"
|
fakeAPIKey := "123412341234123412341234"
|
||||||
fakeKeyAuth := "XXXX"
|
fakeKeyAuth := "XXXX"
|
||||||
provider, err := gandi.NewDNSProvider(fakeAPIKey)
|
provider, err := NewDNSProviderCredentials(fakeAPIKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -47,11 +45,11 @@ func TestDNSProvider(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
defer fakeServer.Close()
|
defer fakeServer.Close()
|
||||||
// override gandi endpoint to point to fake server
|
// override gandi endpoint to point to fake server
|
||||||
savedEndpoint := gandi.Endpoint
|
savedEndpoint := Endpoint
|
||||||
defer func() {
|
defer func() {
|
||||||
gandi.Endpoint = savedEndpoint
|
Endpoint = savedEndpoint
|
||||||
}()
|
}()
|
||||||
gandi.Endpoint = fakeServer.URL + "/"
|
Endpoint = fakeServer.URL + "/"
|
||||||
// run Present
|
// run Present
|
||||||
err = provider.Present("abc.def.example.com", "", fakeKeyAuth)
|
err = provider.Present("abc.def.example.com", "", fakeKeyAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,12 +22,16 @@ type DNSProvider struct {
|
||||||
client *dns.Service
|
client *dns.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance with a configured gcloud client.
|
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud
|
||||||
// Authentication is done using the local account credentials managed by the gcloud utility.
|
// DNS. Credentials must be passed in the environment variable: GCE_PROJECT.
|
||||||
func NewDNSProvider(project string) (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
if project == "" {
|
project := os.Getenv("GCE_PROJECT")
|
||||||
project = gcloudEnvAuth()
|
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 == "" {
|
if project == "" {
|
||||||
return nil, fmt.Errorf("Google Cloud project name missing")
|
return nil, fmt.Errorf("Google Cloud project name missing")
|
||||||
}
|
}
|
||||||
|
@ -149,7 +153,3 @@ func (c *DNSProvider) findTxtRecords(zone, fqdn string) ([]*dns.ResourceRecordSe
|
||||||
|
|
||||||
return found, nil
|
return found, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gcloudEnvAuth() (gcloud string) {
|
|
||||||
return os.Getenv("GCE_PROJECT")
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func TestNewDNSProviderValid(t *testing.T) {
|
||||||
t.Skip("skipping live test (requires credentials)")
|
t.Skip("skipping live test (requires credentials)")
|
||||||
}
|
}
|
||||||
os.Setenv("GCE_PROJECT", "")
|
os.Setenv("GCE_PROJECT", "")
|
||||||
_, err := NewDNSProvider("my-project")
|
_, err := NewDNSProviderCredentials("my-project")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreGCloudEnv()
|
restoreGCloudEnv()
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,14 @@ func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
t.Skip("skipping live test (requires credentials)")
|
t.Skip("skipping live test (requires credentials)")
|
||||||
}
|
}
|
||||||
os.Setenv("GCE_PROJECT", "my-project")
|
os.Setenv("GCE_PROJECT", "my-project")
|
||||||
_, err := NewDNSProvider("")
|
_, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreGCloudEnv()
|
restoreGCloudEnv()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||||
os.Setenv("GCE_PROJECT", "")
|
os.Setenv("GCE_PROJECT", "")
|
||||||
_, err := NewDNSProvider("")
|
_, err := NewDNSProvider()
|
||||||
assert.EqualError(t, err, "Google Cloud project name missing")
|
assert.EqualError(t, err, "Google Cloud project name missing")
|
||||||
restoreGCloudEnv()
|
restoreGCloudEnv()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func TestLiveGoogleCloudPresent(t *testing.T) {
|
||||||
t.Skip("skipping live test")
|
t.Skip("skipping live test")
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := NewDNSProvider(gcloudProject)
|
provider, err := NewDNSProviderCredentials(gcloudProject)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.Present(gcloudDomain, "", "123d==")
|
err = provider.Present(gcloudDomain, "", "123d==")
|
||||||
|
@ -77,7 +77,7 @@ func TestLiveGoogleCloudCleanUp(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
|
|
||||||
provider, err := NewDNSProvider(gcloudProject)
|
provider, err := NewDNSProviderCredentials(gcloudProject)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = provider.CleanUp(gcloudDomain, "", "123d==")
|
err = provider.CleanUp(gcloudDomain, "", "123d==")
|
||||||
|
|
|
@ -44,15 +44,20 @@ type DNSProvider struct {
|
||||||
clientIP string
|
clientIP string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a new DNSProvider instance. apiUser is the namecheap
|
// NewDNSProvider returns a DNSProvider instance configured for namecheap.
|
||||||
// API user's account name, and apiKey is the account's API access key.
|
// Credentials must be passed in the environment variables: NAMECHEAP_API_USER
|
||||||
func NewDNSProvider(apiUser, apiKey string) (*DNSProvider, error) {
|
// 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 == "" {
|
if apiUser == "" || apiKey == "" {
|
||||||
apiUser = os.Getenv("NAMECHEAP_API_USER")
|
return nil, fmt.Errorf("Namecheap credentials missing")
|
||||||
apiKey = os.Getenv("NAMECHEAP_API_KEY")
|
|
||||||
if apiUser == "" || apiKey == "" {
|
|
||||||
return nil, fmt.Errorf("Namecheap credentials missing")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIP, err := getClientIP()
|
clientIP, err := getClientIP()
|
||||||
|
@ -68,8 +73,9 @@ func NewDNSProvider(apiUser, apiKey string) (*DNSProvider, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout : Namecheap can sometimes take a long time to complete an update, so wait
|
// Timeout returns the timeout and interval to use when checking for DNS
|
||||||
// up to 60 minutes for the update to propagate.
|
// 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) {
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
return 60 * time.Minute, 15 * time.Second
|
return 60 * time.Minute, 15 * time.Second
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// Package rfc2136 implements a DNS provider for solving the DNS-01 challenge using the rfc2136 dynamic update.
|
// Package rfc2136 implements a DNS provider for solving the DNS-01 challenge
|
||||||
|
// using the rfc2136 dynamic update.
|
||||||
package rfc2136
|
package rfc2136
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -20,10 +22,29 @@ type DNSProvider struct {
|
||||||
tsigSecret string
|
tsigSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a new DNSProvider instance.
|
// NewDNSProvider returns a DNSProvider instance configured for rfc2136
|
||||||
// To disable TSIG authentication 'tsigAlgorithm, 'tsigKey' and 'tsigSecret' must be set to the empty string.
|
// dynamic update. Credentials must be passed in the environment variables:
|
||||||
// 'nameserver' must be a network address in the the form "host" or "host:port".
|
// RFC2136_NAMESERVER, RFC2136_TSIG_ALGORITHM, RFC2136_TSIG_KEY and
|
||||||
func NewDNSProvider(nameserver, tsigAlgorithm, tsigKey, tsigSecret string) (*DNSProvider, error) {
|
// RFC2136_TSIG_SECRET. To disable TSIG authentication, leave the TSIG
|
||||||
|
// variables unset. RFC2136_NAMESERVER must be a network address in the form
|
||||||
|
// "host" or "host:port".
|
||||||
|
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")
|
||||||
|
return NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 string) (*DNSProvider, error) {
|
||||||
|
if nameserver == "" {
|
||||||
|
return nil, fmt.Errorf("RFC2136 nameserver missing")
|
||||||
|
}
|
||||||
|
|
||||||
// Append the default DNS port if none is specified.
|
// Append the default DNS port if none is specified.
|
||||||
if _, _, err := net.SplitHostPort(nameserver); err != nil {
|
if _, _, err := net.SplitHostPort(nameserver); err != nil {
|
||||||
if strings.Contains(err.Error(), "missing port") {
|
if strings.Contains(err.Error(), "missing port") {
|
||||||
|
|
|
@ -61,9 +61,9 @@ func TestRFC2136ServerSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer server.Shutdown()
|
defer server.Shutdown()
|
||||||
|
|
||||||
provider, err := NewDNSProvider(addrstr, "", "", "")
|
provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err)
|
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
|
||||||
}
|
}
|
||||||
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
|
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
|
||||||
t.Errorf("Expected Present() to return no error but the error was -> %v", err)
|
t.Errorf("Expected Present() to return no error but the error was -> %v", err)
|
||||||
|
@ -81,9 +81,9 @@ func TestRFC2136ServerError(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer server.Shutdown()
|
defer server.Shutdown()
|
||||||
|
|
||||||
provider, err := NewDNSProvider(addrstr, "", "", "")
|
provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err)
|
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
|
||||||
}
|
}
|
||||||
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err == nil {
|
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err == nil {
|
||||||
t.Errorf("Expected Present() to return an error but it did not.")
|
t.Errorf("Expected Present() to return an error but it did not.")
|
||||||
|
@ -103,9 +103,9 @@ func TestRFC2136TsigClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer server.Shutdown()
|
defer server.Shutdown()
|
||||||
|
|
||||||
provider, err := NewDNSProvider(addrstr, "", rfc2136TestTsigKey, rfc2136TestTsigSecret)
|
provider, err := NewDNSProviderCredentials(addrstr, "", rfc2136TestTsigKey, rfc2136TestTsigSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err)
|
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
|
||||||
}
|
}
|
||||||
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
|
if err := provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth); err != nil {
|
||||||
t.Errorf("Expected Present() to return no error but the error was -> %v", err)
|
t.Errorf("Expected Present() to return no error but the error was -> %v", err)
|
||||||
|
@ -135,9 +135,9 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) {
|
||||||
t.Fatalf("Error packing expect msg: %v", err)
|
t.Fatalf("Error packing expect msg: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := NewDNSProvider(addrstr, "", "", "")
|
provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err)
|
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil {
|
if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
// Package route53 implements a DNS provider for solving the DNS-01 challenge using route53 DNS.
|
// Package route53 implements a DNS provider for solving the DNS-01 challenge
|
||||||
|
// using route53 DNS.
|
||||||
package route53
|
package route53
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -16,25 +18,35 @@ type DNSProvider struct {
|
||||||
client *route53.Route53
|
client *route53.Route53
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance with a configured route53 client.
|
// NewDNSProvider returns a DNSProvider instance configured for the AWS
|
||||||
// Authentication is either done using the passed credentials or - when empty - falling back to
|
// route53 service. The AWS region name must be passed in the environment
|
||||||
// the customary AWS credential mechanisms, including the file referenced by $AWS_CREDENTIAL_FILE
|
// variable AWS_REGION.
|
||||||
// (defaulting to $HOME/.aws/credentials) optionally scoped to $AWS_PROFILE, credentials
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
// supplied by the environment variables AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY [ + AWS_SECURITY_TOKEN ],
|
regionName := os.Getenv("AWS_REGION")
|
||||||
// and finally credentials available via the EC2 instance metadata service.
|
return NewDNSProviderCredentials("", "", regionName)
|
||||||
func NewDNSProvider(awsAccessKey, awsSecretKey, awsRegionName string) (*DNSProvider, error) {
|
}
|
||||||
region, ok := aws.Regions[awsRegionName]
|
|
||||||
|
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||||
|
// DNSProvider instance configured for the AWS route53 service. Authentication
|
||||||
|
// is done using the passed credentials or, if empty, falling back to the
|
||||||
|
// custonmary AWS credential mechanisms, including the file referenced by
|
||||||
|
// $AWS_CREDENTIAL_FILE (defaulting to $HOME/.aws/credentials) optionally
|
||||||
|
// scoped to $AWS_PROFILE, credentials supplied by the environment variables
|
||||||
|
// AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY [ + AWS_SECURITY_TOKEN ], and
|
||||||
|
// finally credentials available via the EC2 instance metadata service.
|
||||||
|
func NewDNSProviderCredentials(accessKey, secretKey, regionName string) (*DNSProvider, error) {
|
||||||
|
region, ok := aws.Regions[regionName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Invalid AWS region name %s", awsRegionName)
|
return nil, fmt.Errorf("Invalid AWS region name %s", regionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// use aws.GetAuth, which tries really hard to find credentails:
|
// use aws.GetAuth, which tries really hard to find credentails:
|
||||||
// - uses awsAccessKey and awsSecretKey, if provided
|
// - uses accessKey and secretKey, if provided
|
||||||
// - uses AWS_PROFILE / AWS_CREDENTIAL_FILE, if provided
|
// - uses AWS_PROFILE / AWS_CREDENTIAL_FILE, if provided
|
||||||
// - uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY and optionally AWS_SECURITY_TOKEN, if provided
|
// - uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY and optionally AWS_SECURITY_TOKEN, if provided
|
||||||
// - uses EC2 instance metadata credentials (http://169.254.169.254/latest/meta-data/…), if available
|
// - uses EC2 instance metadata credentials (http://169.254.169.254/latest/meta-data/…), if available
|
||||||
// ...and otherwise returns an error
|
// ...and otherwise returns an error
|
||||||
auth, err := aws.GetAuth(awsAccessKey, awsSecretKey)
|
auth, err := aws.GetAuth(accessKey, secretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,8 @@ func makeRoute53Provider(server *testutil.HTTPServer) *DNSProvider {
|
||||||
func TestNewDNSProviderValid(t *testing.T) {
|
func TestNewDNSProviderValid(t *testing.T) {
|
||||||
os.Setenv("AWS_ACCESS_KEY_ID", "")
|
os.Setenv("AWS_ACCESS_KEY_ID", "")
|
||||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "")
|
os.Setenv("AWS_SECRET_ACCESS_KEY", "")
|
||||||
_, err := NewDNSProvider("123", "123", "us-east-1")
|
os.Setenv("AWS_REGION", "")
|
||||||
|
_, err := NewDNSProviderCredentials("123", "123", "us-east-1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreRoute53Env()
|
restoreRoute53Env()
|
||||||
}
|
}
|
||||||
|
@ -108,7 +109,8 @@ func TestNewDNSProviderValid(t *testing.T) {
|
||||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||||
os.Setenv("AWS_ACCESS_KEY_ID", "123")
|
os.Setenv("AWS_ACCESS_KEY_ID", "123")
|
||||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "123")
|
os.Setenv("AWS_SECRET_ACCESS_KEY", "123")
|
||||||
_, err := NewDNSProvider("", "", "us-east-1")
|
os.Setenv("AWS_REGION", "us-east-1")
|
||||||
|
_, err := NewDNSProvider()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
restoreRoute53Env()
|
restoreRoute53Env()
|
||||||
}
|
}
|
||||||
|
@ -124,7 +126,7 @@ func TestNewDNSProviderMissingAuthErr(t *testing.T) {
|
||||||
awsClient := aws.RetryingClient
|
awsClient := aws.RetryingClient
|
||||||
aws.RetryingClient = &http.Client{Timeout: time.Millisecond}
|
aws.RetryingClient = &http.Client{Timeout: time.Millisecond}
|
||||||
|
|
||||||
_, err := NewDNSProvider("", "", "us-east-1")
|
_, err := NewDNSProviderCredentials("", "", "us-east-1")
|
||||||
assert.EqualError(t, err, "No valid AWS authentication found")
|
assert.EqualError(t, err, "No valid AWS authentication found")
|
||||||
restoreRoute53Env()
|
restoreRoute53Env()
|
||||||
|
|
||||||
|
@ -133,7 +135,7 @@ func TestNewDNSProviderMissingAuthErr(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSProviderInvalidRegionErr(t *testing.T) {
|
func TestNewDNSProviderInvalidRegionErr(t *testing.T) {
|
||||||
_, err := NewDNSProvider("123", "123", "us-east-3")
|
_, err := NewDNSProviderCredentials("123", "123", "us-east-3")
|
||||||
assert.EqualError(t, err, "Invalid AWS region name us-east-3")
|
assert.EqualError(t, err, "Invalid AWS region name us-east-3")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue