Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/zz_gen_cmd_dnshelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,7 @@ func displayDNSHelp(w io.Writer, name string) error {
ew.writeln()

ew.writeln(`Additional Configuration:`)
ew.writeln(` - "PDNS_API_VERSION": Skip API version autodetection and use the provided version number.`)
ew.writeln(` - "PDNS_HTTP_TIMEOUT": API request timeout`)
ew.writeln(` - "PDNS_POLLING_INTERVAL": Time between DNS propagation check`)
ew.writeln(` - "PDNS_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
Expand Down
2 changes: 2 additions & 0 deletions docs/content/dns/zz_gen_pdns.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ More information [here]({{< ref "dns#configuration-and-credentials" >}}).

| Environment Variable Name | Description |
|--------------------------------|-------------|
| `PDNS_API_VERSION` | Skip API version autodetection and use the provided version number. |
| `PDNS_HTTP_TIMEOUT` | API request timeout |
| `PDNS_POLLING_INTERVAL` | Time between DNS propagation check |
| `PDNS_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
Expand All @@ -65,6 +66,7 @@ Tested and confirmed to work with PowerDNS authoritative server 3.4.8 and 4.0.1.
PowerDNS Notes:
- PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc.
- In order to have the SOA serial automatically increment each time the `_acme-challenge` record is added/modified via the API, set `SOA-EDIT-API` to `INCEPTION-INCREMENT` for the zone in the `domainmetadata` table
- Some PowerDNS servers doesn't have root API endpoints enabled and API version autodetection will not work. In that case version number can be defined using `PDNS_API_VERSION`.



Expand Down
2 changes: 1 addition & 1 deletion docs/data/zz_cli_help.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ USAGE:

OPTIONS:
--days value The number of days left on a certificate to renew it. (default: 0)
--ari-enable Use the renewalInfo endpoint (draft-ietf-acme-ari-02) to check if a certificate should be renewed. (default: false)
--ari-enable Use the renewalInfo endpoint (draft-ietf-acme-ari) to check if a certificate should be renewed. (default: false)
--ari-wait-to-renew-duration value The maximum duration you're willing to sleep for a renewal time returned by the renewalInfo endpoint. (default: 0s)
--reuse-key Used to indicate you want to reuse your current private key for the new certificate. (default: false)
--no-bundle Do not create a certificate bundle by adding the issuers certificate to the new certificate. (default: false)
Expand Down
3 changes: 2 additions & 1 deletion providers/dns/pdns/internal/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ type Client struct {
}

// NewClient creates a new Client.
func NewClient(host *url.URL, serverName string, apiKey string) *Client {
func NewClient(host *url.URL, serverName string, apiVersion int, apiKey string) *Client {
return &Client{
serverName: serverName,
apiKey: apiKey,
apiVersion: apiVersion,
Host: host,
HTTPClient: &http.Client{Timeout: 5 * time.Second},
}
Expand Down
5 changes: 2 additions & 3 deletions providers/dns/pdns/internal/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func setupTest(t *testing.T, method, pattern string, status int, file string) *C

serverURL, _ := url.Parse(server.URL)

client := NewClient(serverURL, "server", "secret")
client := NewClient(serverURL, "server", 0, "secret")
client.HTTPClient = server.Client()

return client
Expand Down Expand Up @@ -151,8 +151,7 @@ func TestClient_joinPath(t *testing.T) {
host, err := url.Parse(test.baseURL)
require.NoError(t, err)

client := NewClient(host, "test", "secret")
client.apiVersion = test.apiVersion
client := NewClient(host, "test", test.apiVersion, "secret")

endpoint := client.joinPath(test.uri)

Expand Down
15 changes: 10 additions & 5 deletions providers/dns/pdns/pdns.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
EnvAPIURL = envNamespace + "API_URL"

EnvTTL = envNamespace + "TTL"
EnvAPIVersion = envNamespace + "API_VERSION"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
Expand All @@ -34,6 +35,7 @@ type Config struct {
APIKey string
Host *url.URL
ServerName string
APIVersion int
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int
Expand All @@ -43,10 +45,11 @@ type Config struct {
// NewDefaultConfig returns a default configuration for the DNSProvider.
func NewDefaultConfig() *Config {
return &Config{
ServerName: env.GetOrDefaultString(EnvServerName, "localhost"),
APIVersion: env.GetOrDefaultInt(EnvAPIVersion, 0),
TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 120*time.Second),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 2*time.Second),
ServerName: env.GetOrDefaultString(EnvServerName, "localhost"),
HTTPClient: &http.Client{
Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
},
Expand Down Expand Up @@ -94,11 +97,13 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("pdns: API URL missing")
}

client := internal.NewClient(config.Host, config.ServerName, config.APIKey)
client := internal.NewClient(config.Host, config.ServerName, config.APIVersion, config.APIKey)

err := client.SetAPIVersion(context.Background())
if err != nil {
log.Warnf("pdns: failed to get API version %v", err)
if config.APIVersion <= 0 {
err := client.SetAPIVersion(context.Background())
if err != nil {
log.Warnf("pdns: failed to get API version %v", err)
}
}

return &DNSProvider{config: config, client: client}, nil
Expand Down
4 changes: 3 additions & 1 deletion providers/dns/pdns/pdns.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@ Tested and confirmed to work with PowerDNS authoritative server 3.4.8 and 4.0.1.
PowerDNS Notes:
- PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc.
- In order to have the SOA serial automatically increment each time the `_acme-challenge` record is added/modified via the API, set `SOA-EDIT-API` to `INCEPTION-INCREMENT` for the zone in the `domainmetadata` table
- Some PowerDNS servers doesn't have root API endpoints enabled and API version autodetection will not work. In that case version number can be defined using `PDNS_API_VERSION`.
'''

[Configuration]
[Configuration.Credentials]
PDNS_API_KEY = "API key"
PDNS_API_URL = "API URL"
[Configuration.Additional]
PDNS_SERVER_NAME = "Name of the server in the URL, 'localhost' by default"
PDNS_API_VERSION = "Skip API version autodetection and use the provided version number."
PDNS_POLLING_INTERVAL = "Time between DNS propagation check"
PDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
PDNS_TTL = "The TTL of the TXT record used for the DNS challenge"
PDNS_HTTP_TIMEOUT = "API request timeout"
PDNS_SERVER_NAME = "Name of the server in the URL, 'localhost' by default"

[Links]
API = "https://doc.powerdns.com/md/httpapi/README/"
38 changes: 24 additions & 14 deletions providers/dns/pdns/pdns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,31 @@ func TestNewDNSProvider(t *testing.T) {

func TestNewDNSProviderConfig(t *testing.T) {
testCases := []struct {
desc string
apiKey string
host *url.URL
expected string
desc string
apiKey string
customAPIVersion int
host *url.URL
expected string
}{
{
desc: "success",
apiKey: "123",
host: func() *url.URL {
u, _ := url.Parse("http://example.com")
return u
}(),
host: mustParse("http://example.com"),
},
{
desc: "success custom API version",
apiKey: "123",
customAPIVersion: 1,
host: mustParse("http://example.com"),
},
{
desc: "missing credentials",
expected: "pdns: API key missing",
},
{
desc: "missing API key",
apiKey: "",
host: func() *url.URL {
u, _ := url.Parse("http://example.com")
return u
}(),
desc: "missing API key",
apiKey: "",
host: mustParse("http://example.com"),
expected: "pdns: API key missing",
},
{
Expand All @@ -114,6 +115,7 @@ func TestNewDNSProviderConfig(t *testing.T) {
config := NewDefaultConfig()
config.APIKey = test.apiKey
config.Host = test.host
config.APIVersion = test.customAPIVersion

p, err := NewDNSProviderConfig(config)

Expand Down Expand Up @@ -143,3 +145,11 @@ func TestLivePresentAndCleanup(t *testing.T) {
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
require.NoError(t, err)
}

func mustParse(rawURL string) *url.URL {
u, err := url.Parse(rawURL)
if err != nil {
panic(err)
}
return u
}