Documentation
¶
Overview ¶
Package ednsde implements a libdns provider for the eDNS DNS-01 challenge API offered by edns.de at https://dns-challenge.edns.de.
The API is purpose-built for ACME DNS-01 challenges: it can add and remove TXT challenge records and does nothing else. In particular it has no endpoint that lists the records of a zone, so libdns.RecordGetter cannot be implemented honestly and libdns.RecordSetter cannot be implemented at all. Those methods are therefore deliberately absent rather than present-and- failing, so that misuse is caught by the compiler instead of during a certificate request. Only libdns.RecordAppender and libdns.RecordDeleter are provided, which is exactly what certmagic and Caddy require.
The access token must be assigned to the zone on that zone's "DNS-01-Challenge" tab in the eDNS web interface, otherwise every request for it is answered with 401.
Index ¶
Constants ¶
const DefaultEndpoint = "https://dns-challenge.edns.de"
DefaultEndpoint is the production eDNS challenge API.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status of the response. The eDNS API also repeats
// it in the body, where the two always agree.
StatusCode int
// Message is the API's own description of the failure, passed through
// unchanged.
Message string
// Hint carries advice the API itself does not give, most importantly for
// 401, where an invalid token and a token that is merely not assigned to
// the zone are indistinguishable.
Hint string
}
APIError is returned for any non-200 answer from the eDNS API. Callers can use errors.As to reach it, for example to distinguish an authorization problem (401) from a malformed request (400).
type Provider ¶
type Provider struct {
// APIToken is the eDNS access token, sent as the X-API-TOKEN header. It
// must be assigned to every zone this Provider is used for.
APIToken string `json:"api_token,omitempty"`
// Endpoint overrides the API base URL. It exists so tests can point the
// Provider at a stub server; leave it empty to use [DefaultEndpoint].
//
// It is deliberately excluded from JSON, and the Caddy module does not
// parse it either: a redirectable API URL in the certificate path is
// configuration surface that buys nobody anything.
Endpoint string `json:"-"`
// HTTPClient overrides the HTTP client used for API calls.
HTTPClient *http.Client `json:"-"`
}
Provider manages ACME challenge records through the eDNS challenge API.
A Provider is safe for concurrent use. Its fields are read-only once constructed and must not be modified afterwards.
func (*Provider) AppendRecords ¶
func (p *Provider) AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
AppendRecords creates the given challenge records in the zone and returns those that are now present.
Only TXT records are accepted. The TTL of the input is ignored: eDNS fixes challenge records at 300 seconds and offers no way to change that, so the returned records carry that value rather than the requested one.
A record that already exists is reported as created, because the resulting zone state is the one that was asked for.
func (*Provider) DeleteRecords ¶
func (p *Provider) DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
DeleteRecords removes the given challenge records from the zone and returns those that were actually deleted.
Records that no longer exist are silently skipped: they are left out of the returned slice, as libdns requires, but are not treated as an error, so that cleaning up after a failed challenge stays quiet.
Unlike the general libdns contract, the value of a record may not be left empty. Deleting "everything with this name" would require reading the zone first, and the eDNS challenge API cannot list records. eDNS also only removes records that were created through this same API; records added by hand in the web interface are reported as not found.