forked from TrueCloudLab/lego
parent
8f9e90b2a0
commit
c4bbb4b819
55 changed files with 671 additions and 560 deletions
27
platform/config/env/env.go
vendored
Normal file
27
platform/config/env/env.go
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
package env
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Get environment variables
|
||||
func Get(names ...string) (map[string]string, error) {
|
||||
values := map[string]string{}
|
||||
|
||||
var missingEnvVars []string
|
||||
for _, envVar := range names {
|
||||
value := os.Getenv(envVar)
|
||||
if value == "" {
|
||||
missingEnvVars = append(missingEnvVars, envVar)
|
||||
}
|
||||
values[envVar] = value
|
||||
}
|
||||
|
||||
if len(missingEnvVars) > 0 {
|
||||
return nil, fmt.Errorf("some credentials information are missing: %s", strings.Join(missingEnvVars, ","))
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/edeckers/auroradnsclient/records"
|
||||
"github.com/edeckers/auroradnsclient/zones"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider describes a provider for AuroraDNS
|
||||
|
@ -22,20 +23,23 @@ type DNSProvider struct {
|
|||
// 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"
|
||||
values, err := env.Get("AURORA_USER_ID", "AURORA_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AuroraDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(endpoint, userID, key)
|
||||
endpoint := os.Getenv("AURORA_ENDPOINT")
|
||||
|
||||
return NewDNSProviderCredentials(endpoint, values["AURORA_USER_ID"], values["AURORA_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
// DNSProvider instance configured for AuroraDNS.
|
||||
func NewDNSProviderCredentials(baseURL string, userID string, key string) (*DNSProvider, error) {
|
||||
if baseURL == "" {
|
||||
baseURL = "https://api.auroradns.eu"
|
||||
}
|
||||
|
||||
client, err := auroradnsclient.NewAuroraDNSClient(baseURL, userID, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -69,7 +73,7 @@ func (provider *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
|
||||
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)
|
||||
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,
|
||||
|
|
|
@ -6,6 +6,9 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var fakeAuroraDNSUserID = "asdf1234"
|
||||
|
@ -26,28 +29,13 @@ func TestAuroraDNSPresent(t *testing.T) {
|
|||
|
||||
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)
|
||||
}
|
||||
assert.Equal(t, http.MethodPost, r.Method, "method")
|
||||
assert.Equal(t, "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records", r.URL.Path, "Path")
|
||||
assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type")
|
||||
|
||||
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)
|
||||
}
|
||||
require.NoError(t, err, "reading request body")
|
||||
assert.Equal(t, `{"type":"TXT","name":"_acme-challenge","content":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":300}`, string(reqBody))
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
fmt.Fprintf(w, `{
|
||||
|
@ -61,22 +49,13 @@ func TestAuroraDNSPresent(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, auroraProvider)
|
||||
|
||||
err = auroraProvider.Present("example.com", "", "foobar")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error creating TXT record, but got: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "fail to create TXT record")
|
||||
|
||||
if !requestReceived {
|
||||
t.Error("Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
|
||||
func TestAuroraDNSCleanUp(t *testing.T) {
|
||||
|
@ -105,18 +84,9 @@ func TestAuroraDNSCleanUp(t *testing.T) {
|
|||
|
||||
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)
|
||||
}
|
||||
assert.Equal(t, http.MethodDelete, r.Method, "method")
|
||||
assert.Equal(t, "/zones/c56a4180-65aa-42ec-a945-5fd21dec0538/records/ec56a4180-65aa-42ec-a945-5fd21dec0538", r.URL.Path, "Path")
|
||||
assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type")
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
fmt.Fprintf(w, `{}`)
|
||||
|
@ -124,25 +94,14 @@ func TestAuroraDNSCleanUp(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, auroraProvider)
|
||||
|
||||
err = auroraProvider.Present("example.com", "", "foobar")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error creating TXT record, but got: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "fail to create TXT record")
|
||||
|
||||
err = auroraProvider.CleanUp("example.com", "", "foobar")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error removing TXT record, but got: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "fail to remove TXT record")
|
||||
|
||||
if !requestReceived {
|
||||
t.Error("Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ package azure
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface
|
||||
|
@ -32,25 +33,25 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_SUBSCRIPTION_ID", "AZURE_TENANT_ID", "AZURE_RESOURCE_GROUP")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Azure: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(
|
||||
values["AZURE_CLIENT_ID"],
|
||||
values["AZURE_CLIENT_SECRET"],
|
||||
values["AZURE_SUBSCRIPTION_ID"],
|
||||
values["AZURE_TENANT_ID"],
|
||||
values["AZURE_RESOURCE_GROUP"],
|
||||
)
|
||||
}
|
||||
|
||||
// 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 == "" {
|
||||
var missingEnvVars []string
|
||||
for _, envVar := range []string{"AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_SUBSCRIPTION_ID", "AZURE_TENANT_ID", "AZURE_RESOURCE_GROUP"} {
|
||||
if os.Getenv(envVar) == "" {
|
||||
missingEnvVars = append(missingEnvVars, envVar)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Azure configuration missing: %s", strings.Join(missingEnvVars, ","))
|
||||
return nil, errors.New("Azure: some credentials information are missing")
|
||||
}
|
||||
|
||||
return &DNSProvider{
|
||||
|
|
|
@ -30,7 +30,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreAzureEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("AZURE_CLIENT_ID", azureClientID)
|
||||
os.Setenv("AZURE_SUBSCRIPTION_ID", azureSubscriptionID)
|
||||
}
|
||||
|
@ -39,27 +39,32 @@ func TestNewDNSProviderValid(t *testing.T) {
|
|||
if !azureLiveTest {
|
||||
t.Skip("skipping live test (requires credentials)")
|
||||
}
|
||||
|
||||
defer restoreEnv()
|
||||
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)")
|
||||
}
|
||||
|
||||
defer restoreEnv()
|
||||
os.Setenv("AZURE_CLIENT_ID", "other")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restoreAzureEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AZURE_SUBSCRIPTION_ID", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Azure configuration missing: AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SUBSCRIPTION_ID,AZURE_TENANT_ID,AZURE_RESOURCE_GROUP")
|
||||
restoreAzureEnv()
|
||||
assert.EqualError(t, err, "Azure: some credentials information are missing: AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SUBSCRIPTION_ID,AZURE_TENANT_ID,AZURE_RESOURCE_GROUP")
|
||||
}
|
||||
|
||||
func TestLiveAzurePresent(t *testing.T) {
|
||||
|
|
|
@ -6,16 +6,15 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
const bluecatURLTemplate = "%s/Services/REST/v1"
|
||||
|
@ -51,29 +50,42 @@ type DNSProvider struct {
|
|||
// and external DNS View Name must be passed in BLUECAT_CONFIG_NAME and
|
||||
// BLUECAT_DNS_VIEW
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
server := os.Getenv("BLUECAT_SERVER_URL")
|
||||
userName := os.Getenv("BLUECAT_USER_NAME")
|
||||
password := os.Getenv("BLUECAT_PASSWORD")
|
||||
configName := os.Getenv("BLUECAT_CONFIG_NAME")
|
||||
dnsView := os.Getenv("BLUECAT_DNS_VIEW")
|
||||
httpClient := http.Client{Timeout: 30 * time.Second}
|
||||
return NewDNSProviderCredentials(server, userName, password, configName, dnsView, httpClient)
|
||||
values, err := env.Get("BLUECAT_SERVER_URL", "BLUECAT_USER_NAME", "BLUECAT_CONFIG_NAME", "BLUECAT_CONFIG_NAME", "BLUECAT_DNS_VIEW")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("BlueCat: %v", err)
|
||||
}
|
||||
|
||||
httpClient := &http.Client{Timeout: 30 * time.Second}
|
||||
|
||||
return NewDNSProviderCredentials(
|
||||
values["BLUECAT_SERVER_URL"],
|
||||
values["BLUECAT_USER_NAME"],
|
||||
values["BLUECAT_PASSWORD"],
|
||||
values["BLUECAT_CONFIG_NAME"],
|
||||
values["BLUECAT_DNS_VIEW"],
|
||||
httpClient,
|
||||
)
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
// DNSProvider instance configured for Bluecat DNS.
|
||||
func NewDNSProviderCredentials(server, userName, password, configName, dnsView string, httpClient http.Client) (*DNSProvider, error) {
|
||||
func NewDNSProviderCredentials(server, userName, password, configName, dnsView string, httpClient *http.Client) (*DNSProvider, error) {
|
||||
if server == "" || userName == "" || password == "" || configName == "" || dnsView == "" {
|
||||
return nil, fmt.Errorf("Bluecat credentials missing")
|
||||
}
|
||||
|
||||
client := http.DefaultClient
|
||||
if httpClient != nil {
|
||||
client = httpClient
|
||||
}
|
||||
|
||||
return &DNSProvider{
|
||||
baseURL: fmt.Sprintf(bluecatURLTemplate, server),
|
||||
userName: userName,
|
||||
password: password,
|
||||
configName: configName,
|
||||
dnsView: dnsView,
|
||||
httpClient: http.DefaultClient,
|
||||
httpClient: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,15 @@ package cloudflare
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// CloudFlareAPIURL represents the API endpoint to call.
|
||||
|
@ -30,23 +30,19 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("CLOUDFLARE_EMAIL", "CLOUDFLARE_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CloudFlare: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["CLOUDFLARE_EMAIL"], values["CLOUDFLARE_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
// DNSProvider instance configured for cloudflare.
|
||||
func NewDNSProviderCredentials(email, key string) (*DNSProvider, error) {
|
||||
if email == "" || key == "" {
|
||||
missingEnvVars := []string{}
|
||||
if email == "" {
|
||||
missingEnvVars = append(missingEnvVars, "CLOUDFLARE_EMAIL")
|
||||
}
|
||||
if key == "" {
|
||||
missingEnvVars = append(missingEnvVars, "CLOUDFLARE_API_KEY")
|
||||
}
|
||||
return nil, fmt.Errorf("CloudFlare credentials missing: %s", strings.Join(missingEnvVars, ","))
|
||||
return nil, errors.New("CloudFlare: some credentials information are missing")
|
||||
}
|
||||
|
||||
return &DNSProvider{
|
||||
|
@ -63,7 +59,7 @@ func (c *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
|||
|
||||
// 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)
|
||||
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
||||
zoneID, err := c.getHostedZoneID(fqdn)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -73,7 +69,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
Type: "TXT",
|
||||
Name: acme.UnFqdn(fqdn),
|
||||
Content: value,
|
||||
TTL: 120,
|
||||
TTL: ttl,
|
||||
}
|
||||
|
||||
body, err := json.Marshal(rec)
|
||||
|
@ -122,7 +118,7 @@ func (c *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
|
|||
}
|
||||
|
||||
if len(hostedZone) != 1 {
|
||||
return "", fmt.Errorf("Zone %s not found in CloudFlare for domain %s", authZone, fqdn)
|
||||
return "", fmt.Errorf("zone %s not found in CloudFlare for domain %s", authZone, fqdn)
|
||||
}
|
||||
|
||||
return hostedZone[0].ID, nil
|
||||
|
@ -184,7 +180,7 @@ func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM
|
|||
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)
|
||||
return nil, fmt.Errorf("error querying Cloudflare API -> %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
|
|
@ -24,7 +24,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreCloudFlareEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("CLOUDFLARE_EMAIL", cflareEmail)
|
||||
os.Setenv("CLOUDFLARE_API_KEY", cflareAPIKey)
|
||||
}
|
||||
|
@ -32,32 +32,37 @@ func restoreCloudFlareEnv() {
|
|||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
os.Setenv("CLOUDFLARE_EMAIL", "")
|
||||
os.Setenv("CLOUDFLARE_API_KEY", "")
|
||||
defer restoreEnv()
|
||||
|
||||
_, err := NewDNSProviderCredentials("123", "123")
|
||||
|
||||
assert.NoError(t, err)
|
||||
restoreCloudFlareEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
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) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("CLOUDFLARE_EMAIL", "")
|
||||
os.Setenv("CLOUDFLARE_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "CloudFlare credentials missing: CLOUDFLARE_EMAIL,CLOUDFLARE_API_KEY")
|
||||
restoreCloudFlareEnv()
|
||||
assert.EqualError(t, err, "CloudFlare: some credentials information are missing: CLOUDFLARE_EMAIL,CLOUDFLARE_API_KEY")
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErrSingle(t *testing.T){
|
||||
os.Setenv("CLOUDFLARE_EMAIL", "awesome@possum.com")
|
||||
_, err:= NewDNSProvider()
|
||||
assert.EqualError(t, err, "CloudFlare credentials missing: CLOUDFLARE_API_KEY")
|
||||
restoreCloudFlareEnv()
|
||||
func TestNewDNSProviderMissingCredErrSingle(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("CLOUDFLARE_EMAIL", "awesome@possum.com")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "CloudFlare: some credentials information are missing: CLOUDFLARE_API_KEY")
|
||||
}
|
||||
|
||||
func TestCloudFlarePresent(t *testing.T) {
|
||||
|
|
|
@ -9,11 +9,11 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
const cloudXNSBaseURL = "https://www.cloudxns.net/api2/"
|
||||
|
@ -28,9 +28,12 @@ type DNSProvider struct {
|
|||
// Credentials must be passed in the environment variables: CLOUDXNS_API_KEY
|
||||
// and CLOUDXNS_SECRET_KEY.
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
apiKey := os.Getenv("CLOUDXNS_API_KEY")
|
||||
secretKey := os.Getenv("CLOUDXNS_SECRET_KEY")
|
||||
return NewDNSProviderCredentials(apiKey, secretKey)
|
||||
values, err := env.Get("CLOUDXNS_API_KEY", "CLOUDXNS_SECRET_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CloudXNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["CLOUDXNS_API_KEY"], values["CLOUDXNS_SECRET_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -24,33 +24,36 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreCloudXNSEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("CLOUDXNS_API_KEY", cxAPIKey)
|
||||
os.Setenv("CLOUDXNS_SECRET_KEY", cxSecretKey)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("CLOUDXNS_API_KEY", "")
|
||||
os.Setenv("CLOUDXNS_SECRET_KEY", "")
|
||||
|
||||
_, err := NewDNSProviderCredentials("123", "123")
|
||||
assert.NoError(t, err)
|
||||
restoreCloudXNSEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("CLOUDXNS_API_KEY", "123")
|
||||
os.Setenv("CLOUDXNS_SECRET_KEY", "123")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restoreCloudXNSEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("CLOUDXNS_API_KEY", "")
|
||||
os.Setenv("CLOUDXNS_SECRET_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "CloudXNS credentials missing")
|
||||
restoreCloudXNSEnv()
|
||||
assert.EqualError(t, err, "CloudXNS: some credentials information are missing: CLOUDXNS_API_KEY,CLOUDXNS_SECRET_KEY")
|
||||
}
|
||||
|
||||
func TestCloudXNSPresent(t *testing.T) {
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface
|
||||
|
@ -32,8 +32,12 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
|||
// 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)
|
||||
values, err := env.Get("DO_AUTH_TOKEN")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DigitalOcean: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["DO_AUTH_TOKEN"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -6,6 +6,9 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var fakeDigitalOceanAuth = "asdf1234"
|
||||
|
@ -16,26 +19,14 @@ func TestDigitalOceanPresent(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
assert.Equal(t, http.MethodPost, r.Method, "method")
|
||||
assert.Equal(t, "/v2/domains/example.com/records", r.URL.Path, "Path")
|
||||
assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type")
|
||||
assert.Equal(t, "Bearer asdf1234", r.Header.Get("Authorization"), "Authorization")
|
||||
|
||||
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","ttl":30}`; got != want {
|
||||
t.Errorf("Expected body data to be: `%s` but got `%s`", want, got)
|
||||
}
|
||||
require.NoError(t, err, "reading request body")
|
||||
assert.Equal(t, `{"type":"TXT","name":"_acme-challenge.example.com.","data":"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI","ttl":30}`, string(reqBody))
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
fmt.Fprintf(w, `{
|
||||
|
@ -54,20 +45,13 @@ func TestDigitalOceanPresent(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, doprov)
|
||||
|
||||
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")
|
||||
}
|
||||
require.NoError(t, err, "fail to create TXT record")
|
||||
|
||||
assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
|
||||
func TestDigitalOceanCleanUp(t *testing.T) {
|
||||
|
@ -76,19 +60,11 @@ func TestDigitalOceanCleanUp(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
assert.Equal(t, http.MethodDelete, r.Method, "method")
|
||||
assert.Equal(t, "/v2/domains/example.com/records/1234567", r.URL.Path, "Path")
|
||||
// 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)
|
||||
}
|
||||
assert.Equal(t, "application/json", r.Header.Get("Content-Type"), "Content-Type")
|
||||
assert.Equal(t, "Bearer asdf1234", r.Header.Get("Authorization"), "Authorization")
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}))
|
||||
|
@ -96,22 +72,15 @@ func TestDigitalOceanCleanUp(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, doprov)
|
||||
|
||||
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")
|
||||
}
|
||||
require.NoError(t, err, "fail to remove TXT record")
|
||||
|
||||
assert.True(t, requestReceived, "Expected request to be received by mock backend, but it wasn't")
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package dns
|
|||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -25,23 +24,24 @@ func restoreExoscaleEnv() {
|
|||
}
|
||||
|
||||
func TestKnownDNSProviderSuccess(t *testing.T) {
|
||||
defer restoreExoscaleEnv()
|
||||
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()
|
||||
|
||||
assert.IsType(t, &exoscale.DNSProvider{}, provider, "Not loaded correct DNS provider")
|
||||
}
|
||||
|
||||
func TestKnownDNSProviderError(t *testing.T) {
|
||||
defer restoreExoscaleEnv()
|
||||
os.Setenv("EXOSCALE_API_KEY", "")
|
||||
os.Setenv("EXOSCALE_API_SECRET", "")
|
||||
|
||||
_, err := NewDNSChallengeProviderByName("exoscale")
|
||||
assert.Error(t, err)
|
||||
restoreExoscaleEnv()
|
||||
}
|
||||
|
||||
func TestUnknownDNSProvider(t *testing.T) {
|
||||
|
|
|
@ -31,7 +31,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreDNSimpleEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("DNSIMPLE_OAUTH_TOKEN", dnsimpleOauthToken)
|
||||
os.Setenv("DNSIMPLE_BASE_URL", dnsimpleBaseURL)
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ func restoreDNSimpleEnv() {
|
|||
//
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreDNSimpleEnv()
|
||||
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123")
|
||||
|
||||
provider, err := NewDNSProvider()
|
||||
|
||||
assert.NotNil(t, provider)
|
||||
|
@ -52,10 +52,10 @@ func TestNewDNSProviderValid(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderValidWithBaseUrl(t *testing.T) {
|
||||
defer restoreDNSimpleEnv()
|
||||
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSIMPLE_OAUTH_TOKEN", "123")
|
||||
os.Setenv("DNSIMPLE_BASE_URL", "https://api.dnsimple.test")
|
||||
|
||||
provider, err := NewDNSProvider()
|
||||
|
||||
assert.NotNil(t, provider)
|
||||
|
@ -65,11 +65,8 @@ func TestNewDNSProviderValidWithBaseUrl(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderInvalidWithMissingOauthToken(t *testing.T) {
|
||||
if dnsimpleLiveTest {
|
||||
t.Skip("skipping test in live mode")
|
||||
}
|
||||
|
||||
defer restoreDNSimpleEnv()
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSIMPLE_OAUTH_TOKEN", "")
|
||||
|
||||
provider, err := NewDNSProvider()
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses
|
||||
|
@ -45,20 +46,19 @@ type Record struct {
|
|||
// 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")
|
||||
values, err := env.Get("DNSMADEEASY_API_KEY", "DNSMADEEASY_API_SECRET")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DNSMadeEasy: %v", err)
|
||||
}
|
||||
|
||||
var baseURL string
|
||||
|
||||
sandbox, _ := strconv.ParseBool(dnsmadeeasySandbox)
|
||||
if sandbox {
|
||||
if sandbox, _ := strconv.ParseBool(os.Getenv("DNSMADEEASY_SANDBOX")); sandbox {
|
||||
baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
|
||||
} else {
|
||||
baseURL = "https://api.dnsmadeeasy.com/V2.0"
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(baseURL, dnsmadeeasyAPIKey, dnsmadeeasyAPISecret)
|
||||
return NewDNSProviderCredentials(baseURL, values["DNSMADEEASY_API_KEY"], values["DNSMADEEASY_API_SECRET"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -4,11 +4,11 @@ package dnspod
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/decker502/dnspod-go"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
|
@ -19,8 +19,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("DNSPOD_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DNSPod: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["DNSPOD_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
@ -95,7 +99,7 @@ func (c *DNSProvider) getHostedZone(domain string) (string, string, error) {
|
|||
}
|
||||
|
||||
if hostedZone.ID == 0 {
|
||||
return "", "", fmt.Errorf("Zone %s not found in dnspod for domain %s", authZone, domain)
|
||||
return "", "", fmt.Errorf("zone %s not found in dnspod for domain %s", authZone, domain)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package dnspod
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -21,28 +22,31 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restorednspodEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("DNSPOD_API_KEY", dnspodAPIKey)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSPOD_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProviderCredentials("123")
|
||||
assert.NoError(t, err)
|
||||
restorednspodEnv()
|
||||
}
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSPOD_API_KEY", "123")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restorednspodEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("DNSPOD_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "dnspod credentials missing")
|
||||
restorednspodEnv()
|
||||
assert.EqualError(t, err, "DNSPod: some credentials information are missing: DNSPOD_API_KEY")
|
||||
}
|
||||
|
||||
func TestLivednspodPresent(t *testing.T) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Package duckdns Adds lego support for http://duckdns.org .
|
||||
// Package duckdns Adds lego support for http://duckdns.org.
|
||||
// See http://www.duckdns.org/spec.jsp for more info on updating TXT records.
|
||||
package duckdns
|
||||
|
||||
|
@ -6,30 +6,33 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider adds and removes the record for the DNS challenge
|
||||
type DNSProvider struct {
|
||||
// The duckdns api token
|
||||
// The api token
|
||||
token string
|
||||
}
|
||||
|
||||
// NewDNSProvider returns a new DNS provider using
|
||||
// environment variable DUCKDNS_TOKEN for adding and removing the DNS record.
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
duckdnsToken := os.Getenv("DUCKDNS_TOKEN")
|
||||
values, err := env.Get("DUCKDNS_TOKEN")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DuckDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(duckdnsToken)
|
||||
return NewDNSProviderCredentials(values["DUCKDNS_TOKEN"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
// DNSProvider instance configured for http://duckdns.org .
|
||||
func NewDNSProviderCredentials(duckdnsToken string) (*DNSProvider, error) {
|
||||
if duckdnsToken == "" {
|
||||
return nil, errors.New("environment variable DUCKDNS_TOKEN not set")
|
||||
return nil, errors.New("DuckDNS: credentials missing")
|
||||
}
|
||||
|
||||
return &DNSProvider{token: duckdnsToken}, nil
|
||||
|
|
|
@ -22,22 +22,26 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreDuckdnsEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("DUCKDNS_TOKEN", duckdnsToken)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("DUCKDNS_TOKEN", "123")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restoreDuckdnsEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("DUCKDNS_TOKEN", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "environment variable DUCKDNS_TOKEN not set")
|
||||
restoreDuckdnsEnv()
|
||||
assert.EqualError(t, err, "DuckDNS: some credentials information are missing: DUCKDNS_TOKEN")
|
||||
}
|
||||
|
||||
func TestLiveDuckdnsPresent(t *testing.T) {
|
||||
if !duckdnsLiveTest {
|
||||
t.Skip("skipping live test")
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
var dynBaseURL = "https://api.dynect.net/REST"
|
||||
|
@ -43,10 +43,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("DYN_CUSTOMER_NAME", "DYN_USER_NAME", "DYN_PASSWORD")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DynDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["DYN_CUSTOMER_NAME"], values["DYN_USER_NAME"], values["DYN_PASSWORD"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/exoscale/egoscale"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
|
@ -19,10 +20,13 @@ type DNSProvider struct {
|
|||
// NewDNSProvider 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")
|
||||
values, err := env.Get("EXOSCALE_API_KEY", "EXOSCALE_API_SECRET")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Exoscale: %v", err)
|
||||
}
|
||||
|
||||
endpoint := os.Getenv("EXOSCALE_ENDPOINT")
|
||||
return NewDNSProviderClient(key, secret, endpoint)
|
||||
return NewDNSProviderClient(values["EXOSCALE_API_KEY"], values["EXOSCALE_API_SECRET"], endpoint)
|
||||
}
|
||||
|
||||
// NewDNSProviderClient Uses the supplied parameters to return a DNSProvider instance
|
||||
|
@ -31,6 +35,7 @@ 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"
|
||||
}
|
||||
|
|
|
@ -24,32 +24,36 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreExoscaleEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("EXOSCALE_API_KEY", exoscaleAPIKey)
|
||||
os.Setenv("EXOSCALE_API_SECRET", exoscaleAPISecret)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
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) {
|
||||
defer restoreEnv()
|
||||
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", "")
|
||||
defer restoreEnv()
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Exoscale credentials missing")
|
||||
restoreExoscaleEnv()
|
||||
assert.EqualError(t, err, "Exoscale: some credentials information are missing: EXOSCALE_API_KEY,EXOSCALE_API_SECRET")
|
||||
}
|
||||
|
||||
func TestExtractRootRecordName(t *testing.T) {
|
||||
|
|
|
@ -2,12 +2,12 @@ package fastdns
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
configdns "github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1"
|
||||
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
|
@ -18,19 +18,24 @@ type DNSProvider struct {
|
|||
// NewDNSProvider uses the supplied environment variables to return a DNSProvider instance:
|
||||
// AKAMAI_HOST, AKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKEN
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
host := os.Getenv("AKAMAI_HOST")
|
||||
clientToken := os.Getenv("AKAMAI_CLIENT_TOKEN")
|
||||
clientSecret := os.Getenv("AKAMAI_CLIENT_SECRET")
|
||||
accessToken := os.Getenv("AKAMAI_ACCESS_TOKEN")
|
||||
values, err := env.Get("AKAMAI_HOST", "AKAMAI_CLIENT_TOKEN", "AKAMAI_CLIENT_SECRET", "AKAMAI_ACCESS_TOKEN")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FastDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderClient(host, clientToken, clientSecret, accessToken)
|
||||
return NewDNSProviderClient(
|
||||
values["AKAMAI_HOST"],
|
||||
values["AKAMAI_CLIENT_TOKEN"],
|
||||
values["AKAMAI_CLIENT_SECRET"],
|
||||
values["AKAMAI_ACCESS_TOKEN"],
|
||||
)
|
||||
}
|
||||
|
||||
// NewDNSProviderClient uses the supplied parameters to return a DNSProvider instance
|
||||
// configured for FastDNS.
|
||||
func NewDNSProviderClient(host, clientToken, clientSecret, accessToken string) (*DNSProvider, error) {
|
||||
if clientToken == "" || clientSecret == "" || accessToken == "" || host == "" {
|
||||
return nil, fmt.Errorf("Akamai FastDNS credentials missing")
|
||||
return nil, fmt.Errorf("FastDNS credentials are missing")
|
||||
}
|
||||
config := edgegrid.Config{
|
||||
Host: host,
|
||||
|
|
|
@ -29,7 +29,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreFastdnsEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("AKAMAI_HOST", host)
|
||||
os.Setenv("AKAMAI_CLIENT_TOKEN", clientToken)
|
||||
os.Setenv("AKAMAI_CLIENT_SECRET", clientSecret)
|
||||
|
@ -37,33 +37,36 @@ func restoreFastdnsEnv() {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AKAMAI_HOST", "")
|
||||
os.Setenv("AKAMAI_CLIENT_TOKEN", "")
|
||||
os.Setenv("AKAMAI_CLIENT_SECRET", "")
|
||||
os.Setenv("AKAMAI_ACCESS_TOKEN", "")
|
||||
|
||||
_, err := NewDNSProviderClient("somehost", "someclienttoken", "someclientsecret", "someaccesstoken")
|
||||
assert.NoError(t, err)
|
||||
restoreFastdnsEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AKAMAI_HOST", "somehost")
|
||||
os.Setenv("AKAMAI_CLIENT_TOKEN", "someclienttoken")
|
||||
os.Setenv("AKAMAI_CLIENT_SECRET", "someclientsecret")
|
||||
os.Setenv("AKAMAI_ACCESS_TOKEN", "someaccesstoken")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restoreFastdnsEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AKAMAI_HOST", "")
|
||||
os.Setenv("AKAMAI_CLIENT_TOKEN", "")
|
||||
os.Setenv("AKAMAI_CLIENT_SECRET", "")
|
||||
os.Setenv("AKAMAI_ACCESS_TOKEN", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Akamai FastDNS credentials missing")
|
||||
restoreFastdnsEnv()
|
||||
assert.EqualError(t, err, "FastDNS: some credentials information are missing: AKAMAI_HOST,AKAMAI_CLIENT_TOKEN,AKAMAI_CLIENT_SECRET,AKAMAI_ACCESS_TOKEN")
|
||||
}
|
||||
|
||||
func TestLiveFastdnsPresent(t *testing.T) {
|
||||
|
|
|
@ -9,12 +9,12 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// Gandi API reference: http://doc.rpc.gandi.net/index.html
|
||||
|
@ -49,8 +49,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("GANDI_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GandiDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["GANDI_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestDNSProvider runs Present and CleanUp against a fake Gandi RPC
|
||||
|
@ -15,55 +17,49 @@ import (
|
|||
func TestDNSProvider(t *testing.T) {
|
||||
fakeAPIKey := "123412341234123412341234"
|
||||
fakeKeyAuth := "XXXX"
|
||||
|
||||
provider, err := NewDNSProviderCredentials(fakeAPIKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
regexpDate, err := regexp.Compile(`\[ACME Challenge [^\]:]*:[^\]]*\]`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, 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")
|
||||
}
|
||||
require.Equal(t, "text/xml", r.Header.Get("Content-Type"), "invalid content type")
|
||||
|
||||
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]`))
|
||||
require.NoError(t, 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")
|
||||
}
|
||||
require.True(t, ok, "Server response for request not found")
|
||||
|
||||
_, err = io.Copy(w, strings.NewReader(resp))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, 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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// run CleanUp
|
||||
err = provider.CleanUp("abc.def.example.com", "", fakeKeyAuth)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// serverResponses is the XML-RPC Request->Response map used by the
|
||||
|
|
|
@ -7,12 +7,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// Gandi API reference: http://doc.livedns.gandi.net/
|
||||
|
@ -45,8 +45,12 @@ type DNSProvider struct {
|
|||
// NewDNSProvider returns a DNSProvider instance configured for Gandi.
|
||||
// Credentials must be passed in the environment variable: GANDIV5_API_KEY.
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
apiKey := os.Getenv("GANDIV5_API_KEY")
|
||||
return NewDNSProviderCredentials(apiKey)
|
||||
values, err := env.Get("GANDIV5_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GandiDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["GANDIV5_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestDNSProvider runs Present and CleanUp against a fake Gandi RPC
|
||||
|
@ -15,55 +17,50 @@ import (
|
|||
func TestDNSProvider(t *testing.T) {
|
||||
fakeAPIKey := "123412341234123412341234"
|
||||
fakeKeyAuth := "XXXX"
|
||||
|
||||
provider, err := NewDNSProviderCredentials(fakeAPIKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
regexpToken, err := regexp.Compile(`"rrset_values":\[".+"\]`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// start fake RPC server
|
||||
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
t.Fatalf("Content-Type: application/json header not found")
|
||||
}
|
||||
require.Equal(t, "application/json", r.Header.Get("Content-Type"), "invalid content type")
|
||||
|
||||
req, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req = regexpToken.ReplaceAllLiteral(
|
||||
req, []byte(`"rrset_values":["TOKEN"]`))
|
||||
require.NoError(t, err)
|
||||
|
||||
req = regexpToken.ReplaceAllLiteral(req, []byte(`"rrset_values":["TOKEN"]`))
|
||||
|
||||
resp, ok := serverResponses[string(req)]
|
||||
if !ok {
|
||||
t.Fatalf("Server response for request not found")
|
||||
}
|
||||
require.True(t, ok, "Server response for request not found")
|
||||
|
||||
_, err = io.Copy(w, strings.NewReader(resp))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, 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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// run CleanUp
|
||||
err = provider.CleanUp("abc.def.example.com", "", fakeKeyAuth)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// serverResponses is the JSON Request->Response map used by the
|
||||
|
|
|
@ -31,6 +31,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
|||
if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok {
|
||||
return NewDNSProviderServiceAccount(saFile)
|
||||
}
|
||||
|
||||
project := os.Getenv("GCE_PROJECT")
|
||||
return NewDNSProviderCredentials(project)
|
||||
}
|
||||
|
@ -44,11 +45,11 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
|
|||
|
||||
client, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to get Google Cloud client: %v", err)
|
||||
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 nil, fmt.Errorf("unable to create Google Cloud DNS service: %v", err)
|
||||
}
|
||||
return &DNSProvider{
|
||||
project: project,
|
||||
|
@ -65,7 +66,7 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
|||
|
||||
dat, err := ioutil.ReadFile(saFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to read Service Account file: %v", err)
|
||||
return nil, fmt.Errorf("unable to read Service Account file: %v", err)
|
||||
}
|
||||
|
||||
// read project id from service account file
|
||||
|
@ -74,19 +75,19 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
|||
}
|
||||
err = json.Unmarshal(dat, &datJSON)
|
||||
if err != nil || datJSON.ProjectID == "" {
|
||||
return nil, fmt.Errorf("Project ID not found in Google Cloud Service Account file")
|
||||
return nil, fmt.Errorf("project ID not found in Google Cloud Service Account file")
|
||||
}
|
||||
project := datJSON.ProjectID
|
||||
|
||||
conf, err := google.JWTConfigFromJSON(dat, dns.NdevClouddnsReadwriteScope)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to acquire config: %v", err)
|
||||
return nil, fmt.Errorf("unable to acquire config: %v", err)
|
||||
}
|
||||
client := conf.Client(context.Background())
|
||||
|
||||
svc, err := dns.New(client)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err)
|
||||
return nil, fmt.Errorf("unable to create Google Cloud DNS service: %v", err)
|
||||
}
|
||||
return &DNSProvider{
|
||||
project: project,
|
||||
|
@ -189,7 +190,7 @@ func (c *DNSProvider) getHostedZone(domain string) (string, error) {
|
|||
}
|
||||
|
||||
if len(zones.ManagedZones) == 0 {
|
||||
return "", fmt.Errorf("No matching GoogleCloud domain found for domain %s", authZone)
|
||||
return "", fmt.Errorf("no matching GoogleCloud domain found for domain %s", authZone)
|
||||
}
|
||||
|
||||
return zones.ManagedZones[0].Name, nil
|
||||
|
@ -202,7 +203,7 @@ func (c *DNSProvider) findTxtRecords(zone, fqdn string) ([]*dns.ResourceRecordSe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
found := []*dns.ResourceRecordSet{}
|
||||
var found []*dns.ResourceRecordSet
|
||||
for _, r := range recs.Rrsets {
|
||||
if r.Type == "TXT" && r.Name == fqdn {
|
||||
found = append(found, r)
|
||||
|
|
|
@ -27,7 +27,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreGCloudEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("GCE_PROJECT", gcloudProject)
|
||||
}
|
||||
|
||||
|
@ -35,27 +35,32 @@ func TestNewDNSProviderValid(t *testing.T) {
|
|||
if !gcloudLiveTest {
|
||||
t.Skip("skipping live test (requires credentials)")
|
||||
}
|
||||
|
||||
defer restoreEnv()
|
||||
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)")
|
||||
}
|
||||
|
||||
defer restoreEnv()
|
||||
os.Setenv("GCE_PROJECT", "my-project")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
restoreGCloudEnv()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("GCE_PROJECT", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Google Cloud project name missing")
|
||||
restoreGCloudEnv()
|
||||
}
|
||||
|
||||
func TestLiveGoogleCloudPresent(t *testing.T) {
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/log"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// GleSYS API reference: https://github.com/GleSYS/API/wiki/API-Documentation
|
||||
|
@ -35,9 +35,12 @@ type DNSProvider struct {
|
|||
// Credentials must be passed in the environment variables: GLESYS_API_USER
|
||||
// and GLESYS_API_KEY.
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
apiUser := os.Getenv("GLESYS_API_USER")
|
||||
apiKey := os.Getenv("GLESYS_API_KEY")
|
||||
return NewDNSProviderCredentials(apiUser, apiKey)
|
||||
values, err := env.Get("GLESYS_API_USER", "GLESYS_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GleSYS DNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["GLESYS_API_USER"], values["GLESYS_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -2,18 +2,17 @@
|
|||
package godaddy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// GoDaddyAPIURL represents the API endpoint to call.
|
||||
|
@ -29,9 +28,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("GODADDY_API_KEY", "GODADDY_API_SECRET")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GoDaddy: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["GODADDY_API_KEY"], values["GODADDY_API_SECRET"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -8,40 +8,40 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/lightsail"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLightsailTTL(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())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(m["lightsailDomain"], "foo", "bar")
|
||||
if err != nil {
|
||||
t.Fatalf("Fatal: %s", err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// we need a separate Lightshail client here as the one in the DNS provider is
|
||||
// unexported.
|
||||
fqdn := "_acme-challenge." + m["lightsailDomain"]
|
||||
svc := lightsail.New(session.New())
|
||||
if err != nil {
|
||||
provider.CleanUp(m["lightsailDomain"], "foo", "bar")
|
||||
t.Fatalf("Fatal: %s", err.Error())
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
params := &lightsail.GetDomainInput{
|
||||
DomainName: aws.String(m["lightsailDomain"]),
|
||||
}
|
||||
|
||||
resp, err := svc.GetDomain(params)
|
||||
if err != nil {
|
||||
provider.CleanUp(m["lightsailDomain"], "foo", "bar")
|
||||
t.Fatalf("Fatal: %s", err.Error())
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
entries := resp.Domain.DomainEntries
|
||||
for _, entry := range entries {
|
||||
if *entry.Type == "TXT" && *entry.Name == fqdn {
|
||||
|
@ -49,6 +49,7 @@ func TestLightsailTTL(t *testing.T) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
provider.CleanUp(m["lightsailDomain"], "foo", "bar")
|
||||
t.Fatalf("Could not find a TXT record for _acme-challenge.%s", m["lightsailDomain"])
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func init() {
|
|||
lightsailSecret = os.Getenv("AWS_SECRET_ACCESS_KEY")
|
||||
}
|
||||
|
||||
func restoreLightsailEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", lightsailKey)
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", lightsailSecret)
|
||||
os.Setenv("AWS_REGION", "us-east-1")
|
||||
|
@ -43,6 +43,7 @@ func makeLightsailProvider(ts *httptest.Server) *DNSProvider {
|
|||
}
|
||||
|
||||
func TestCredentialsFromEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "123")
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "123")
|
||||
os.Setenv("AWS_REGION", "us-east-1")
|
||||
|
@ -54,8 +55,6 @@ func TestCredentialsFromEnv(t *testing.T) {
|
|||
sess := session.New(config)
|
||||
_, err := sess.Config.Credentials.Get()
|
||||
assert.NoError(t, err, "Expected credentials to be set from environment")
|
||||
|
||||
restoreLightsailEnv()
|
||||
}
|
||||
|
||||
func TestLightsailPresent(t *testing.T) {
|
||||
|
|
|
@ -4,12 +4,13 @@ package linode
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/timewasted/linode/dns"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -31,8 +32,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("LINODE_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Linode: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["LINODE_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -48,8 +48,7 @@ func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server {
|
|||
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)
|
||||
require.FailNowf(t, "Unsupported mock action: %s", action)
|
||||
}
|
||||
|
||||
// Build the response that the server will return.
|
||||
|
@ -75,17 +74,19 @@ func newMockServer(t *testing.T, responses MockResponseMap) *httptest.Server {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderWithEnv(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderWithoutEnv(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Linode credentials missing")
|
||||
assert.EqualError(t, err, "Linode: some credentials information are missing: LINODE_API_KEY")
|
||||
}
|
||||
|
||||
func TestNewDNSProviderCredentialsWithKey(t *testing.T) {
|
||||
|
@ -99,8 +100,9 @@ func TestNewDNSProviderCredentialsWithoutKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_Present(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -109,7 +111,7 @@ func TestDNSProvider_Present(t *testing.T) {
|
|||
mockResponses := MockResponseMap{
|
||||
"domain.list": MockResponse{
|
||||
Response: []dns.Domain{
|
||||
dns.Domain{
|
||||
{
|
||||
Domain: domain,
|
||||
DomainID: 1234,
|
||||
},
|
||||
|
@ -121,8 +123,10 @@ func TestDNSProvider_Present(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
mockSrv := newMockServer(t, mockResponses)
|
||||
defer mockSrv.Close()
|
||||
|
||||
p.linode.ToLinode().SetEndpoint(mockSrv.URL)
|
||||
|
||||
err = p.Present(domain, "", keyAuth)
|
||||
|
@ -130,8 +134,9 @@ func TestDNSProvider_Present(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_PresentNoDomain(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -140,15 +145,17 @@ func TestDNSProvider_PresentNoDomain(t *testing.T) {
|
|||
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)
|
||||
|
@ -156,8 +163,9 @@ func TestDNSProvider_PresentNoDomain(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_PresentCreateFailed(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -166,7 +174,7 @@ func TestDNSProvider_PresentCreateFailed(t *testing.T) {
|
|||
mockResponses := MockResponseMap{
|
||||
"domain.list": MockResponse{
|
||||
Response: []dns.Domain{
|
||||
dns.Domain{
|
||||
{
|
||||
Domain: domain,
|
||||
DomainID: 1234,
|
||||
},
|
||||
|
@ -175,7 +183,7 @@ func TestDNSProvider_PresentCreateFailed(t *testing.T) {
|
|||
"domain.resource.create": MockResponse{
|
||||
Response: nil,
|
||||
Errors: []linode.ResponseError{
|
||||
linode.ResponseError{
|
||||
{
|
||||
Code: 1234,
|
||||
Message: "Failed to create domain resource",
|
||||
},
|
||||
|
@ -184,6 +192,7 @@ func TestDNSProvider_PresentCreateFailed(t *testing.T) {
|
|||
}
|
||||
mockSrv := newMockServer(t, mockResponses)
|
||||
defer mockSrv.Close()
|
||||
|
||||
p.linode.ToLinode().SetEndpoint(mockSrv.URL)
|
||||
|
||||
err = p.Present(domain, "", keyAuth)
|
||||
|
@ -197,8 +206,9 @@ func TestDNSProvider_PresentLive(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_CleanUp(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -207,7 +217,7 @@ func TestDNSProvider_CleanUp(t *testing.T) {
|
|||
mockResponses := MockResponseMap{
|
||||
"domain.list": MockResponse{
|
||||
Response: []dns.Domain{
|
||||
dns.Domain{
|
||||
{
|
||||
Domain: domain,
|
||||
DomainID: 1234,
|
||||
},
|
||||
|
@ -215,7 +225,7 @@ func TestDNSProvider_CleanUp(t *testing.T) {
|
|||
},
|
||||
"domain.resource.list": MockResponse{
|
||||
Response: []dns.Resource{
|
||||
dns.Resource{
|
||||
{
|
||||
DomainID: 1234,
|
||||
Name: "_acme-challenge",
|
||||
ResourceID: 1234,
|
||||
|
@ -230,8 +240,10 @@ func TestDNSProvider_CleanUp(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
mockSrv := newMockServer(t, mockResponses)
|
||||
defer mockSrv.Close()
|
||||
|
||||
p.linode.ToLinode().SetEndpoint(mockSrv.URL)
|
||||
|
||||
err = p.CleanUp(domain, "", keyAuth)
|
||||
|
@ -239,8 +251,9 @@ func TestDNSProvider_CleanUp(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_CleanUpNoDomain(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -249,15 +262,17 @@ func TestDNSProvider_CleanUpNoDomain(t *testing.T) {
|
|||
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)
|
||||
|
@ -265,8 +280,9 @@ func TestDNSProvider_CleanUpNoDomain(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDNSProvider_CleanUpDeleteFailed(t *testing.T) {
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
defer restoreEnv()
|
||||
os.Setenv("LINODE_API_KEY", "testing")
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -275,7 +291,7 @@ func TestDNSProvider_CleanUpDeleteFailed(t *testing.T) {
|
|||
mockResponses := MockResponseMap{
|
||||
"domain.list": MockResponse{
|
||||
Response: []dns.Domain{
|
||||
dns.Domain{
|
||||
{
|
||||
Domain: domain,
|
||||
DomainID: 1234,
|
||||
},
|
||||
|
@ -283,7 +299,7 @@ func TestDNSProvider_CleanUpDeleteFailed(t *testing.T) {
|
|||
},
|
||||
"domain.resource.list": MockResponse{
|
||||
Response: []dns.Resource{
|
||||
dns.Resource{
|
||||
{
|
||||
DomainID: 1234,
|
||||
Name: "_acme-challenge",
|
||||
ResourceID: 1234,
|
||||
|
@ -295,23 +311,19 @@ func TestDNSProvider_CleanUpDeleteFailed(t *testing.T) {
|
|||
"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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// Notes about namecheap's tool API:
|
||||
|
@ -48,9 +48,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("NAMECHEAP_API_USER", "NAMECHEAP_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NameCheap: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["NAMECHEAP_API_USER"], values["NAMECHEAP_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
@ -117,7 +120,7 @@ func getClientIP() (addr string, err error) {
|
|||
return string(clientIP), nil
|
||||
}
|
||||
|
||||
// A challenge repesents all the data needed to specify a dns-01 challenge
|
||||
// A challenge represents all the data needed to specify a dns-01 challenge
|
||||
// to lets-encrypt.
|
||||
type challenge struct {
|
||||
domain string
|
||||
|
|
|
@ -241,24 +241,27 @@ func TestNamecheapDomainSplit(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
valid := true
|
||||
ch, err := newChallenge(test.domain, "", tlds)
|
||||
if err != nil {
|
||||
valid = false
|
||||
}
|
||||
test := test
|
||||
t.Run(test.domain, func(t *testing.T) {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/namedotcom/go/namecom"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
|
@ -19,11 +20,13 @@ type DNSProvider struct {
|
|||
// NewDNSProvider returns a DNSProvider instance configured for namedotcom.
|
||||
// Credentials must be passed in the environment variables: NAMECOM_USERNAME and NAMECOM_API_TOKEN
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
username := os.Getenv("NAMECOM_USERNAME")
|
||||
apiToken := os.Getenv("NAMECOM_API_TOKEN")
|
||||
server := os.Getenv("NAMECOM_SERVER")
|
||||
values, err := env.Get("NAMECOM_USERNAME", "NAMECOM_API_TOKEN")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Name.com: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(username, apiToken, server)
|
||||
server := os.Getenv("NAMECOM_SERVER")
|
||||
return NewDNSProviderCredentials(values["NAMECOM_USERNAME"], values["NAMECOM_API_TOKEN"], server)
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
@ -59,7 +62,7 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
|
||||
_, err := c.client.CreateRecord(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("namedotcom API call failed: %v", err)
|
||||
return fmt.Errorf("Name.com API call failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -27,7 +27,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLivenamedotcomPresent(t *testing.T) {
|
||||
func TestLiveNamedotcomPresent(t *testing.T) {
|
||||
if !namedotcomLiveTest {
|
||||
t.Skip("skipping live test")
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func TestLivenamedotcomPresent(t *testing.T) {
|
|||
// Cleanup
|
||||
//
|
||||
|
||||
func TestLivenamedotcomCleanUp(t *testing.T) {
|
||||
func TestLiveNamedotcomCleanUp(t *testing.T) {
|
||||
if !namedotcomLiveTest {
|
||||
t.Skip("skipping live test")
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ package ns1
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
)
|
||||
|
@ -21,11 +21,12 @@ type DNSProvider struct {
|
|||
// 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")
|
||||
values, err := env.Get("NS1_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NS1: %v", err)
|
||||
}
|
||||
return NewDNSProviderCredentials(key)
|
||||
|
||||
return NewDNSProviderCredentials(values["NS1_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -22,22 +22,24 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restoreNS1Env() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("NS1_API_KEY", apiKey)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("NS1_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProviderCredentials("123")
|
||||
assert.NoError(t, err)
|
||||
restoreNS1Env()
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("NS1_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "NS1 credentials missing")
|
||||
restoreNS1Env()
|
||||
assert.EqualError(t, err, "NS1: some credentials information are missing: NS1_API_KEY")
|
||||
}
|
||||
|
||||
func TestLivePresent(t *testing.T) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses
|
||||
|
@ -31,12 +32,18 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("OTC_DOMAIN_NAME", "OTC_USER_NAME", "OTC_PASSWORD", "OTC_PROJECT_NAME")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OTC: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(
|
||||
values["OTC_DOMAIN_NAME"],
|
||||
values["OTC_USER_NAME"],
|
||||
values["OTC_PASSWORD"],
|
||||
values["OTC_PROJECT_NAME"],
|
||||
os.Getenv("OTC_IDENTITY_ENDPOINT"),
|
||||
)
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -2,10 +2,11 @@ package otc
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type OTCDNSTestSuite struct {
|
||||
|
@ -34,6 +35,8 @@ func (s *OTCDNSTestSuite) createDNSProvider() (*DNSProvider, error) {
|
|||
}
|
||||
|
||||
func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() {
|
||||
defer os.Clearenv()
|
||||
|
||||
os.Setenv("OTC_DOMAIN_NAME", "unittest1")
|
||||
os.Setenv("OTC_USER_NAME", "unittest2")
|
||||
os.Setenv("OTC_PASSWORD", "unittest3")
|
||||
|
@ -53,15 +56,13 @@ func (s *OTCDNSTestSuite) TestOTCDNSLoginEnv() {
|
|||
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())
|
||||
defer os.Clearenv()
|
||||
|
||||
os.Clearenv()
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(s.T(), err, "OTC: some credentials information are missing: OTC_DOMAIN_NAME,OTC_USER_NAME,OTC_PASSWORD,OTC_PROJECT_NAME")
|
||||
}
|
||||
|
||||
func (s *OTCDNSTestSuite) TestOTCDNSLogin() {
|
||||
|
|
|
@ -4,12 +4,12 @@ package ovh
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/ovh/go-ovh/ovh"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// OVH API reference: https://eu.api.ovh.com/
|
||||
|
@ -30,11 +30,17 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("OVH_ENDPOINT", "OVH_APPLICATION_KEY", "OVH_APPLICATION_SECRET", "OVH_CONSUMER_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OVH: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(
|
||||
values["OVH_ENDPOINT"],
|
||||
values["OVH_APPLICATION_KEY"],
|
||||
values["OVH_APPLICATION_SECRET"],
|
||||
values["OVH_CONSUMER_KEY"],
|
||||
)
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -33,47 +33,88 @@ func restoreEnv() {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
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")
|
||||
testCases := []struct {
|
||||
desc string
|
||||
envVars map[string]string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "missing OVH_ENDPOINT",
|
||||
envVars: map[string]string{
|
||||
"OVH_ENDPOINT": "",
|
||||
"OVH_APPLICATION_KEY": "1234",
|
||||
"OVH_APPLICATION_SECRET": "5678",
|
||||
"OVH_CONSUMER_KEY": "abcde",
|
||||
},
|
||||
expected: "OVH: some credentials information are missing: OVH_ENDPOINT",
|
||||
},
|
||||
{
|
||||
desc: "missing OVH_APPLICATION_KEY",
|
||||
envVars: map[string]string{
|
||||
"OVH_ENDPOINT": "ovh-eu",
|
||||
"OVH_APPLICATION_KEY": "",
|
||||
"OVH_APPLICATION_SECRET": "5678",
|
||||
"OVH_CONSUMER_KEY": "abcde",
|
||||
},
|
||||
expected: "OVH: some credentials information are missing: OVH_APPLICATION_KEY",
|
||||
},
|
||||
{
|
||||
desc: "missing OVH_APPLICATION_SECRET",
|
||||
envVars: map[string]string{
|
||||
"OVH_ENDPOINT": "ovh-eu",
|
||||
"OVH_APPLICATION_KEY": "1234",
|
||||
"OVH_APPLICATION_SECRET": "",
|
||||
"OVH_CONSUMER_KEY": "abcde",
|
||||
},
|
||||
expected: "OVH: some credentials information are missing: OVH_APPLICATION_SECRET",
|
||||
},
|
||||
{
|
||||
desc: "missing OVH_CONSUMER_KEY",
|
||||
envVars: map[string]string{
|
||||
"OVH_ENDPOINT": "ovh-eu",
|
||||
"OVH_APPLICATION_KEY": "1234",
|
||||
"OVH_APPLICATION_SECRET": "5678",
|
||||
"OVH_CONSUMER_KEY": "",
|
||||
},
|
||||
expected: "OVH: some credentials information are missing: OVH_CONSUMER_KEY",
|
||||
},
|
||||
{
|
||||
desc: "all missing",
|
||||
envVars: map[string]string{
|
||||
"OVH_ENDPOINT": "",
|
||||
"OVH_APPLICATION_KEY": "",
|
||||
"OVH_APPLICATION_SECRET": "",
|
||||
"OVH_CONSUMER_KEY": "",
|
||||
},
|
||||
expected: "OVH: some credentials information are missing: OVH_ENDPOINT,OVH_APPLICATION_KEY,OVH_APPLICATION_SECRET,OVH_CONSUMER_KEY",
|
||||
},
|
||||
}
|
||||
|
||||
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")
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(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", "")
|
||||
defer restoreEnv()
|
||||
_, err = NewDNSProvider()
|
||||
assert.EqualError(t, err, "OVH credentials missing")
|
||||
for key, value := range test.envVars {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, test.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLivePresent(t *testing.T) {
|
||||
|
|
|
@ -9,12 +9,12 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface
|
||||
|
@ -28,13 +28,17 @@ type DNSProvider struct {
|
|||
// 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"))
|
||||
values, err := env.Get("PDNS_API_KEY", "PDNS_API_URL")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("PDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(hostURL, key)
|
||||
hostURL, err := url.Parse(values["PDNS_API_URL"])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("PDNS: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(hostURL, values["PDNS_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -26,42 +26,46 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func restorePdnsEnv() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("PDNS_API_URL", pdnsURLStr)
|
||||
os.Setenv("PDNS_API_KEY", pdnsAPIKey)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderValid(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
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) {
|
||||
defer restoreEnv()
|
||||
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) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("PDNS_API_URL", "")
|
||||
os.Setenv("PDNS_API_KEY", "123")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "PDNS API URL missing")
|
||||
restorePdnsEnv()
|
||||
assert.EqualError(t, err, "PDNS: some credentials information are missing: PDNS_API_URL")
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingKeyErr(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("PDNS_API_URL", pdnsURLStr)
|
||||
os.Setenv("PDNS_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "PDNS API key missing")
|
||||
restorePdnsEnv()
|
||||
assert.EqualError(t, err, "PDNS: some credentials information are missing: PDNS_API_KEY,PDNS_API_URL")
|
||||
}
|
||||
|
||||
func TestPdnsPresentAndCleanup(t *testing.T) {
|
||||
|
|
|
@ -8,10 +8,10 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// rackspaceAPIURL represents the Identity API endpoint to call
|
||||
|
@ -28,9 +28,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("RACKSPACE_USER", "RACKSPACE_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Rackspace: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["RACKSPACE_USER"], values["RACKSPACE_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||
|
|
|
@ -38,6 +38,7 @@ func NewDNSProvider() (*DNSProvider, error) {
|
|||
tsigKey := os.Getenv("RFC2136_TSIG_KEY")
|
||||
tsigSecret := os.Getenv("RFC2136_TSIG_SECRET")
|
||||
timeout := os.Getenv("RFC2136_TIMEOUT")
|
||||
|
||||
return NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret, timeout)
|
||||
}
|
||||
|
||||
|
@ -58,13 +59,14 @@ func NewDNSProviderCredentials(nameserver, tsigAlgorithm, tsigKey, tsigSecret, t
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
d := &DNSProvider{
|
||||
nameserver: nameserver,
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
||||
|
@ -32,22 +34,20 @@ func TestRFC2136CanaryLocalTestServer(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to start test server")
|
||||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to communicate with test server")
|
||||
assert.Len(t, r.Extra, 1, "Failed to communicate with test server")
|
||||
|
||||
txt := r.Extra[0].(*dns.TXT).Txt[0]
|
||||
if txt != "Hello world" {
|
||||
t.Error("Expected test server to return 'Hello world' but got: ", txt)
|
||||
}
|
||||
assert.Equal(t, "Hello world", txt)
|
||||
}
|
||||
|
||||
func TestRFC2136ServerSuccess(t *testing.T) {
|
||||
|
@ -56,18 +56,14 @@ func TestRFC2136ServerSuccess(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to start test server")
|
||||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRFC2136ServerError(t *testing.T) {
|
||||
|
@ -76,19 +72,16 @@ func TestRFC2136ServerError(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to start test server")
|
||||
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.")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth)
|
||||
require.Error(t, err)
|
||||
if !strings.Contains(err.Error(), "NOTZONE") {
|
||||
t.Errorf("Expected Present() to return an error with the 'NOTZONE' rcode string but it did not: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,18 +91,14 @@ func TestRFC2136TsigClient(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to start test server")
|
||||
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)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(rfc2136TestDomain, "", rfc2136TestKeyAuth)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRFC2136ValidUpdatePacket(t *testing.T) {
|
||||
|
@ -118,9 +107,7 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
require.NoError(t, err, "Failed to start test server")
|
||||
defer server.Shutdown()
|
||||
|
||||
txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", rfc2136TestFqdn, rfc2136TestTTL, rfc2136TestValue))
|
||||
|
@ -130,26 +117,21 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) {
|
|||
m.RemoveRRset(rrs)
|
||||
m.Insert(rrs)
|
||||
expectstr := m.String()
|
||||
|
||||
expect, err := m.Pack()
|
||||
if err != nil {
|
||||
t.Fatalf("Error packing expect msg: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "error packing")
|
||||
|
||||
provider, err := NewDNSProviderCredentials(addrstr, "", "", "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected NewDNSProviderCredentials() to return no error but the error was -> %v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil {
|
||||
t.Errorf("Expected Present() to return no error but the error was -> %v", err)
|
||||
}
|
||||
err = provider.Present(rfc2136TestDomain, "", "1234d==")
|
||||
require.NoError(t, err)
|
||||
|
||||
rcvMsg := <-reqChan
|
||||
rcvMsg.Id = m.Id
|
||||
|
||||
actual, err := rcvMsg.Pack()
|
||||
if err != nil {
|
||||
t.Fatalf("Error packing actual msg: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "error packing")
|
||||
|
||||
if !bytes.Equal(actual, expect) {
|
||||
tmp := new(dns.Msg)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRoute53TTL(t *testing.T) {
|
||||
|
@ -17,14 +18,10 @@ func TestRoute53TTL(t *testing.T) {
|
|||
}
|
||||
|
||||
provider, err := NewDNSProvider()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(m["route53Domain"], "foo", "bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
// we need a separate R53 client here as the one in the DNS provider is
|
||||
// unexported.
|
||||
|
|
|
@ -26,7 +26,7 @@ func init() {
|
|||
route53Zone = os.Getenv("AWS_HOSTED_ZONE_ID")
|
||||
}
|
||||
|
||||
func restoreRoute53Env() {
|
||||
func restoreEnv() {
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", route53Key)
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", route53Secret)
|
||||
os.Setenv("AWS_REGION", route53Region)
|
||||
|
@ -46,6 +46,7 @@ func makeRoute53Provider(ts *httptest.Server) *DNSProvider {
|
|||
}
|
||||
|
||||
func TestCredentialsFromEnv(t *testing.T) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AWS_ACCESS_KEY_ID", "123")
|
||||
os.Setenv("AWS_SECRET_ACCESS_KEY", "123")
|
||||
os.Setenv("AWS_REGION", "us-east-1")
|
||||
|
@ -57,23 +58,20 @@ func TestCredentialsFromEnv(t *testing.T) {
|
|||
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) {
|
||||
defer restoreEnv()
|
||||
os.Setenv("AWS_REGION", "us-east-1")
|
||||
|
||||
sess := session.New(aws.NewConfig())
|
||||
assert.Equal(t, "us-east-1", aws.StringValue(sess.Config.Region), "Expected Region to be set from environment")
|
||||
|
||||
restoreRoute53Env()
|
||||
}
|
||||
|
||||
func TestHostedZoneIDFromEnv(t *testing.T) {
|
||||
const testZoneID = "testzoneid"
|
||||
defer restoreEnv()
|
||||
|
||||
defer restoreRoute53Env()
|
||||
const testZoneID = "testzoneid"
|
||||
os.Setenv("AWS_HOSTED_ZONE_ID", testZoneID)
|
||||
|
||||
provider, err := NewDNSProvider()
|
||||
|
|
|
@ -5,11 +5,11 @@ package vultr
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
vultr "github.com/JamesClonk/vultr/lib"
|
||||
"github.com/xenolf/lego/acme"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
|
@ -20,8 +20,12 @@ type DNSProvider struct {
|
|||
// 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)
|
||||
values, err := env.Get("VULTR_API_KEY")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Vultr: %v", err)
|
||||
}
|
||||
|
||||
return NewDNSProviderCredentials(values["VULTR_API_KEY"])
|
||||
}
|
||||
|
||||
// NewDNSProviderCredentials uses the supplied credentials to return a DNSProvider
|
||||
|
|
|
@ -25,17 +25,19 @@ func restoreEnv() {
|
|||
}
|
||||
|
||||
func TestNewDNSProviderValidEnv(t *testing.T) {
|
||||
os.Setenv("VULTR_API_KEY", "123")
|
||||
defer restoreEnv()
|
||||
os.Setenv("VULTR_API_KEY", "123")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||
os.Setenv("VULTR_API_KEY", "")
|
||||
defer restoreEnv()
|
||||
os.Setenv("VULTR_API_KEY", "")
|
||||
|
||||
_, err := NewDNSProvider()
|
||||
assert.EqualError(t, err, "Vultr credentials missing")
|
||||
assert.EqualError(t, err, "Vultr: some credentials information are missing: VULTR_API_KEY")
|
||||
}
|
||||
|
||||
func TestLivePresent(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue