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/dns_providers.go2
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go39
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go27
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go8
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53.go24
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53_integration_test.go2
-rw-r--r--vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go18
7 files changed, 105 insertions, 15 deletions
diff --git a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go b/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
index 33fca0fad..af6c02cca 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
@@ -48,7 +48,7 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
case "dyn":
provider, err = dyn.NewDNSProvider()
case "exoscale":
- provider, err = exoscale.NewDNSProvider()
+ provider, err = exoscale.NewDNSProvider()
case "gandi":
provider, err = gandi.NewDNSProvider()
case "gcloud":
diff --git a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go b/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go
index ea6c0875c..ba753f6dc 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/googlecloud/googlecloud.go
@@ -4,12 +4,14 @@ 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"
@@ -22,9 +24,14 @@ type DNSProvider struct {
}
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud
-// DNS. Credentials must be passed in the environment variable: GCE_PROJECT.
+// 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)
}
@@ -49,6 +56,36 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
}, 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)
diff --git a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go b/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go
index 1f1af790f..dde42ddf1 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136.go
@@ -20,29 +20,32 @@ type DNSProvider struct {
tsigAlgorithm string
tsigKey string
tsigSecret string
+ timeout time.Duration
}
// NewDNSProvider returns a DNSProvider instance configured for rfc2136
-// dynamic update. Credentials must be passed in environment variables:
+// 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")
- return NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret)
+ 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 string) (*DNSProvider, error) {
+func NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret, timeout string) (*DNSProvider, error) {
if nameserver == "" {
return nil, fmt.Errorf("RFC2136 nameserver missing")
}
@@ -67,9 +70,27 @@ func NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret st
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)
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
index a2515e995..f3ca65b31 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/rfc2136/rfc2136_test.go
@@ -61,7 +61,7 @@ func TestRFC2136ServerSuccess(t *testing.T) {
}
defer server.Shutdown()
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
+ provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
if err != nil {
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
}
@@ -81,7 +81,7 @@ func TestRFC2136ServerError(t *testing.T) {
}
defer server.Shutdown()
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
+ provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
if err != nil {
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
}
@@ -103,7 +103,7 @@ func TestRFC2136TsigClient(t *testing.T) {
}
defer server.Shutdown()
- provider, err := NewDNSProviderCredentials(addrstr, "", rfc2136TestTsigKey, rfc2136TestTsigSecret)
+ provider, err := NewDNSProviderCredentials(addrstr, "", rfc2136TestTsigKey, rfc2136TestTsigSecret, "")
if err != nil {
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
}
@@ -135,7 +135,7 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) {
t.Fatalf("Error packing expect msg: %v", err)
}
- provider, err := NewDNSProviderCredentials(addrstr, "", "", "")
+ provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
if err != nil {
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
}
diff --git a/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go b/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go
index f3e53a8e5..934f0a2d4 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/route53/route53.go
@@ -5,6 +5,7 @@ package route53
import (
"fmt"
"math/rand"
+ "os"
"strings"
"time"
@@ -23,7 +24,8 @@ const (
// DNSProvider implements the acme.ChallengeProvider interface
type DNSProvider struct {
- client *route53.Route53
+ client *route53.Route53
+ hostedZoneID string
}
// customRetryer implements the client.Retryer interface by composing the
@@ -58,14 +60,22 @@ func (d customRetryer) RetryRules(r *request.Request) time.Duration {
// 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}, nil
+ return &DNSProvider{
+ client: client,
+ hostedZoneID: hostedZoneID,
+ }, nil
}
// Present creates a TXT record using the specified parameters
@@ -83,7 +93,7 @@ func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error {
}
func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
- hostedZoneID, err := getHostedZoneID(fqdn, r.client)
+ hostedZoneID, err := r.getHostedZoneID(fqdn)
if err != nil {
return fmt.Errorf("Failed to determine Route 53 hosted zone ID: %v", err)
}
@@ -124,7 +134,11 @@ func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
})
}
-func getHostedZoneID(fqdn string, client *route53.Route53) (string, error) {
+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
@@ -134,7 +148,7 @@ func getHostedZoneID(fqdn string, client *route53.Route53) (string, error) {
reqParams := &route53.ListHostedZonesByNameInput{
DNSName: aws.String(acme.UnFqdn(authZone)),
}
- resp, err := client.ListHostedZonesByName(reqParams)
+ resp, err := r.client.ListHostedZonesByName(reqParams)
if err != nil {
return "", err
}
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
index 64678906a..17ba4a08a 100644
--- 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
@@ -30,7 +30,7 @@ func TestRoute53TTL(t *testing.T) {
// unexported.
fqdn := "_acme-challenge." + m["route53Domain"] + "."
svc := route53.New(session.New())
- zoneID, err := getHostedZoneID(fqdn, svc)
+ zoneID, err := provider.getHostedZoneID(fqdn)
if err != nil {
provider.CleanUp(m["route53Domain"], "foo", "bar")
t.Fatalf("Fatal: %s", err.Error())
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
index ab8739a58..de4e28f3d 100644
--- a/vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go
+++ b/vendor/github.com/xenolf/lego/providers/dns/route53/route53_test.go
@@ -16,18 +16,21 @@ 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 {
@@ -67,6 +70,21 @@ func TestRegionFromEnv(t *testing.T) {
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},