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 ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk" "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) return "", fmt.Errorf("fail to convert punycode: %w", err)
} }
name := dns01.UnFqdn(fqdn) subDomain, err := dns01.ExtractSubDomain(fqdn, asciiDomain)
if idx := strings.Index(name, "."+asciiDomain); idx != -1 { if err != nil {
return name[:idx], nil return "", err
} }
return name, nil
return subDomain, nil
} }

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -114,9 +113,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return err return err
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("arvancloud: %w", err)
}
record := internal.DNSRecord{ record := internal.DNSRecord{
Type: "txt", Type: "txt",
Name: extractRecordName(fqdn, authZone), Name: subDomain,
Value: internal.TXTRecordValue{Text: value}, Value: internal.TXTRecordValue{Text: value},
TTL: d.config.TTL, TTL: d.config.TTL,
UpstreamHTTPS: "default", UpstreamHTTPS: "default",
@ -176,11 +180,3 @@ func getZone(fqdn string) (string, error) {
return dns01.UnFqdn(authZone), nil 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 ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/civo/civogo" "github.com/civo/civogo"
@ -104,8 +103,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("civo: %w", err) 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{ _, err = d.client.CreateDNSRecord(dnsDomain.ID, &civogo.DNSRecordConfig{
Name: extractRecordName(fqdn, zone), Name: subDomain,
Value: value, Value: value,
Type: civogo.DNSRecordTypeTXT, Type: civogo.DNSRecordTypeTXT,
TTL: d.config.TTL, TTL: d.config.TTL,
@ -136,9 +140,14 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("civo: %w", err) 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 var dnsRecord civogo.DNSRecord
for _, entry := range dnsRecords { for _, entry := range dnsRecords {
if entry.Name == extractRecordName(fqdn, zone) && entry.Value == value { if entry.Name == subDomain && entry.Value == value {
dnsRecord = entry dnsRecord = entry
break break
} }
@ -166,11 +175,3 @@ func getZone(fqdn string) (string, error) {
return dns01.UnFqdn(authZone), nil 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) 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) records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
if err != nil { 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) 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) records, err := d.client.TxtRecords.Search(dom.ID, internal.Exact, recordName)
if err != nil { if err != nil {
@ -262,7 +268,3 @@ func containsValue(record *internal.Record, value string) bool {
return false 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) 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) 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) 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) domainName := dns01.UnFqdn(authZone)
@ -179,7 +185,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil return nil
} }
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-1]
}

View file

@ -6,7 +6,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/dnsimple/dnsimple-go/dnsimple" "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) 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) _, err = d.client.Zones.CreateRecord(context.Background(), accountID, zoneName, recordAttributes)
if err != nil { if err != nil {
return fmt.Errorf("dnsimple: API call failed: %w", err) 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 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 { if err != nil {
return nil, fmt.Errorf("API call has failed: %w", err) 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 return result.Data, nil
} }
func newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimple.ZoneRecordAttributes { func newTxtRecord(zoneName, fqdn, value string, ttl int) (dnsimple.ZoneRecordAttributes, error) {
name := extractRecordName(fqdn, zoneName) subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return dnsimple.ZoneRecordAttributes{}, err
}
return dnsimple.ZoneRecordAttributes{ return dnsimple.ZoneRecordAttributes{
Type: "TXT", Type: "TXT",
Name: &name, Name: &subDomain,
Content: value, Content: value,
TTL: ttl, TTL: ttl,
} }, 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 (d *DNSProvider) getAccountID() (string, error) { func (d *DNSProvider) getAccountID() (string, error) {

View file

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

View file

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

View file

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

View file

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

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/go-acme/lego/v4/challenge/dns01" "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) 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 { if err != nil {
return fmt.Errorf("godaddy: failed to get TXT records: %w", err) 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{ record := internal.DNSRecord{
Type: "TXT", Type: "TXT",
Name: recordName, Name: subDomain,
Data: value, Data: value,
TTL: d.config.TTL, TTL: d.config.TTL,
} }
newRecords = append(newRecords, record) newRecords = append(newRecords, record)
err = d.client.UpdateTxtRecords(newRecords, domainZone, recordName) err = d.client.UpdateTxtRecords(newRecords, domainZone, subDomain)
if err != nil { if err != nil {
return fmt.Errorf("godaddy: failed to add TXT record: %w", err) 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) 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 { if err != nil {
return fmt.Errorf("godaddy: failed to get TXT records: %w", err) 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 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) { func getZone(fqdn string) (string, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn) authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil { if err != nil {

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/go-acme/lego/v4/challenge/dns01" "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) return fmt.Errorf("hetzner: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("hetzner: %w", err)
}
record := internal.DNSRecord{ record := internal.DNSRecord{
Type: "TXT", Type: "TXT",
Name: extractRecordName(fqdn, zone), Name: subDomain,
Value: value, Value: value,
TTL: d.config.TTL, TTL: d.config.TTL,
ZoneID: zoneID, ZoneID: zoneID,
@ -140,9 +144,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("hetzner: %w", err) 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 { if err != nil {
return fmt.Errorf("hetzner: %w", err) return fmt.Errorf("hetzner: %w", err)
} }
@ -154,14 +161,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil 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) { func getZone(fqdn string) (string, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn) authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil { if err != nil {

View file

@ -122,8 +122,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
d.domainIDs[token] = ikDomain.ID d.domainIDs[token] = ikDomain.ID
d.domainIDsMu.Unlock() d.domainIDsMu.Unlock()
subDomain, err := dns01.ExtractSubDomain(fqdn, ikDomain.CustomerName)
if err != nil {
return fmt.Errorf("infomaniak: %w", err)
}
record := internal.Record{ record := internal.Record{
Source: extractRecordName(fqdn, ikDomain.CustomerName), Source: subDomain,
Target: value, Target: value,
Type: "TXT", Type: "TXT",
TTL: d.config.TTL, 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) { func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval 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) 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) authZone = dns01.UnFqdn(authZone)
@ -123,7 +126,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err) return fmt.Errorf("mythicbeasts: %w", err)
} }
err = d.createTXTRecord(authZone, leaf, value) err = d.createTXTRecord(authZone, subDomain, value)
if err != nil { if err != nil {
return fmt.Errorf("mythicbeasts: %w", err) 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) 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) authZone = dns01.UnFqdn(authZone)
@ -149,7 +155,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("mythicbeasts: %w", err) return fmt.Errorf("mythicbeasts: %w", err)
} }
err = d.removeTXTRecord(authZone, leaf, value) err = d.removeTXTRecord(authZone, subDomain, value)
if err != nil { if err != nil {
return fmt.Errorf("mythicbeasts: %w", err) return fmt.Errorf("mythicbeasts: %w", err)
} }

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/go-acme/lego/v4/challenge/dns01" "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. // TODO(ldez) replace domain by FQDN to follow CNAME.
domainDetails, err := d.client.GetDomain(&namecom.GetDomainRequest{DomainName: domain}) domainDetails, err := d.client.GetDomain(&namecom.GetDomainRequest{DomainName: domain})
if err != nil { 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. // TODO(ldez) replace domain by FQDN to follow CNAME.
request := &namecom.Record{ request := &namecom.Record{
DomainName: domain, DomainName: domain,
Host: extractRecordName(fqdn, domainDetails.DomainName), Host: subDomain,
Type: "TXT", Type: "TXT",
TTL: uint32(d.config.TTL), TTL: uint32(d.config.TTL),
Answer: value, Answer: value,
@ -183,11 +187,3 @@ func (d *DNSProvider) getRecords(domain string) ([]*namecom.Record, error) {
return records, nil 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 ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/go-acme/lego/v4/challenge/dns01" "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) 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{ _, err = d.client.DnsAddRecord(&namesilo.DnsAddRecordParams{
Domain: zoneName, Domain: zoneName,
Type: "TXT", Type: "TXT",
Host: getRecordName(fqdn, zoneName), Host: subdomain,
Value: value, Value: value,
TTL: d.config.TTL, TTL: d.config.TTL,
}) })
@ -121,10 +125,14 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("namesilo: %w", err) return fmt.Errorf("namesilo: %w", err)
} }
subdomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return fmt.Errorf("namesilo: %w", err)
}
var lastErr error var lastErr error
name := getRecordName(fqdn, zoneName)
for _, r := range resp.Reply.ResourceRecord { 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}) _, err := d.client.DnsDeleteRecord(&namesilo.DnsDeleteRecordParams{Domain: zoneName, ID: r.RecordID})
if err != nil { if err != nil {
lastErr = fmt.Errorf("namesilo: %w", err) lastErr = fmt.Errorf("namesilo: %w", err)
@ -147,7 +155,3 @@ func getZoneNameByDomain(domain string) (string, error) {
} }
return dns01.UnFqdn(zone), nil 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) 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{ record := internal.Record{
Name: getRecordName(fqdn, authZone), Name: recordName,
Type: "TXT", Type: "TXT",
Data: value, Data: value,
TTL: d.config.TTL, 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) 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{ record := internal.Record{
Name: getRecordName(fqdn, authZone), Name: recordName,
Type: "TXT", Type: "TXT",
Data: value, Data: value,
} }
@ -152,7 +162,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil return nil
} }
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-1]
}

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -132,7 +131,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
} }
authZone = dns01.UnFqdn(authZone) 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) reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone)
reqData := Record{FieldType: "TXT", SubDomain: subDomain, Target: value, TTL: d.config.TTL} 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) { func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval 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 ( import (
"context" "context"
"fmt" "fmt"
"strings"
"sync" "sync"
"github.com/go-acme/lego/v4/challenge/dns01" "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) zone, err := d.getHostedZone(fqdn)
if err != nil { 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{ records := append(zone.Records, &iaas.DNSRecord{
Name: name, Name: subDomain,
Type: "TXT", Type: "TXT",
RData: value, RData: value,
TTL: ttl, TTL: ttl,
}) })
_, err = d.client.UpdateSettings(context.Background(), zone.ID, &iaas.DNSUpdateSettingsRequest{ _, err = d.client.UpdateSettings(context.Background(), zone.ID, &iaas.DNSUpdateSettingsRequest{
Records: records, Records: records,
SettingsHash: zone.SettingsHash, SettingsHash: zone.SettingsHash,
@ -52,11 +55,14 @@ func (d *DNSProvider) cleanupTXTRecord(fqdn, value string) error {
return err return err
} }
recordName := extractRecordName(fqdn, zone.Name) subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Name)
if err != nil {
return err
}
var updRecords iaas.DNSRecords var updRecords iaas.DNSRecords
for _, r := range zone.Records { 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) 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) 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) 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) 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) 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) record := findRecords(records, recordName)
if record == nil { if record == nil {
@ -231,7 +237,3 @@ func containsValue(record *internal.Record, value string) bool {
return false return false
} }
func getRecordName(fqdn, authZone string) string {
return fqdn[0 : len(fqdn)-len(authZone)-2]
}

View file

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings"
"time" "time"
"github.com/go-acme/lego/v4/challenge/dns01" "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) return fmt.Errorf("stackpath: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, zone.Domain)
if err != nil {
return fmt.Errorf("stackpath: %w", err)
}
record := Record{ record := Record{
Name: extractRecordName(fqdn, zone.Domain), Name: subDomain,
Type: "TXT", Type: "TXT",
TTL: d.config.TTL, TTL: d.config.TTL,
Data: value, Data: value,
@ -139,9 +143,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("stackpath: %w", err) 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 { if err != nil {
return err return err
} }
@ -161,11 +168,3 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval 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 ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/dns01"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "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) return "", fmt.Errorf("fail to convert punycode: %w", err)
} }
name := dns01.UnFqdn(fqdn) subDomain, err := dns01.ExtractSubDomain(fqdn, asciiDomain)
if idx := strings.Index(name, "."+asciiDomain); idx != -1 { if err != nil {
return name[:idx], 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) 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 { if err != nil {
return fmt.Errorf("vkcloud: %w", err) return fmt.Errorf("vkcloud: %w", err)
} }
@ -182,9 +185,12 @@ func (r *DNSProvider) CleanUp(domain, _, keyAuth string) error {
return nil 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 { if err != nil {
return fmt.Errorf("vkcloud: %w", err) 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) 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{ req := govultr.DomainRecordReq{
Name: name, Name: subDomain,
Type: "TXT", Type: "TXT",
Data: `"` + value + `"`, Data: `"` + value + `"`,
TTL: d.config.TTL, TTL: d.config.TTL,
@ -196,6 +199,11 @@ func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (
return "", nil, err return "", nil, err
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, zoneDomain)
if err != nil {
return "", nil, err
}
listOptions := &govultr.ListOptions{PerPage: 25} listOptions := &govultr.ListOptions{PerPage: 25}
var records []govultr.DomainRecord 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) return "", records, fmt.Errorf("API call has failed: %w", err)
} }
recordName := extractRecordName(fqdn, zoneDomain)
for _, record := range result { for _, record := range result {
if record.Type == "TXT" && record.Name == recordName { if record.Type == "TXT" && record.Name == subDomain {
records = append(records, record) records = append(records, record)
} }
} }
@ -221,11 +228,3 @@ func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (
return zoneDomain, records, nil 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) 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 { if err != nil {
return fmt.Errorf("yandexcloud: %w", err) return fmt.Errorf("yandexcloud: %w", err)
} }
@ -166,9 +169,12 @@ func (r *DNSProvider) CleanUp(domain, _, keyAuth string) error {
return nil 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 { if err != nil {
return fmt.Errorf("yandexcloud: %w", err) 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) fqdn, value := dns01.GetRecord(domain, keyAuth)
record := txtRecord{ record := txtRecord{
Name: fqdn[:len(fqdn)-1], Name: dns01.UnFqdn(fqdn),
Destination: value, Destination: value,
} }