DNS challenge Cloudflare auth zone
This commit is contained in:
parent
0335f6fba9
commit
7c2409b5a7
18 changed files with 312 additions and 248 deletions
3
Gopkg.lock
generated
3
Gopkg.lock
generated
|
@ -1366,6 +1366,7 @@
|
||||||
"providers/dns/dnsimple",
|
"providers/dns/dnsimple",
|
||||||
"providers/dns/dnsmadeeasy",
|
"providers/dns/dnsmadeeasy",
|
||||||
"providers/dns/dnspod",
|
"providers/dns/dnspod",
|
||||||
|
"providers/dns/dreamhost",
|
||||||
"providers/dns/duckdns",
|
"providers/dns/duckdns",
|
||||||
"providers/dns/dyn",
|
"providers/dns/dyn",
|
||||||
"providers/dns/exec",
|
"providers/dns/exec",
|
||||||
|
@ -1397,7 +1398,7 @@
|
||||||
"providers/dns/vegadns",
|
"providers/dns/vegadns",
|
||||||
"providers/dns/vultr"
|
"providers/dns/vultr"
|
||||||
]
|
]
|
||||||
revision = "01c63ec08d1d85e3ad44c16dff95dadee26a81bc"
|
revision = "160d6fe60303699067faad57dc0b1e147ac499ef"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
|
@ -263,6 +263,7 @@ Here is a list of supported `provider`s, that can automate the DNS verification,
|
||||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | Not tested yet |
|
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | Not tested yet |
|
||||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
|
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
|
||||||
| [DNSPod](http://www.dnspod.net/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
|
| [DNSPod](http://www.dnspod.net/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
|
||||||
|
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
|
||||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | Not tested yet |
|
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | Not tested yet |
|
||||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
|
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
|
||||||
| External Program | `exec` | `EXEC_PATH` | Not tested yet |
|
| External Program | `exec` | `EXEC_PATH` | Not tested yet |
|
||||||
|
|
2
vendor/github.com/xenolf/lego/acme/challenges.go
generated
vendored
2
vendor/github.com/xenolf/lego/acme/challenges.go
generated
vendored
|
@ -7,9 +7,11 @@ const (
|
||||||
// HTTP01 is the "http-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http
|
// HTTP01 is the "http-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http
|
||||||
// Note: HTTP01ChallengePath returns the URL path to fulfill this challenge
|
// Note: HTTP01ChallengePath returns the URL path to fulfill this challenge
|
||||||
HTTP01 = Challenge("http-01")
|
HTTP01 = Challenge("http-01")
|
||||||
|
|
||||||
// DNS01 is the "dns-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#dns
|
// DNS01 is the "dns-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#dns
|
||||||
// Note: DNS01Record returns a DNS record which will fulfill this challenge
|
// Note: DNS01Record returns a DNS record which will fulfill this challenge
|
||||||
DNS01 = Challenge("dns-01")
|
DNS01 = Challenge("dns-01")
|
||||||
|
|
||||||
// TLSALPN01 is the "tls-alpn-01" ACME challenge https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01
|
// TLSALPN01 is the "tls-alpn-01" ACME challenge https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01
|
||||||
TLSALPN01 = Challenge("tls-alpn-01")
|
TLSALPN01 = Challenge("tls-alpn-01")
|
||||||
)
|
)
|
||||||
|
|
2
vendor/github.com/xenolf/lego/acme/client.go
generated
vendored
2
vendor/github.com/xenolf/lego/acme/client.go
generated
vendored
|
@ -412,7 +412,7 @@ DNSNames:
|
||||||
// the whole certificate will fail.
|
// the whole certificate will fail.
|
||||||
func (c *Client) ObtainCertificate(domains []string, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (*CertificateResource, error) {
|
func (c *Client) ObtainCertificate(domains []string, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (*CertificateResource, error) {
|
||||||
if len(domains) == 0 {
|
if len(domains) == 0 {
|
||||||
return nil, errors.New("No domains to obtain a certificate for")
|
return nil, errors.New("no domains to obtain a certificate for")
|
||||||
}
|
}
|
||||||
|
|
||||||
if bundle {
|
if bundle {
|
||||||
|
|
4
vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go
generated
vendored
4
vendor/github.com/xenolf/lego/providers/dns/cloudflare/cloudflare.go
generated
vendored
|
@ -114,7 +114,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
return fmt.Errorf("cloudflare: %v", err)
|
return fmt.Errorf("cloudflare: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zoneID, err := d.client.ZoneIDByName(authZone)
|
zoneID, err := d.client.ZoneIDByName(acme.UnFqdn(authZone))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err)
|
return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
return fmt.Errorf("cloudflare: %v", err)
|
return fmt.Errorf("cloudflare: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zoneID, err := d.client.ZoneIDByName(authZone)
|
zoneID, err := d.client.ZoneIDByName(acme.UnFqdn(authZone))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err)
|
return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err)
|
||||||
}
|
}
|
||||||
|
|
3
vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
generated
vendored
3
vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
generated
vendored
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/xenolf/lego/providers/dns/dnsimple"
|
"github.com/xenolf/lego/providers/dns/dnsimple"
|
||||||
"github.com/xenolf/lego/providers/dns/dnsmadeeasy"
|
"github.com/xenolf/lego/providers/dns/dnsmadeeasy"
|
||||||
"github.com/xenolf/lego/providers/dns/dnspod"
|
"github.com/xenolf/lego/providers/dns/dnspod"
|
||||||
|
"github.com/xenolf/lego/providers/dns/dreamhost"
|
||||||
"github.com/xenolf/lego/providers/dns/duckdns"
|
"github.com/xenolf/lego/providers/dns/duckdns"
|
||||||
"github.com/xenolf/lego/providers/dns/dyn"
|
"github.com/xenolf/lego/providers/dns/dyn"
|
||||||
"github.com/xenolf/lego/providers/dns/exec"
|
"github.com/xenolf/lego/providers/dns/exec"
|
||||||
|
@ -72,6 +73,8 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
|
||||||
return dnsmadeeasy.NewDNSProvider()
|
return dnsmadeeasy.NewDNSProvider()
|
||||||
case "dnspod":
|
case "dnspod":
|
||||||
return dnspod.NewDNSProvider()
|
return dnspod.NewDNSProvider()
|
||||||
|
case "dreamhost":
|
||||||
|
return dreamhost.NewDNSProvider()
|
||||||
case "duckdns":
|
case "duckdns":
|
||||||
return duckdns.NewDNSProvider()
|
return duckdns.NewDNSProvider()
|
||||||
case "dyn":
|
case "dyn":
|
||||||
|
|
4
vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/client.go
generated
vendored
4
vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/client.go
generated
vendored
|
@ -38,11 +38,11 @@ type Client struct {
|
||||||
// NewClient creates a DNSMadeEasy client
|
// NewClient creates a DNSMadeEasy client
|
||||||
func NewClient(apiKey string, apiSecret string) (*Client, error) {
|
func NewClient(apiKey string, apiSecret string) (*Client, error) {
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
return nil, fmt.Errorf("DNSMadeEasy: credentials missing: API key")
|
return nil, fmt.Errorf("credentials missing: API key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if apiSecret == "" {
|
if apiSecret == "" {
|
||||||
return nil, fmt.Errorf("DNSMadeEasy: credentials missing: API secret")
|
return nil, fmt.Errorf("credentials missing: API secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
|
|
24
vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go
generated
vendored
24
vendor/github.com/xenolf/lego/providers/dns/dnsmadeeasy/dnsmadeeasy.go
generated
vendored
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -18,6 +17,7 @@ type Config struct {
|
||||||
BaseURL string
|
BaseURL string
|
||||||
APIKey string
|
APIKey string
|
||||||
APISecret string
|
APISecret string
|
||||||
|
Sandbox bool
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
PropagationTimeout time.Duration
|
PropagationTimeout time.Duration
|
||||||
PollingInterval time.Duration
|
PollingInterval time.Duration
|
||||||
|
@ -55,15 +55,8 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
return nil, fmt.Errorf("dnsmadeeasy: %v", err)
|
return nil, fmt.Errorf("dnsmadeeasy: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseURL string
|
|
||||||
if sandbox, _ := strconv.ParseBool(env.GetOrFile("DNSMADEEASY_SANDBOX")); sandbox {
|
|
||||||
baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
|
|
||||||
} else {
|
|
||||||
baseURL = "https://api.dnsmadeeasy.com/V2.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
config := NewDefaultConfig()
|
config := NewDefaultConfig()
|
||||||
config.BaseURL = baseURL
|
config.Sandbox = env.GetOrDefaultBool("DNSMADEEASY_SANDBOX", false)
|
||||||
config.APIKey = values["DNSMADEEASY_API_KEY"]
|
config.APIKey = values["DNSMADEEASY_API_KEY"]
|
||||||
config.APISecret = values["DNSMADEEASY_API_SECRET"]
|
config.APISecret = values["DNSMADEEASY_API_SECRET"]
|
||||||
|
|
||||||
|
@ -88,8 +81,15 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, errors.New("dnsmadeeasy: the configuration of the DNS provider is nil")
|
return nil, errors.New("dnsmadeeasy: the configuration of the DNS provider is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.BaseURL == "" {
|
var baseURL string
|
||||||
return nil, fmt.Errorf("dnsmadeeasy: base URL missing")
|
if config.Sandbox {
|
||||||
|
baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0"
|
||||||
|
} else {
|
||||||
|
if len(config.BaseURL) > 0 {
|
||||||
|
baseURL = config.BaseURL
|
||||||
|
} else {
|
||||||
|
baseURL = "https://api.dnsmadeeasy.com/V2.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := NewClient(config.APIKey, config.APISecret)
|
client, err := NewClient(config.APIKey, config.APISecret)
|
||||||
|
@ -98,7 +98,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
client.HTTPClient = config.HTTPClient
|
client.HTTPClient = config.HTTPClient
|
||||||
client.BaseURL = config.BaseURL
|
client.BaseURL = baseURL
|
||||||
|
|
||||||
return &DNSProvider{
|
return &DNSProvider{
|
||||||
client: client,
|
client: client,
|
||||||
|
|
73
vendor/github.com/xenolf/lego/providers/dns/dreamhost/client.go
generated
vendored
Normal file
73
vendor/github.com/xenolf/lego/providers/dns/dreamhost/client.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package dreamhost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/xenolf/lego/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultBaseURL = "https://api.dreamhost.com"
|
||||||
|
|
||||||
|
cmdAddRecord = "dns-add_record"
|
||||||
|
cmdRemoveRecord = "dns-remove_record"
|
||||||
|
)
|
||||||
|
|
||||||
|
type apiResponse struct {
|
||||||
|
Data string `json:"data"`
|
||||||
|
Result string `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) buildQuery(action, domain, txt string) (*url.URL, error) {
|
||||||
|
u, err := url.Parse(d.config.BaseURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := u.Query()
|
||||||
|
query.Set("key", d.config.APIKey)
|
||||||
|
query.Set("cmd", action)
|
||||||
|
query.Set("format", "json")
|
||||||
|
query.Set("record", domain)
|
||||||
|
query.Set("type", "TXT")
|
||||||
|
query.Set("value", txt)
|
||||||
|
query.Set("comment", url.QueryEscape("Managed By lego"))
|
||||||
|
u.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateTxtRecord will either add or remove a TXT record.
|
||||||
|
// action is either cmdAddRecord or cmdRemoveRecord
|
||||||
|
func (d *DNSProvider) updateTxtRecord(u fmt.Stringer) error {
|
||||||
|
resp, err := d.config.HTTPClient.Get(u.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("request failed with HTTP status code %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var response apiResponse
|
||||||
|
err = json.Unmarshal(raw, &response)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to decode API server response: %v: %s", err, string(raw))
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.Result == "error" {
|
||||||
|
return fmt.Errorf("add TXT record failed: %s", response.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("dreamhost: %s", response.Data)
|
||||||
|
return nil
|
||||||
|
}
|
111
vendor/github.com/xenolf/lego/providers/dns/dreamhost/dreamhost.go
generated
vendored
Normal file
111
vendor/github.com/xenolf/lego/providers/dns/dreamhost/dreamhost.go
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// Package dreamhost Adds lego support for http://dreamhost.com DNS updates
|
||||||
|
// See https://help.dreamhost.com/hc/en-us/articles/217560167-API_overview
|
||||||
|
// and https://help.dreamhost.com/hc/en-us/articles/217555707-DNS-API-commands for the API spec.
|
||||||
|
package dreamhost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xenolf/lego/acme"
|
||||||
|
"github.com/xenolf/lego/platform/config/env"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is used to configure the creation of the DNSProvider
|
||||||
|
type Config struct {
|
||||||
|
BaseURL string
|
||||||
|
APIKey string
|
||||||
|
PropagationTimeout time.Duration
|
||||||
|
PollingInterval time.Duration
|
||||||
|
HTTPClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultConfig returns a default configuration for the DNSProvider
|
||||||
|
func NewDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
BaseURL: defaultBaseURL,
|
||||||
|
PropagationTimeout: env.GetOrDefaultSecond("DREAMHOST_PROPAGATION_TIMEOUT", 60*time.Minute),
|
||||||
|
PollingInterval: env.GetOrDefaultSecond("DREAMHOST_POLLING_INTERVAL", 1*time.Minute),
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Timeout: env.GetOrDefaultSecond("DREAMHOST_HTTP_TIMEOUT", 30*time.Second),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider adds and removes the record for the DNS challenge
|
||||||
|
type DNSProvider struct {
|
||||||
|
config *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a new DNS provider using
|
||||||
|
// environment variable DREAMHOST_TOKEN for adding and removing the DNS record.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get("DREAMHOST_API_KEY")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("dreamhost: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.APIKey = values["DREAMHOST_API_KEY"]
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderConfig return a DNSProvider instance configured for DreamHost.
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("dreamhost: the configuration of the DNS provider is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.APIKey == "" {
|
||||||
|
return nil, errors.New("dreamhost: credentials missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.BaseURL == "" {
|
||||||
|
config.BaseURL = defaultBaseURL
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{config: config}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record to fulfill the dns-01 challenge.
|
||||||
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
record := acme.UnFqdn(fqdn)
|
||||||
|
|
||||||
|
u, err := d.buildQuery(cmdAddRecord, record, value)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dreamhost: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.updateTxtRecord(u)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dreamhost: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp clears DreamHost TXT record
|
||||||
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
record := acme.UnFqdn(fqdn)
|
||||||
|
|
||||||
|
u, err := d.buildQuery(cmdRemoveRecord, record, value)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dreamhost: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.updateTxtRecord(u)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dreamhost: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
// Adjusting here to cope with spikes in propagation times.
|
||||||
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
|
}
|
2
vendor/github.com/xenolf/lego/providers/dns/fastdns/fastdns.go
generated
vendored
2
vendor/github.com/xenolf/lego/providers/dns/fastdns/fastdns.go
generated
vendored
|
@ -77,7 +77,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ClientToken == "" || config.ClientSecret == "" || config.AccessToken == "" || config.Host == "" {
|
if config.ClientToken == "" || config.ClientSecret == "" || config.AccessToken == "" || config.Host == "" {
|
||||||
return nil, fmt.Errorf("FastDNS credentials are missing")
|
return nil, fmt.Errorf("fastdns: credentials are missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DNSProvider{config: config}, nil
|
return &DNSProvider{config: config}, nil
|
||||||
|
|
8
vendor/github.com/xenolf/lego/providers/dns/gandiv5/gandiv5.go
generated
vendored
8
vendor/github.com/xenolf/lego/providers/dns/gandiv5/gandiv5.go
generated
vendored
|
@ -102,6 +102,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
config.BaseURL = defaultBaseURL
|
config.BaseURL = defaultBaseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.TTL < minTTL {
|
||||||
|
return nil, fmt.Errorf("gandiv5: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL)
|
||||||
|
}
|
||||||
|
|
||||||
return &DNSProvider{
|
return &DNSProvider{
|
||||||
config: config,
|
config: config,
|
||||||
inProgressFQDNs: make(map[string]inProgressInfo),
|
inProgressFQDNs: make(map[string]inProgressInfo),
|
||||||
|
@ -112,10 +116,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
|
||||||
if d.config.TTL < minTTL {
|
|
||||||
d.config.TTL = minTTL // 300 is gandi minimum value for ttl
|
|
||||||
}
|
|
||||||
|
|
||||||
// find authZone
|
// find authZone
|
||||||
authZone, err := findZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
authZone, err := findZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
7
vendor/github.com/xenolf/lego/providers/dns/glesys/glesys.go
generated
vendored
7
vendor/github.com/xenolf/lego/providers/dns/glesys/glesys.go
generated
vendored
|
@ -93,6 +93,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, fmt.Errorf("glesys: incomplete credentials provided")
|
return nil, fmt.Errorf("glesys: incomplete credentials provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.TTL < minTTL {
|
||||||
|
return nil, fmt.Errorf("glesys: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL)
|
||||||
|
}
|
||||||
|
|
||||||
return &DNSProvider{
|
return &DNSProvider{
|
||||||
config: config,
|
config: config,
|
||||||
activeRecords: make(map[string]int),
|
activeRecords: make(map[string]int),
|
||||||
|
@ -103,9 +107,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
|
||||||
if d.config.TTL < minTTL {
|
|
||||||
d.config.TTL = minTTL // 60 is GleSYS minimum value for ttl
|
|
||||||
}
|
|
||||||
// find authZone
|
// find authZone
|
||||||
authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
8
vendor/github.com/xenolf/lego/providers/dns/nifcloud/client.go
generated
vendored
8
vendor/github.com/xenolf/lego/providers/dns/nifcloud/client.go
generated
vendored
|
@ -89,13 +89,17 @@ type ChangeInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient Creates a new client of NIFCLOUD DNS
|
// NewClient Creates a new client of NIFCLOUD DNS
|
||||||
func NewClient(accessKey string, secretKey string) *Client {
|
func NewClient(accessKey string, secretKey string) (*Client, error) {
|
||||||
|
if len(accessKey) == 0 || len(secretKey) == 0 {
|
||||||
|
return nil, errors.New("credentials missing")
|
||||||
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
accessKey: accessKey,
|
accessKey: accessKey,
|
||||||
secretKey: secretKey,
|
secretKey: secretKey,
|
||||||
BaseURL: defaultBaseURL,
|
BaseURL: defaultBaseURL,
|
||||||
HTTPClient: &http.Client{},
|
HTTPClient: &http.Client{},
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client client of NIFCLOUD DNS
|
// Client client of NIFCLOUD DNS
|
||||||
|
|
5
vendor/github.com/xenolf/lego/providers/dns/nifcloud/nifcloud.go
generated
vendored
5
vendor/github.com/xenolf/lego/providers/dns/nifcloud/nifcloud.go
generated
vendored
|
@ -77,7 +77,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, errors.New("nifcloud: the configuration of the DNS provider is nil")
|
return nil, errors.New("nifcloud: the configuration of the DNS provider is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewClient(config.AccessKey, config.SecretKey)
|
client, err := NewClient(config.AccessKey, config.SecretKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("nifcloud: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if config.HTTPClient != nil {
|
if config.HTTPClient != nil {
|
||||||
client.HTTPClient = config.HTTPClient
|
client.HTTPClient = config.HTTPClient
|
||||||
|
|
162
vendor/github.com/xenolf/lego/providers/dns/otc/mock.go
generated
vendored
162
vendor/github.com/xenolf/lego/providers/dns/otc/mock.go
generated
vendored
|
@ -1,162 +0,0 @@
|
||||||
package otc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var fakeOTCUserName = "test"
|
|
||||||
var fakeOTCPassword = "test"
|
|
||||||
var fakeOTCDomainName = "test"
|
|
||||||
var fakeOTCProjectName = "test"
|
|
||||||
var fakeOTCToken = "62244bc21da68d03ebac94e6636ff01f"
|
|
||||||
|
|
||||||
// DNSMock mock
|
|
||||||
type DNSMock struct {
|
|
||||||
t *testing.T
|
|
||||||
Server *httptest.Server
|
|
||||||
Mux *http.ServeMux
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDNSMock create a new DNSMock
|
|
||||||
func NewDNSMock(t *testing.T) *DNSMock {
|
|
||||||
return &DNSMock{
|
|
||||||
t: t,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup creates the mock server
|
|
||||||
func (m *DNSMock) Setup() {
|
|
||||||
m.Mux = http.NewServeMux()
|
|
||||||
m.Server = httptest.NewServer(m.Mux)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShutdownServer creates the mock server
|
|
||||||
func (m *DNSMock) ShutdownServer() {
|
|
||||||
m.Server.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleAuthSuccessfully Handle auth successfully
|
|
||||||
func (m *DNSMock) HandleAuthSuccessfully() {
|
|
||||||
m.Mux.HandleFunc("/v3/auth/token", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("X-Subject-Token", fakeOTCToken)
|
|
||||||
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"token": {
|
|
||||||
"catalog": [
|
|
||||||
{
|
|
||||||
"type": "dns",
|
|
||||||
"id": "56cd81db1f8445d98652479afe07c5ba",
|
|
||||||
"name": "",
|
|
||||||
"endpoints": [
|
|
||||||
{
|
|
||||||
"url": "%s",
|
|
||||||
"region": "eu-de",
|
|
||||||
"region_id": "eu-de",
|
|
||||||
"interface": "public",
|
|
||||||
"id": "0047a06690484d86afe04877074efddf"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}}`, m.Server.URL)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleListZonesSuccessfully Handle list zones successfully
|
|
||||||
func (m *DNSMock) HandleListZonesSuccessfully() {
|
|
||||||
m.Mux.HandleFunc("/v2/zones", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"zones":[{
|
|
||||||
"id":"123123"
|
|
||||||
}]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.Method, http.MethodGet)
|
|
||||||
assert.Equal(m.t, r.URL.Path, "/v2/zones")
|
|
||||||
assert.Equal(m.t, r.URL.RawQuery, "name=example.com.")
|
|
||||||
assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleListZonesEmpty Handle list zones empty
|
|
||||||
func (m *DNSMock) HandleListZonesEmpty() {
|
|
||||||
m.Mux.HandleFunc("/v2/zones", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"zones":[
|
|
||||||
]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.Method, http.MethodGet)
|
|
||||||
assert.Equal(m.t, r.URL.Path, "/v2/zones")
|
|
||||||
assert.Equal(m.t, r.URL.RawQuery, "name=example.com.")
|
|
||||||
assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleDeleteRecordsetsSuccessfully Handle delete recordsets successfully
|
|
||||||
func (m *DNSMock) HandleDeleteRecordsetsSuccessfully() {
|
|
||||||
m.Mux.HandleFunc("/v2/zones/123123/recordsets/321321", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"zones":[{
|
|
||||||
"id":"123123"
|
|
||||||
}]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.Method, http.MethodDelete)
|
|
||||||
assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets/321321")
|
|
||||||
assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleListRecordsetsEmpty Handle list recordsets empty
|
|
||||||
func (m *DNSMock) HandleListRecordsetsEmpty() {
|
|
||||||
m.Mux.HandleFunc("/v2/zones/123123/recordsets", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"recordsets":[
|
|
||||||
]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets")
|
|
||||||
assert.Equal(m.t, r.URL.RawQuery, "type=TXT&name=_acme-challenge.example.com.")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleListRecordsetsSuccessfully Handle list recordsets successfully
|
|
||||||
func (m *DNSMock) HandleListRecordsetsSuccessfully() {
|
|
||||||
m.Mux.HandleFunc("/v2/zones/123123/recordsets", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method == http.MethodGet {
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"recordsets":[{
|
|
||||||
"id":"321321"
|
|
||||||
}]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.URL.Path, "/v2/zones/123123/recordsets")
|
|
||||||
assert.Equal(m.t, r.URL.RawQuery, "type=TXT&name=_acme-challenge.example.com.")
|
|
||||||
|
|
||||||
} else if r.Method == http.MethodPost {
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
|
||||||
|
|
||||||
assert.Nil(m.t, err)
|
|
||||||
exceptedString := "{\"name\":\"_acme-challenge.example.com.\",\"description\":\"Added TXT record for ACME dns-01 challenge using lego client\",\"type\":\"TXT\",\"ttl\":300,\"records\":[\"\\\"w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI\\\"\"]}"
|
|
||||||
assert.Equal(m.t, string(body), exceptedString)
|
|
||||||
|
|
||||||
fmt.Fprintf(w, `{
|
|
||||||
"recordsets":[{
|
|
||||||
"id":"321321"
|
|
||||||
}]}
|
|
||||||
`)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
m.t.Errorf("Expected method to be 'GET' or 'POST' but got '%s'", r.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(m.t, r.Header.Get("Content-Type"), "application/json")
|
|
||||||
})
|
|
||||||
}
|
|
42
vendor/github.com/xenolf/lego/providers/dns/rackspace/client.go
generated
vendored
42
vendor/github.com/xenolf/lego/providers/dns/rackspace/client.go
generated
vendored
|
@ -18,18 +18,42 @@ type AuthData struct {
|
||||||
|
|
||||||
// Identity Identity
|
// Identity Identity
|
||||||
type Identity struct {
|
type Identity struct {
|
||||||
Access struct {
|
Access Access `json:"access"`
|
||||||
ServiceCatalog []struct {
|
}
|
||||||
Endpoints []struct {
|
|
||||||
|
// Access Access
|
||||||
|
type Access struct {
|
||||||
|
ServiceCatalog []ServiceCatalog `json:"serviceCatalog"`
|
||||||
|
Token Token `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token Token
|
||||||
|
type Token struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceCatalog ServiceCatalog
|
||||||
|
type ServiceCatalog struct {
|
||||||
|
Endpoints []Endpoint `json:"endpoints"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoint Endpoint
|
||||||
|
type Endpoint struct {
|
||||||
PublicURL string `json:"publicURL"`
|
PublicURL string `json:"publicURL"`
|
||||||
TenantID string `json:"tenantId"`
|
TenantID string `json:"tenantId"`
|
||||||
} `json:"endpoints"`
|
}
|
||||||
|
|
||||||
|
// ZoneSearchResponse represents the response when querying Rackspace DNS zones
|
||||||
|
type ZoneSearchResponse struct {
|
||||||
|
TotalEntries int `json:"totalEntries"`
|
||||||
|
HostedZones []HostedZone `json:"domains"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HostedZone HostedZone
|
||||||
|
type HostedZone struct {
|
||||||
|
ID int `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
} `json:"serviceCatalog"`
|
|
||||||
Token struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
} `json:"token"`
|
|
||||||
} `json:"access"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Records is the list of records sent/received from the DNS API
|
// Records is the list of records sent/received from the DNS API
|
||||||
|
|
91
vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go
generated
vendored
91
vendor/github.com/xenolf/lego/providers/dns/rackspace/rackspace.go
generated
vendored
|
@ -89,39 +89,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, fmt.Errorf("rackspace: credentials missing")
|
return nil, fmt.Errorf("rackspace: credentials missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
authData := AuthData{
|
identity, err := login(config)
|
||||||
Auth: Auth{
|
|
||||||
APIKeyCredentials: APIKeyCredentials{
|
|
||||||
Username: config.APIUser,
|
|
||||||
APIKey: config.APIKey,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := json.Marshal(authData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, config.BaseURL, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
// client := &http.Client{Timeout: 30 * time.Second}
|
|
||||||
resp, err := config.HTTPClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("rackspace: error querying Identity API: %v", err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("rackspace: authentication failed: response code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
var identity Identity
|
|
||||||
err = json.NewDecoder(resp.Body).Decode(&identity)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("rackspace: %v", err)
|
return nil, fmt.Errorf("rackspace: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -134,6 +102,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dnsEndpoint == "" {
|
if dnsEndpoint == "" {
|
||||||
return nil, fmt.Errorf("rackspace: failed to populate DNS endpoint, check Rackspace API for changes")
|
return nil, fmt.Errorf("rackspace: failed to populate DNS endpoint, check Rackspace API for changes")
|
||||||
}
|
}
|
||||||
|
@ -149,6 +118,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
// Present creates a TXT record to fulfill the dns-01 challenge
|
// Present creates a TXT record to fulfill the dns-01 challenge
|
||||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
fqdn, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
|
||||||
zoneID, err := d.getHostedZoneID(fqdn)
|
zoneID, err := d.getHostedZoneID(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rackspace: %v", err)
|
return fmt.Errorf("rackspace: %v", err)
|
||||||
|
@ -178,6 +148,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
// CleanUp removes the TXT record matching the specified parameters
|
// CleanUp removes the TXT record matching the specified parameters
|
||||||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
|
fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
|
||||||
zoneID, err := d.getHostedZoneID(fqdn)
|
zoneID, err := d.getHostedZoneID(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rackspace: %v", err)
|
return fmt.Errorf("rackspace: %v", err)
|
||||||
|
@ -204,15 +175,6 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
// getHostedZoneID performs a lookup to get the DNS zone which needs
|
// getHostedZoneID performs a lookup to get the DNS zone which needs
|
||||||
// modifying for a given FQDN
|
// modifying for a given FQDN
|
||||||
func (d *DNSProvider) getHostedZoneID(fqdn string) (int, error) {
|
func (d *DNSProvider) getHostedZoneID(fqdn string) (int, error) {
|
||||||
// HostedZones represents the response when querying Rackspace DNS zones
|
|
||||||
type ZoneSearchResponse struct {
|
|
||||||
TotalEntries int `json:"totalEntries"`
|
|
||||||
HostedZones []struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"domains"`
|
|
||||||
}
|
|
||||||
|
|
||||||
authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -250,8 +212,7 @@ func (d *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*Record, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
recordsLength := len(records.Record)
|
switch len(records.Record) {
|
||||||
switch recordsLength {
|
|
||||||
case 1:
|
case 1:
|
||||||
case 0:
|
case 0:
|
||||||
return nil, fmt.Errorf("no TXT record found for %s", fqdn)
|
return nil, fmt.Errorf("no TXT record found for %s", fqdn)
|
||||||
|
@ -265,6 +226,7 @@ func (d *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*Record, error) {
|
||||||
// makeRequest is a wrapper function used for making DNS API requests
|
// makeRequest is a wrapper function used for making DNS API requests
|
||||||
func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) {
|
func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) {
|
||||||
url := d.cloudDNSEndpoint + uri
|
url := d.cloudDNSEndpoint + uri
|
||||||
|
|
||||||
req, err := http.NewRequest(method, url, body)
|
req, err := http.NewRequest(method, url, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -292,3 +254,44 @@ func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func login(config *Config) (*Identity, error) {
|
||||||
|
authData := AuthData{
|
||||||
|
Auth: Auth{
|
||||||
|
APIKeyCredentials: APIKeyCredentials{
|
||||||
|
Username: config.APIUser,
|
||||||
|
APIKey: config.APIKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(authData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, config.BaseURL, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := config.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error querying Identity API: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("authentication failed: response code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var identity Identity
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&identity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &identity, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue