fix: return an error when extracting record name (#1766)

This commit is contained in:
Ludovic Fernandez 2022-11-28 18:53:13 +01:00 committed by GitHub
parent 300f42d084
commit 9ec5c8a18f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 363 additions and 225 deletions

24
challenge/dns01/domain.go Normal file
View file

@ -0,0 +1,24 @@
package dns01
import (
"fmt"
"strings"
"github.com/miekg/dns"
)
// ExtractSubDomain extracts the subdomain part from a domain and a zone.
func ExtractSubDomain(domain, zone string) (string, error) {
canonDomain := dns.Fqdn(domain)
canonZone := dns.Fqdn(zone)
if canonDomain == canonZone {
return "", fmt.Errorf("no subdomain because the domain and the zone are identical: %s", canonDomain)
}
if !dns.IsSubDomain(canonZone, canonDomain) {
return "", fmt.Errorf("%s is not a subdomain of %s", canonDomain, canonZone)
}
return strings.TrimSuffix(canonDomain, "."+canonZone), nil
}

View file

@ -0,0 +1,104 @@
package dns01
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestExtractSubDomain(t *testing.T) {
testCases := []struct {
desc string
domain string
zone string
expected string
}{
{
desc: "no FQDN",
domain: "_acme-challenge.example.com",
zone: "example.com",
expected: "_acme-challenge",
},
{
desc: "no FQDN zone",
domain: "_acme-challenge.example.com.",
zone: "example.com",
expected: "_acme-challenge",
},
{
desc: "no FQDN domain",
domain: "_acme-challenge.example.com",
zone: "example.com.",
expected: "_acme-challenge",
},
{
desc: "FQDN",
domain: "_acme-challenge.example.com.",
zone: "example.com.",
expected: "_acme-challenge",
},
{
desc: "multi-level subdomain",
domain: "_acme-challenge.one.example.com.",
zone: "example.com.",
expected: "_acme-challenge.one",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
subDomain, err := ExtractSubDomain(test.domain, test.zone)
require.NoError(t, err)
assert.Equal(t, test.expected, subDomain)
})
}
}
func TestExtractSubDomain_errors(t *testing.T) {
testCases := []struct {
desc string
domain string
zone string
}{
{
desc: "same domain",
domain: "example.com",
zone: "example.com",
},
{
desc: "same domain, no FQDN zone",
domain: "example.com.",
zone: "example.com",
},
{
desc: "same domain, no FQDN domain",
domain: "example.com",
zone: "example.com.",
},
{
desc: "same domain, FQDN",
domain: "example.com.",
zone: "example.com.",
},
{
desc: "zone and domain are unrelated",
domain: "_acme-challenge.example.com",
zone: "example.org",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
_, err := ExtractSubDomain(test.domain, test.zone)
require.Error(t, err)
})
}
}

View file

@ -4,7 +4,6 @@ package alidns
import (
"errors"
"fmt"
"strings"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
@ -269,9 +268,10 @@ func extractRecordName(fqdn, zone string) (string, error) {
return "", fmt.Errorf("fail to convert punycode: %w", err)
}
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+asciiDomain); idx != -1 {
return name[:idx], nil
subDomain, err := dns01.ExtractSubDomain(fqdn, asciiDomain)
if err != nil {
return "", err
}
return name, nil
return subDomain, nil
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
@ -114,9 +113,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return err
}
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("arvancloud: %w", err)
}
record := internal.DNSRecord{
Type: "txt",
Name: extractRecordName(fqdn, authZone),
Name: subDomain,
Value: internal.TXTRecordValue{Text: value},
TTL: d.config.TTL,
UpstreamHTTPS: "default",
@ -176,11 +180,3 @@ func getZone(fqdn string) (string, error) {
return dns01.UnFqdn(authZone), nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -4,7 +4,6 @@ package civo
import (
"errors"
"fmt"
"strings"
"time"
"github.com/civo/civogo"
@ -104,8 +103,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("civo: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("civo: %w", err)
}
_, err = d.client.CreateDNSRecord(dnsDomain.ID, &civogo.DNSRecordConfig{
Name: extractRecordName(fqdn, zone),
Name: subDomain,
Value: value,
Type: civogo.DNSRecordTypeTXT,
TTL: d.config.TTL,
@ -136,9 +140,14 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("civo: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("civo: %w", err)
}
var dnsRecord civogo.DNSRecord
for _, entry := range dnsRecords {
if entry.Name == extractRecordName(fqdn, zone) && entry.Value == value {
if entry.Name == subDomain && entry.Value == value {
dnsRecord = entry
break
}
@ -166,11 +175,3 @@ func getZone(fqdn string) (string, error) {
return dns01.UnFqdn(authZone), nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -109,7 +109,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("constellix: failed to get domain (%s): %w", authZone, err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("constellix: %w", err)
}
records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
if err != nil {
@ -147,7 +150,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("constellix: failed to get domain (%s): %w", authZone, err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("constellix: %w", err)
}
records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
if err != nil {
@ -262,7 +268,3 @@ func containsValue(record *internal.Record, value string) bool {
return false
}
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-1]
}

View file

@ -109,7 +109,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("desec: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("desec: %w", err)
}
domainName := dns01.UnFqdn(authZone)
@ -156,7 +159,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("desec: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("desec: %w", err)
}
domainName := dns01.UnFqdn(authZone)
@ -179,7 +185,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-1]
}

View file

@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"github.com/dnsimple/dnsimple-go/dnsimple"
@ -103,7 +102,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("dnsimple: %w", err)
}
recordAttributes := newTxtRecord(zoneName, fqdn, value, d.config.TTL)
recordAttributes, err := newTxtRecord(zoneName, fqdn, value, d.config.TTL)
if err != nil {
return fmt.Errorf("dnsimple: %w", err)
}
_, err = d.client.Zones.CreateRecord(context.Background(), accountID, zoneName, recordAttributes)
if err != nil {
return fmt.Errorf("dnsimple: API call failed: %w", err)
@ -186,9 +189,12 @@ func (d *DNSProvider) findTxtRecords(fqdn string) ([]dnsimple.ZoneRecord, error)
return nil, err
}
recordName := extractRecordName(fqdn, zoneName)
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return nil, err
}
result, err := d.client.Zones.ListRecords(context.Background(), accountID, zoneName, &dnsimple.ZoneRecordListOptions{Name: &recordName, Type: dnsimple.String("TXT"), ListOptions: dnsimple.ListOptions{}})
result, err := d.client.Zones.ListRecords(context.Background(), accountID, zoneName, &dnsimple.ZoneRecordListOptions{Name: &subDomain, Type: dnsimple.String("TXT"), ListOptions: dnsimple.ListOptions{}})
if err != nil {
return nil, fmt.Errorf("API call has failed: %w", err)
}
@ -196,23 +202,18 @@ func (d *DNSProvider) findTxtRecords(fqdn string) ([]dnsimple.ZoneRecord, error)
return result.Data, nil
}
func newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimple.ZoneRecordAttributes {
name := extractRecordName(fqdn, zoneName)
func newTxtRecord(zoneName, fqdn, value string, ttl int) (dnsimple.ZoneRecordAttributes, error) {
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return dnsimple.ZoneRecordAttributes{}, err
}
return dnsimple.ZoneRecordAttributes{
Type: "TXT",
Name: &name,
Name: &subDomain,
Content: value,
TTL: ttl,
}
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}, nil
}
func (d *DNSProvider) getAccountID() (string, error) {

View file

@ -6,7 +6,6 @@ import (
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -94,7 +93,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return err
}
recordAttributes := d.newTxtRecord(zoneName, fqdn, value, d.config.TTL)
recordAttributes, err := d.newTxtRecord(zoneName, fqdn, value, d.config.TTL)
if err != nil {
return err
}
_, _, err = d.client.Records.Create(zoneID, *recordAttributes)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
@ -157,40 +160,38 @@ func (d *DNSProvider) getHostedZone(domain string) (string, string, error) {
return hostedZone.ID.String(), hostedZone.Name, nil
}
func (d *DNSProvider) newTxtRecord(zone, fqdn, value string, ttl int) *dnspod.Record {
name := extractRecordName(fqdn, zone)
func (d *DNSProvider) newTxtRecord(zone, fqdn, value string, ttl int) (*dnspod.Record, error) {
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return nil, err
}
return &dnspod.Record{
Type: "TXT",
Name: name,
Name: subDomain,
Value: value,
Line: "默认",
TTL: strconv.Itoa(ttl),
}
}, nil
}
func (d *DNSProvider) findTxtRecords(fqdn, zoneID, zoneName string) ([]dnspod.Record, error) {
recordName := extractRecordName(fqdn, zoneName)
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return nil, err
}
var records []dnspod.Record
result, _, err := d.client.Records.List(zoneID, recordName)
result, _, err := d.client.Records.List(zoneID, subDomain)
if err != nil {
return records, fmt.Errorf("API call has failed: %w", err)
}
for _, record := range result {
if record.Name == recordName {
if record.Name == subDomain {
records = append(records, record)
}
}
return records, nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -254,8 +254,10 @@ func (d *DNSProvider) findZoneAndRecordName(fqdn string) (string, string, error)
zone = dns01.UnFqdn(zone)
name := dns01.UnFqdn(fqdn)
name = name[:len(name)-len("."+zone)]
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return "", "", err
}
return zone, name, nil
return zone, subDomain, nil
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
@ -131,11 +130,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
}
// determine name of TXT record
if !strings.HasSuffix(
strings.ToLower(fqdn), strings.ToLower("."+authZone)) {
return fmt.Errorf("gandi: unexpected authZone %s for fqdn %s", authZone, fqdn)
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("gandi: %w", err)
}
name := fqdn[:len(fqdn)-len("."+authZone)]
// acquire lock and check there is not a challenge already in
// progress for this value of authZone
@ -160,7 +158,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("gandi: %w", err)
}
err = d.addTXTRecord(newZoneID, newZoneVersion, name, value, d.config.TTL)
err = d.addTXTRecord(newZoneID, newZoneVersion, subDomain, value, d.config.TTL)
if err != nil {
return fmt.Errorf("gandi: %w", err)
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
@ -120,11 +119,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
}
// determine name of TXT record
if !strings.HasSuffix(
strings.ToLower(fqdn), strings.ToLower("."+authZone)) {
return fmt.Errorf("gandiv5: unexpected authZone %s for fqdn %s", authZone, fqdn)
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("gandiv5: %w", err)
}
name := fqdn[:len(fqdn)-len("."+authZone)]
// acquire lock and check there is not a challenge already in
// progress for this value of authZone
@ -132,7 +130,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
defer d.inProgressMu.Unlock()
// add TXT record into authZone
err = d.addTXTRecord(dns01.UnFqdn(authZone), name, value, d.config.TTL)
err = d.addTXTRecord(dns01.UnFqdn(authZone), subDomain, value, d.config.TTL)
if err != nil {
return err
}
@ -140,7 +138,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
// save data necessary for CleanUp
d.inProgressFQDNs[fqdn] = inProgressInfo{
authZone: authZone,
fieldName: name,
fieldName: subDomain,
}
return nil
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
@ -107,12 +106,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("glesys: findZoneByFqdn failure: %w", err)
}
// determine name of TXT record
if !strings.HasSuffix(
strings.ToLower(fqdn), strings.ToLower("."+authZone)) {
return fmt.Errorf("glesys: unexpected authZone %s for fqdn %s", authZone, fqdn)
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("glesys: %w", err)
}
name := fqdn[:len(fqdn)-len("."+authZone)]
// acquire lock and check there is not a challenge already in
// progress for this value of authZone
@ -121,7 +118,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
// add TXT record into authZone
// TODO(ldez) replace domain by FQDN to follow CNAME.
recordID, err := d.addTXTRecord(domain, dns01.UnFqdn(authZone), name, value, d.config.TTL)
recordID, err := d.addTXTRecord(domain, dns01.UnFqdn(authZone), subDomain, value, d.config.TTL)
if err != nil {
return err
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -110,9 +109,12 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("godaddy: failed to get zone: %w", err)
}
recordName := extractRecordName(fqdn, domainZone)
subDomain, err := dns01.ExtractSubDomain(fqdn, domainZone)
if err != nil {
return fmt.Errorf("godaddy: %w", err)
}
records, err := d.client.GetRecords(domainZone, "TXT", recordName)
records, err := d.client.GetRecords(domainZone, "TXT", subDomain)
if err != nil {
return fmt.Errorf("godaddy: failed to get TXT records: %w", err)
}
@ -126,13 +128,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
record := internal.DNSRecord{
Type: "TXT",
Name: recordName,
Name: subDomain,
Data: value,
TTL: d.config.TTL,
}
newRecords = append(newRecords, record)
err = d.client.UpdateTxtRecords(newRecords, domainZone, recordName)
err = d.client.UpdateTxtRecords(newRecords, domainZone, subDomain)
if err != nil {
return fmt.Errorf("godaddy: failed to add TXT record: %w", err)
}
@ -149,9 +151,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("godaddy: failed to get zone: %w", err)
}
recordName := extractRecordName(fqdn, domainZone)
subDomain, err := dns01.ExtractSubDomain(fqdn, domainZone)
if err != nil {
return fmt.Errorf("godaddy: %w", err)
}
records, err := d.client.GetRecords(domainZone, "TXT", recordName)
records, err := d.client.GetRecords(domainZone, "TXT", subDomain)
if err != nil {
return fmt.Errorf("godaddy: failed to get TXT records: %w", err)
}
@ -186,14 +191,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}
func getZone(fqdn string) (string, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -111,9 +110,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("hetzner: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("hetzner: %w", err)
}
record := internal.DNSRecord{
Type: "TXT",
Name: extractRecordName(fqdn, zone),
Name: subDomain,
Value: value,
TTL: d.config.TTL,
ZoneID: zoneID,
@ -140,9 +144,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("hetzner: %w", err)
}
recordName := extractRecordName(fqdn, zone)
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("hetzner: %w", err)
}
record, err := d.client.GetTxtRecord(recordName, value, zoneID)
record, err := d.client.GetTxtRecord(subDomain, value, zoneID)
if err != nil {
return fmt.Errorf("hetzner: %w", err)
}
@ -154,14 +161,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}
func getZone(fqdn string) (string, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {

View file

@ -122,8 +122,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
d.domainIDs[token] = ikDomain.ID
d.domainIDsMu.Unlock()
subDomain, err := dns01.ExtractSubDomain(fqdn, ikDomain.CustomerName)
if err != nil {
return fmt.Errorf("infomaniak: %w", err)
}
record := internal.Record{
Source: extractRecordName(fqdn, ikDomain.CustomerName),
Source: subDomain,
Target: value,
Type: "TXT",
TTL: d.config.TTL,
@ -184,9 +189,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func extractRecordName(fqdn, domain string) string {
name := dns01.UnFqdn(fqdn)
return name[:len(name)-len(domain)-1]
}

View file

@ -114,7 +114,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err)
}
leaf := fqdn[:len(fqdn)-(len(authZone)+1)]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("mythicbeasts: %w", err)
}
authZone = dns01.UnFqdn(authZone)
@ -123,7 +126,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err)
}
err = d.createTXTRecord(authZone, leaf, value)
err = d.createTXTRecord(authZone, subDomain, value)
if err != nil {
return fmt.Errorf("mythicbeasts: %w", err)
}
@ -140,7 +143,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err)
}
leaf := fqdn[:len(fqdn)-(len(authZone)+1)]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("mythicbeasts: %w", err)
}
authZone = dns01.UnFqdn(authZone)
@ -149,7 +155,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err)
}
err = d.removeTXTRecord(authZone, leaf, value)
err = d.removeTXTRecord(authZone, subDomain, value)
if err != nil {
return fmt.Errorf("mythicbeasts: %w", err)
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -111,13 +110,18 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
// TODO(ldez) replace domain by FQDN to follow CNAME.
domainDetails, err := d.client.GetDomain(&namecom.GetDomainRequest{DomainName: domain})
if err != nil {
return fmt.Errorf("namedotcom API call failed: %w", err)
return fmt.Errorf("namedotcom: API call failed: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(fqdn, domainDetails.DomainName)
if err != nil {
return fmt.Errorf("namedotcom: %w", err)
}
// TODO(ldez) replace domain by FQDN to follow CNAME.
request := &namecom.Record{
DomainName: domain,
Host: extractRecordName(fqdn, domainDetails.DomainName),
Host: subDomain,
Type: "TXT",
TTL: uint32(d.config.TTL),
Answer: value,
@ -183,11 +187,3 @@ func (d *DNSProvider) getRecords(domain string) ([]*namecom.Record, error) {
return records, nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -4,7 +4,6 @@ package namesilo
import (
"errors"
"fmt"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -94,10 +93,15 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("namesilo: %w", err)
}
subdomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return fmt.Errorf("namesilo: %w", err)
}
_, err = d.client.DnsAddRecord(&namesilo.DnsAddRecordParams{
Domain: zoneName,
Type: "TXT",
Host: getRecordName(fqdn, zoneName),
Host: subdomain,
Value: value,
TTL: d.config.TTL,
})
@ -121,10 +125,14 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("namesilo: %w", err)
}
subdomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return fmt.Errorf("namesilo: %w", err)
}
var lastErr error
name := getRecordName(fqdn, zoneName)
for _, r := range resp.Reply.ResourceRecord {
if r.Type == "TXT" && (r.Host == name || r.Host == dns01.UnFqdn(fqdn)) {
if r.Type == "TXT" && (r.Host == subdomain || r.Host == dns01.UnFqdn(fqdn)) {
_, err := d.client.DnsDeleteRecord(&namesilo.DnsDeleteRecordParams{Domain: zoneName, ID: r.RecordID})
if err != nil {
lastErr = fmt.Errorf("namesilo: %w", err)
@ -147,7 +155,3 @@ func getZoneNameByDomain(domain string) (string, error) {
}
return dns01.UnFqdn(zone), nil
}
func getRecordName(domain, zone string) string {
return strings.TrimSuffix(dns01.ToFqdn(domain), "."+dns01.ToFqdn(zone))
}

View file

@ -115,8 +115,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("nearlyfreespeech: could not determine zone for domain %q: %w", fqdn, err)
}
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("nearlyfreespeech: %w", err)
}
record := internal.Record{
Name: getRecordName(fqdn, authZone),
Name: recordName,
Type: "TXT",
Data: value,
TTL: d.config.TTL,
@ -139,8 +144,13 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("nearlyfreespeech: could not determine zone for domain %q: %w", fqdn, err)
}
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("nearlyfreespeech: %w", err)
}
record := internal.Record{
Name: getRecordName(fqdn, authZone),
Name: recordName,
Type: "TXT",
Data: value,
}
@ -152,7 +162,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-1]
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
@ -132,7 +131,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
}
authZone = dns01.UnFqdn(authZone)
subDomain := extractRecordName(fqdn, authZone)
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("ovh: %w", err)
}
reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone)
reqData := Record{FieldType: "TXT", SubDomain: subDomain, Target: value, TTL: d.config.TTL}
@ -204,11 +207,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return ""
}

View file

@ -3,7 +3,6 @@ package sakuracloud
import (
"context"
"fmt"
"strings"
"sync"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -21,17 +20,21 @@ func (d *DNSProvider) addTXTRecord(fqdn, value string, ttl int) error {
zone, err := d.getHostedZone(fqdn)
if err != nil {
return fmt.Errorf("%w", err)
return err
}
name := extractRecordName(fqdn, zone.Name)
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Name)
if err != nil {
return err
}
records := append(zone.Records, &iaas.DNSRecord{
Name: name,
Name: subDomain,
Type: "TXT",
RData: value,
TTL: ttl,
})
_, err = d.client.UpdateSettings(context.Background(), zone.ID, &iaas.DNSUpdateSettingsRequest{
Records: records,
SettingsHash: zone.SettingsHash,
@ -52,11 +55,14 @@ func (d *DNSProvider) cleanupTXTRecord(fqdn, value string) error {
return err
}
recordName := extractRecordName(fqdn, zone.Name)
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Name)
if err != nil {
return err
}
var updRecords iaas.DNSRecords
for _, r := range zone.Records {
if !(r.Name == recordName && r.Type == "TXT" && r.RData == value) {
if !(r.Name == subDomain && r.Type == "TXT" && r.RData == value) {
updRecords = append(updRecords, r)
}
}
@ -104,11 +110,3 @@ func (d *DNSProvider) getHostedZone(domain string) (*iaas.DNS, error) {
return nil, fmt.Errorf("zone %s not found", zoneName)
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -109,7 +109,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("servercow: %w", err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("servercow: %w", err)
}
record := findRecords(records, recordName)
@ -162,7 +165,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("servercow: failed to get TXT records: %w", err)
}
recordName := getRecordName(fqdn, authZone)
recordName, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("servercow: %w", err)
}
record := findRecords(records, recordName)
if record == nil {
@ -231,7 +237,3 @@ func containsValue(record *internal.Record, value string) bool {
return false
}
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-2]
}

View file

@ -8,7 +8,6 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge/dns01"
@ -120,8 +119,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("stackpath: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Domain)
if err != nil {
return fmt.Errorf("stackpath: %w", err)
}
record := Record{
Name: extractRecordName(fqdn, zone.Domain),
Name: subDomain,
Type: "TXT",
TTL: d.config.TTL,
Data: value,
@ -139,9 +143,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("stackpath: %w", err)
}
recordName := extractRecordName(fqdn, zone.Domain)
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Domain)
if err != nil {
return fmt.Errorf("stackpath: %w", err)
}
records, err := d.getZoneRecords(recordName, zone)
records, err := d.getZoneRecords(subDomain, zone)
if err != nil {
return err
}
@ -161,11 +168,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -3,7 +3,6 @@ package tencentcloud
import (
"errors"
"fmt"
"strings"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
@ -84,9 +83,10 @@ func extractRecordName(fqdn, zone string) (string, error) {
return "", fmt.Errorf("fail to convert punycode: %w", err)
}
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+asciiDomain); idx != -1 {
return name[:idx], nil
subDomain, err := dns01.ExtractSubDomain(fqdn, asciiDomain)
if err != nil {
return "", err
}
return name, nil
return subDomain, nil
}

View file

@ -144,9 +144,12 @@ func (r *DNSProvider) Present(domain, _, keyAuth string) error {
return fmt.Errorf("vkcloud: cant find dns zone %s in VK Cloud", authZone)
}
name := fqdn[:len(fqdn)-len(authZone)-1]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("vkcloud: %w", err)
}
err = r.upsertTXTRecord(zoneUUID, name, value)
err = r.upsertTXTRecord(zoneUUID, subDomain, value)
if err != nil {
return fmt.Errorf("vkcloud: %w", err)
}
@ -182,9 +185,12 @@ func (r *DNSProvider) CleanUp(domain, _, keyAuth string) error {
return nil
}
name := fqdn[:len(fqdn)-len(authZone)-1]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("vkcloud: %w", err)
}
err = r.removeTXTRecord(zoneUUID, name, value)
err = r.removeTXTRecord(zoneUUID, subDomain, value)
if err != nil {
return fmt.Errorf("vkcloud: %w", err)
}

View file

@ -105,10 +105,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("vultr: %w", err)
}
name := extractRecordName(fqdn, zoneDomain)
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneDomain)
if err != nil {
return fmt.Errorf("vultr: %w", err)
}
req := govultr.DomainRecordReq{
Name: name,
Name: subDomain,
Type: "TXT",
Data: `"` + value + `"`,
TTL: d.config.TTL,
@ -196,6 +199,11 @@ func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (
return "", nil, err
}
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneDomain)
if err != nil {
return "", nil, err
}
listOptions := &govultr.ListOptions{PerPage: 25}
var records []govultr.DomainRecord
@ -205,9 +213,8 @@ func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (
return "", records, fmt.Errorf("API call has failed: %w", err)
}
recordName := extractRecordName(fqdn, zoneDomain)
for _, record := range result {
if record.Type == "TXT" && record.Name == recordName {
if record.Type == "TXT" && record.Name == subDomain {
records = append(records, record)
}
}
@ -221,11 +228,3 @@ func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (
return zoneDomain, records, nil
}
func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}

View file

@ -128,9 +128,12 @@ func (r *DNSProvider) Present(domain, _, keyAuth string) error {
return fmt.Errorf("yandexcloud: cant find dns zone %s in yandex cloud", authZone)
}
name := fqdn[:len(fqdn)-len(authZone)-1]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("yandexcloud: %w", err)
}
err = r.upsertRecordSetData(ctx, zoneID, name, value)
err = r.upsertRecordSetData(ctx, zoneID, subDomain, value)
if err != nil {
return fmt.Errorf("yandexcloud: %w", err)
}
@ -166,9 +169,12 @@ func (r *DNSProvider) CleanUp(domain, _, keyAuth string) error {
return nil
}
name := fqdn[:len(fqdn)-len(authZone)-1]
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("yandexcloud: %w", err)
}
err = r.removeRecordSetData(ctx, zoneID, name, value)
err = r.removeRecordSetData(ctx, zoneID, subDomain, value)
if err != nil {
return fmt.Errorf("yandexcloud: %w", err)
}

View file

@ -108,7 +108,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
record := txtRecord{
Name: fqdn[:len(fqdn)-1],
Name: dns01.UnFqdn(fqdn),
Destination: value,
}