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

This commit is contained in:
Ludovic Fernandez 2022-12-04 16:11:27 +01:00 committed by GitHub
parent 9ec5c8a18f
commit 7095aa66a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 207 additions and 116 deletions

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -114,7 +113,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("allinkl: %w", err) return fmt.Errorf("allinkl: %w", err)
} }
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("allinkl: %w", err)
}
record := internal.DNSRequest{ record := internal.DNSRequest{
ZoneHost: authZone, ZoneHost: authZone,

View file

@ -7,14 +7,12 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
aazure "github.com/Azure/go-autorest/autorest/azure" aazure "github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth" "github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env" "github.com/go-acme/lego/v4/platform/config/env"
) )
@ -179,11 +177,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return d.provider.CleanUp(domain, token, keyAuth) return d.provider.CleanUp(domain, token, keyAuth)
} }
// Returns the relative record to the domain.
func toRelativeRecord(domain, zone string) string {
return dns01.UnFqdn(strings.TrimSuffix(domain, zone))
}
func getAuthorizer(config *Config) (autorest.Authorizer, error) { func getAuthorizer(config *Config) (autorest.Authorizer, error) {
if config.ClientID != "" && config.ClientSecret != "" && config.TenantID != "" { if config.ClientID != "" && config.ClientSecret != "" && config.TenantID != "" {
credentialsConfig := auth.ClientCredentialsConfig{ credentialsConfig := auth.ClientCredentialsConfig{

View file

@ -39,10 +39,13 @@ func (d *dnsProviderPrivate) Present(domain, token, keyAuth string) error {
rsc := privatedns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID) rsc := privatedns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID)
rsc.Authorizer = d.authorizer rsc.Authorizer = d.authorizer
relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("azure: %w", err)
}
// Get existing record set // Get existing record set
rset, err := rsc.Get(ctx, d.config.ResourceGroup, zone, privatedns.TXT, relative) rset, err := rsc.Get(ctx, d.config.ResourceGroup, zone, privatedns.TXT, subDomain)
if err != nil { if err != nil {
var detailed autorest.DetailedError var detailed autorest.DetailedError
if !errors.As(err, &detailed) || detailed.StatusCode != http.StatusNotFound { if !errors.As(err, &detailed) || detailed.StatusCode != http.StatusNotFound {
@ -68,14 +71,14 @@ func (d *dnsProviderPrivate) Present(domain, token, keyAuth string) error {
} }
rec := privatedns.RecordSet{ rec := privatedns.RecordSet{
Name: &relative, Name: &subDomain,
RecordSetProperties: &privatedns.RecordSetProperties{ RecordSetProperties: &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(int64(d.config.TTL)), TTL: to.Int64Ptr(int64(d.config.TTL)),
TxtRecords: &txtRecords, TxtRecords: &txtRecords,
}, },
} }
_, err = rsc.CreateOrUpdate(ctx, d.config.ResourceGroup, zone, privatedns.TXT, relative, rec, "", "") _, err = rsc.CreateOrUpdate(ctx, d.config.ResourceGroup, zone, privatedns.TXT, subDomain, rec, "", "")
if err != nil { if err != nil {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }
@ -92,12 +95,15 @@ func (d *dnsProviderPrivate) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }
relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("azure: %w", err)
}
rsc := privatedns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID) rsc := privatedns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID)
rsc.Authorizer = d.authorizer rsc.Authorizer = d.authorizer
_, err = rsc.Delete(ctx, d.config.ResourceGroup, zone, privatedns.TXT, relative, "") _, err = rsc.Delete(ctx, d.config.ResourceGroup, zone, privatedns.TXT, subDomain, "")
if err != nil { if err != nil {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }

View file

@ -39,10 +39,13 @@ func (d *dnsProviderPublic) Present(domain, token, keyAuth string) error {
rsc := dns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID) rsc := dns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID)
rsc.Authorizer = d.authorizer rsc.Authorizer = d.authorizer
relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("azure: %w", err)
}
// Get existing record set // Get existing record set
rset, err := rsc.Get(ctx, d.config.ResourceGroup, zone, relative, dns.TXT) rset, err := rsc.Get(ctx, d.config.ResourceGroup, zone, subDomain, dns.TXT)
if err != nil { if err != nil {
var detailed autorest.DetailedError var detailed autorest.DetailedError
if !errors.As(err, &detailed) || detailed.StatusCode != http.StatusNotFound { if !errors.As(err, &detailed) || detailed.StatusCode != http.StatusNotFound {
@ -68,14 +71,14 @@ func (d *dnsProviderPublic) Present(domain, token, keyAuth string) error {
} }
rec := dns.RecordSet{ rec := dns.RecordSet{
Name: &relative, Name: &subDomain,
RecordSetProperties: &dns.RecordSetProperties{ RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(int64(d.config.TTL)), TTL: to.Int64Ptr(int64(d.config.TTL)),
TxtRecords: &txtRecords, TxtRecords: &txtRecords,
}, },
} }
_, err = rsc.CreateOrUpdate(ctx, d.config.ResourceGroup, zone, relative, dns.TXT, rec, "", "") _, err = rsc.CreateOrUpdate(ctx, d.config.ResourceGroup, zone, subDomain, dns.TXT, rec, "", "")
if err != nil { if err != nil {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }
@ -92,12 +95,15 @@ func (d *dnsProviderPublic) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }
relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("azure: %w", err)
}
rsc := dns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID) rsc := dns.NewRecordSetsClientWithBaseURI(d.config.ResourceManagerEndpoint, d.config.SubscriptionID)
rsc.Authorizer = d.authorizer rsc.Authorizer = d.authorizer
_, err = rsc.Delete(ctx, d.config.ResourceGroup, zone, relative, dns.TXT, "") _, err = rsc.Delete(ctx, d.config.ResourceGroup, zone, subDomain, dns.TXT, "")
if err != nil { if err != nil {
return fmt.Errorf("azure: %w", err) return fmt.Errorf("azure: %w", err)
} }

View file

@ -9,7 +9,6 @@ import (
"net/url" "net/url"
"path" "path"
"strconv" "strconv"
"strings"
"github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/dns01"
) )
@ -89,7 +88,10 @@ func (c *Client) GetZone(authFQDN string) (*Zone, error) {
// FindTxtRecord returns the TXT record a zone ID and a FQDN. // FindTxtRecord returns the TXT record a zone ID and a FQDN.
func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) { func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) {
host := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), zoneName)) subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return nil, err
}
reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "records.json")) reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "records.json"))
if err != nil { if err != nil {
@ -98,7 +100,7 @@ func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) {
q := reqURL.Query() q := reqURL.Query()
q.Set("domain-name", zoneName) q.Set("domain-name", zoneName)
q.Set("host", host) q.Set("host", subDomain)
q.Set("type", "TXT") q.Set("type", "TXT")
reqURL.RawQuery = q.Encode() reqURL.RawQuery = q.Encode()
@ -118,7 +120,7 @@ func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) {
} }
for _, record := range records { for _, record := range records {
if record.Host == host && record.Type == "TXT" { if record.Host == subDomain && record.Type == "TXT" {
return &record, nil return &record, nil
} }
} }
@ -128,7 +130,10 @@ func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) {
// ListTxtRecords returns the TXT records a zone ID and a FQDN. // ListTxtRecords returns the TXT records a zone ID and a FQDN.
func (c *Client) ListTxtRecords(zoneName, fqdn string) ([]TXTRecord, error) { func (c *Client) ListTxtRecords(zoneName, fqdn string) ([]TXTRecord, error) {
host := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), zoneName)) subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return nil, err
}
reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "records.json")) reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "records.json"))
if err != nil { if err != nil {
@ -137,7 +142,7 @@ func (c *Client) ListTxtRecords(zoneName, fqdn string) ([]TXTRecord, error) {
q := reqURL.Query() q := reqURL.Query()
q.Set("domain-name", zoneName) q.Set("domain-name", zoneName)
q.Set("host", host) q.Set("host", subDomain)
q.Set("type", "TXT") q.Set("type", "TXT")
reqURL.RawQuery = q.Encode() reqURL.RawQuery = q.Encode()
@ -158,7 +163,7 @@ func (c *Client) ListTxtRecords(zoneName, fqdn string) ([]TXTRecord, error) {
var records []TXTRecord var records []TXTRecord
for _, record := range raw { for _, record := range raw {
if record.Host == host && record.Type == "TXT" { if record.Host == subDomain && record.Type == "TXT" {
records = append(records, record) records = append(records, record)
} }
} }
@ -168,7 +173,10 @@ func (c *Client) ListTxtRecords(zoneName, fqdn string) ([]TXTRecord, error) {
// AddTxtRecord adds a TXT record. // AddTxtRecord adds a TXT record.
func (c *Client) AddTxtRecord(zoneName, fqdn, value string, ttl int) error { func (c *Client) AddTxtRecord(zoneName, fqdn, value string, ttl int) error {
host := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), zoneName)) subDomain, err := dns01.ExtractSubDomain(fqdn, zoneName)
if err != nil {
return err
}
reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "add-record.json")) reqURL, err := c.BaseURL.Parse(path.Join(c.BaseURL.Path, "add-record.json"))
if err != nil { if err != nil {
@ -177,7 +185,7 @@ func (c *Client) AddTxtRecord(zoneName, fqdn, value string, ttl int) error {
q := reqURL.Query() q := reqURL.Query()
q.Set("domain-name", zoneName) q.Set("domain-name", zoneName)
q.Set("host", host) q.Set("host", subDomain)
q.Set("record", value) q.Set("record", value)
q.Set("ttl", strconv.Itoa(ttlRounder(ttl))) q.Set("ttl", strconv.Itoa(ttlRounder(ttl)))
q.Set("record-type", "TXT") q.Set("record-type", "TXT")

View file

@ -212,14 +212,14 @@ func TestClient_FindTxtRecord(t *testing.T) {
}, },
{ {
desc: "zero records", desc: "zero records",
authFQDN: "_acme-challenge.foo.com.", authFQDN: "_acme-challenge.example.com.",
zoneName: "test-zone", zoneName: "example.com",
apiResponse: `[]`, apiResponse: `[]`,
}, },
{ {
desc: "invalid json response", desc: "invalid json response",
authFQDN: "_acme-challenge.foo.com.", authFQDN: "_acme-challenge.example.com.",
zoneName: "test-zone", zoneName: "example.com",
apiResponse: `[{}]`, apiResponse: `[{}]`,
expected: expected{ expected: expected{
errorMsg: "failed to unmarshall TXT records: json: cannot unmarshal array into Go value of type map[string]internal.TXTRecord: [{}]", errorMsg: "failed to unmarshall TXT records: json: cannot unmarshal array into Go value of type map[string]internal.TXTRecord: [{}]",
@ -327,14 +327,14 @@ func TestClient_ListTxtRecord(t *testing.T) {
}, },
{ {
desc: "zero records", desc: "zero records",
authFQDN: "_acme-challenge.foo.com.", authFQDN: "_acme-challenge.example.com.",
zoneName: "test-zone", zoneName: "example.com",
apiResponse: `[]`, apiResponse: `[]`,
}, },
{ {
desc: "invalid json response", desc: "invalid json response",
authFQDN: "_acme-challenge.foo.com.", authFQDN: "_acme-challenge.example.com.",
zoneName: "test-zone", zoneName: "example.com",
apiResponse: `[{}]`, apiResponse: `[{}]`,
expected: expected{ expected: expected{
errorMsg: "failed to unmarshall TXT records: json: cannot unmarshal array into Go value of type map[string]internal.TXTRecord: [{}]", errorMsg: "failed to unmarshall TXT records: json: cannot unmarshal array into Go value of type map[string]internal.TXTRecord: [{}]",

View file

@ -10,7 +10,6 @@ import (
"io" "io"
"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"
@ -127,9 +126,14 @@ func (c *Client) AddTxtRecord(info *Data, fqdn, value string, ttl int) error {
return fmt.Errorf("CloudXNS: invalid zone ID: %w", err) return fmt.Errorf("CloudXNS: invalid zone ID: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, info.Domain)
if err != nil {
return fmt.Errorf("CloudXNS: %w", err)
}
payload := TXTRecord{ payload := TXTRecord{
ID: id, ID: id,
Host: dns01.UnFqdn(strings.TrimSuffix(fqdn, info.Domain)), Host: subDomain,
Value: value, Value: value,
Type: "TXT", Type: "TXT",
LineID: 1, LineID: 1,

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"
@ -142,8 +141,10 @@ func (d *DNSProvider) splitDomain(fqdn string) (string, string, error) {
return "", "", err return "", "", err
} }
host := dns01.UnFqdn(strings.TrimSuffix(fqdn, zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
zone = dns01.UnFqdn(zone) if err != nil {
return "", "", err
}
return zone, host, nil return dns01.UnFqdn(zone), subDomain, nil
} }

View file

@ -5,13 +5,11 @@ 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"
"github.com/go-acme/lego/v4/platform/config/env" "github.com/go-acme/lego/v4/platform/config/env"
"github.com/go-acme/lego/v4/providers/dns/dynu/internal" "github.com/go-acme/lego/v4/providers/dns/dynu/internal"
"github.com/miekg/dns"
) )
// Environment variables names. // Environment variables names.
@ -117,11 +115,16 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
} }
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, domain)
if err != nil {
return fmt.Errorf("dynu: %w", err)
}
record := internal.DNSRecord{ record := internal.DNSRecord{
Type: "TXT", Type: "TXT",
DomainName: rootDomain.DomainName, DomainName: rootDomain.DomainName,
Hostname: dns01.UnFqdn(fqdn), Hostname: dns01.UnFqdn(fqdn),
NodeName: dns01.UnFqdn(strings.TrimSuffix(fqdn, dns.Fqdn(domain))), NodeName: subDomain,
TextData: value, TextData: value,
State: true, State: true,
TTL: d.config.TTL, TTL: d.config.TTL,

View file

@ -101,8 +101,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("epik: %w", err) return fmt.Errorf("epik: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("epik: %w", err)
}
record := internal.RecordRequest{ record := internal.RecordRequest{
Host: dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)), Host: subDomain,
Type: "TXT", Type: "TXT",
Data: value, Data: value,
TTL: d.config.TTL, TTL: d.config.TTL,
@ -127,15 +132,19 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
} }
dom := dns01.UnFqdn(authZone) dom := dns01.UnFqdn(authZone)
host := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone))
records, err := d.client.GetDNSRecords(dom) records, err := d.client.GetDNSRecords(dom)
if err != nil { if err != nil {
return fmt.Errorf("epik: %w", err) return fmt.Errorf("epik: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("epik: %w", err)
}
for _, record := range records { for _, record := range records {
if strings.EqualFold(record.Type, "TXT") && record.Data == value && record.Name == host { if strings.EqualFold(record.Type, "TXT") && record.Data == value && record.Name == subDomain {
_, err = d.client.RemoveHostRecord(dom, record.ID) _, err = d.client.RemoveHostRecord(dom, record.ID)
if err != nil { if err != nil {
return fmt.Errorf("epik: %w", err) return fmt.Errorf("epik: %w", err)

View file

@ -6,7 +6,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"
@ -108,9 +107,12 @@ func (d *DNSProvider) Sequential() time.Duration {
func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth) fqdn, value := dns01.GetRecord(domain, keyAuth)
subDomain := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), freemyip.RootDomain)) subDomain, err := dns01.ExtractSubDomain(fqdn, freemyip.RootDomain)
if err != nil {
return fmt.Errorf("freemyip: %w", err)
}
_, err := d.client.EditTXTRecord(context.Background(), subDomain, value) _, err = d.client.EditTXTRecord(context.Background(), subDomain, value)
if err != nil { if err != nil {
return fmt.Errorf("freemyip: %w", err) return fmt.Errorf("freemyip: %w", err)
} }
@ -122,9 +124,12 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth) fqdn, _ := dns01.GetRecord(domain, keyAuth)
subDomain := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), freemyip.RootDomain)) subDomain, err := dns01.ExtractSubDomain(fqdn, freemyip.RootDomain)
if err != nil {
return fmt.Errorf("freemyip: %w", err)
}
_, err := d.client.DeleteTXTRecord(context.Background(), subDomain) _, err = d.client.DeleteTXTRecord(context.Background(), subDomain)
if err != nil { if err != nil {
return fmt.Errorf("freemyip: %w", err) return fmt.Errorf("freemyip: %w", err)
} }

View file

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
@ -114,9 +113,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("hosttech: could not find zone for domain %q (%s): %w", domain, authZone, err) return fmt.Errorf("hosttech: could not find zone for domain %q (%s): %w", domain, authZone, err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("hosttech: %w", err)
}
record := internal.Record{ record := internal.Record{
Type: "TXT", Type: "TXT",
Name: dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)), Name: subDomain,
Text: value, Text: value,
TTL: d.config.TTL, TTL: d.config.TTL,
} }

View file

@ -3,7 +3,6 @@ package joker
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"
@ -81,10 +80,13 @@ func (d *dmapiProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err) return fmt.Errorf("joker: %w", err)
} }
relative := getRelative(fqdn, zone) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("joker: %w", err)
}
if d.config.Debug { if d.config.Debug {
log.Infof("[%s] joker: adding TXT record %q to zone %q with value %q", domain, relative, zone, value) log.Infof("[%s] joker: adding TXT record %q to zone %q with value %q", domain, subDomain, zone, value)
} }
response, err := d.client.Login() response, err := d.client.Login()
@ -97,7 +99,7 @@ func (d *dmapiProvider) Present(domain, token, keyAuth string) error {
return formatResponseError(response, err) return formatResponseError(response, err)
} }
dnsZone := dmapi.AddTxtEntryToZone(response.Body, relative, value, d.config.TTL) dnsZone := dmapi.AddTxtEntryToZone(response.Body, subDomain, value, d.config.TTL)
response, err = d.client.PutZone(zone, dnsZone) response, err = d.client.PutZone(zone, dnsZone)
if err != nil || response.StatusCode != 0 { if err != nil || response.StatusCode != 0 {
@ -116,10 +118,13 @@ func (d *dmapiProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err) return fmt.Errorf("joker: %w", err)
} }
relative := getRelative(fqdn, zone) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("joker: %w", err)
}
if d.config.Debug { if d.config.Debug {
log.Infof("[%s] joker: removing entry %q from zone %q", domain, relative, zone) log.Infof("[%s] joker: removing entry %q from zone %q", domain, subDomain, zone)
} }
response, err := d.client.Login() response, err := d.client.Login()
@ -128,7 +133,7 @@ func (d *dmapiProvider) CleanUp(domain, token, keyAuth string) error {
} }
defer func() { defer func() {
// Try to logout in case of errors // Try to log out in case of errors
_, _ = d.client.Logout() _, _ = d.client.Logout()
}() }()
@ -137,7 +142,7 @@ func (d *dmapiProvider) CleanUp(domain, token, keyAuth string) error {
return formatResponseError(response, err) return formatResponseError(response, err)
} }
dnsZone, modified := dmapi.RemoveTxtEntryFromZone(response.Body, relative) dnsZone, modified := dmapi.RemoveTxtEntryFromZone(response.Body, subDomain)
if modified { if modified {
response, err = d.client.PutZone(zone, dnsZone) response, err = d.client.PutZone(zone, dnsZone)
if err != nil || response.StatusCode != 0 { if err != nil || response.StatusCode != 0 {
@ -152,10 +157,6 @@ func (d *dmapiProvider) CleanUp(domain, token, keyAuth string) error {
return nil return nil
} }
func getRelative(fqdn, zone string) string {
return dns01.UnFqdn(strings.TrimSuffix(fqdn, dns01.ToFqdn(zone)))
}
// formatResponseError formats error with optional details from DMAPI response. // formatResponseError formats error with optional details from DMAPI response.
func formatResponseError(response *dmapi.Response, err error) error { func formatResponseError(response *dmapi.Response, err error) error {
if response != nil { if response != nil {

View file

@ -61,9 +61,12 @@ func (d *svcProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err) return fmt.Errorf("joker: %w", err)
} }
relative := getRelative(fqdn, zone) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("joker: %w", err)
}
return d.client.Send(dns01.UnFqdn(zone), relative, value) return d.client.Send(dns01.UnFqdn(zone), subDomain, value)
} }
// CleanUp removes the TXT record matching the specified parameters. // CleanUp removes the TXT record matching the specified parameters.
@ -75,9 +78,12 @@ func (d *svcProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("joker: %w", err) return fmt.Errorf("joker: %w", err)
} }
relative := getRelative(fqdn, zone) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return fmt.Errorf("joker: %w", err)
}
return d.client.Send(dns01.UnFqdn(zone), relative, "") return d.client.Send(dns01.UnFqdn(zone), subDomain, "")
} }
// Sequential All DNS challenges for this provider will be resolved sequentially. // Sequential All DNS challenges for this provider will be resolved sequentially.

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -128,9 +127,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("liara: %w", err) return fmt.Errorf("liara: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("liara: %w", err)
}
record := internal.Record{ record := internal.Record{
Type: "TXT", Type: "TXT",
Name: dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)), Name: subDomain,
Contents: []internal.Content{{Text: value}}, Contents: []internal.Content{{Text: value}},
TTL: d.config.TTL, TTL: d.config.TTL,
} }

View file

@ -7,7 +7,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"
@ -167,7 +166,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
// Remove the specified resource, if it exists. // Remove the specified resource, if it exists.
for _, resource := range resources { for _, resource := range resources {
if (resource.Name == strings.TrimSuffix(fqdn, ".") || resource.Name == zone.resourceName) && if (resource.Name == dns01.UnFqdn(fqdn) || resource.Name == zone.resourceName) &&
resource.Target == value { resource.Target == value {
if err := d.client.DeleteDomainRecord(context.Background(), zone.domainID, resource.ID); err != nil { if err := d.client.DeleteDomainRecord(context.Background(), zone.domainID, resource.ID); err != nil {
return err return err
@ -201,8 +200,13 @@ func (d *DNSProvider) getHostedZoneInfo(fqdn string) (*hostedZoneInfo, error) {
return nil, errors.New("domain not found") return nil, errors.New("domain not found")
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return nil, err
}
return &hostedZoneInfo{ return &hostedZoneInfo{
domainID: domains[0].ID, domainID: domains[0].ID,
resourceName: strings.TrimSuffix(fqdn, "."+authZone), resourceName: subDomain,
}, nil }, nil
} }

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -131,14 +130,17 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth) fqdn, value := dns01.GetRecord(domain, keyAuth)
subdomain, authZone := d.splitDomain(fqdn) subDomain, authZone, err := d.splitDomain(fqdn)
if err != nil {
return fmt.Errorf("loopia: %w", err)
}
err := d.client.AddTXTRecord(authZone, subdomain, d.config.TTL, value) err = d.client.AddTXTRecord(authZone, subDomain, d.config.TTL, value)
if err != nil { if err != nil {
return fmt.Errorf("loopia: failed to add TXT record: %w", err) return fmt.Errorf("loopia: failed to add TXT record: %w", err)
} }
txtRecords, err := d.client.GetTXTRecords(authZone, subdomain) txtRecords, err := d.client.GetTXTRecords(authZone, subDomain)
if err != nil { if err != nil {
return fmt.Errorf("loopia: failed to get TXT records: %w", err) return fmt.Errorf("loopia: failed to get TXT records: %w", err)
} }
@ -160,17 +162,20 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth) fqdn, _ := dns01.GetRecord(domain, keyAuth)
subdomain, authZone := d.splitDomain(fqdn) subDomain, authZone, err := d.splitDomain(fqdn)
if err != nil {
return fmt.Errorf("loopia: %w", err)
}
d.inProgressMu.Lock() d.inProgressMu.Lock()
defer d.inProgressMu.Unlock() defer d.inProgressMu.Unlock()
err := d.client.RemoveTXTRecord(authZone, subdomain, d.inProgressInfo[token]) err = d.client.RemoveTXTRecord(authZone, subDomain, d.inProgressInfo[token])
if err != nil { if err != nil {
return fmt.Errorf("loopia: failed to remove TXT record: %w", err) return fmt.Errorf("loopia: failed to remove TXT record: %w", err)
} }
records, err := d.client.GetTXTRecords(authZone, subdomain) records, err := d.client.GetTXTRecords(authZone, subDomain)
if err != nil { if err != nil {
return fmt.Errorf("loopia: failed to get TXT records: %w", err) return fmt.Errorf("loopia: failed to get TXT records: %w", err)
} }
@ -179,7 +184,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil return nil
} }
err = d.client.RemoveSubdomain(authZone, subdomain) err = d.client.RemoveSubdomain(authZone, subDomain)
if err != nil { if err != nil {
return fmt.Errorf("loopia: failed to remove sub-domain: %w", err) return fmt.Errorf("loopia: failed to remove sub-domain: %w", err)
} }
@ -187,11 +192,14 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil return nil
} }
func (d *DNSProvider) splitDomain(fqdn string) (string, string) { func (d *DNSProvider) splitDomain(fqdn string) (string, string, error) {
authZone, _ := d.findZoneByFqdn(fqdn) authZone, _ := d.findZoneByFqdn(fqdn)
authZone = dns01.UnFqdn(authZone) authZone = dns01.UnFqdn(authZone)
subdomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+authZone) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return "", "", err
}
return subdomain, authZone return subDomain, authZone, nil
} }

View file

@ -55,7 +55,8 @@ func TestSplitDomain(t *testing.T) {
for _, test := range testCases { for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
subdomain, domain := provider.splitDomain(test.fqdn) subdomain, domain, err := provider.splitDomain(test.fqdn)
require.NoError(t, err)
assert.Equal(t, test.subdomain, subdomain) assert.Equal(t, test.subdomain, subdomain)
assert.Equal(t, test.domain, domain) assert.Equal(t, test.domain, domain)

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"
@ -170,5 +169,5 @@ func getAuthZone(fqdn string) (string, error) {
return "", err return "", err
} }
return strings.TrimSuffix(authZone, "."), nil return dns01.UnFqdn(authZone), nil
} }

View file

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
@ -175,7 +174,10 @@ func splitDomain(fqdn string) (string, string, error) {
return "", "", err return "", "", err
} }
host := dns01.UnFqdn(strings.TrimSuffix(fqdn, zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return "", "", err
}
return zone, host, nil return zone, subDomain, 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"
@ -105,7 +104,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("regru: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err) return fmt.Errorf("regru: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
} }
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("regru: %w", err)
}
err = d.client.AddTXTRecord(dns01.UnFqdn(authZone), subDomain, value) err = d.client.AddTXTRecord(dns01.UnFqdn(authZone), subDomain, value)
if err != nil { if err != nil {
return fmt.Errorf("regru: failed to create TXT records [domain: %s, sub domain: %s]: %w", return fmt.Errorf("regru: failed to create TXT records [domain: %s, sub domain: %s]: %w",
@ -124,7 +127,11 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("regru: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err) return fmt.Errorf("regru: could not find zone for domain %q and fqdn %q : %w", domain, fqdn, err)
} }
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("regru: %w", err)
}
err = d.client.RemoveTxtRecord(dns01.UnFqdn(authZone), subDomain, value) err = d.client.RemoveTxtRecord(dns01.UnFqdn(authZone), subDomain, value)
if err != nil { if err != nil {
return fmt.Errorf("regru: failed to remove TXT records [domain: %s, sub domain: %s]: %w", return fmt.Errorf("regru: failed to remove TXT records [domain: %s, sub domain: %s]: %w",

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@ -119,7 +118,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
} }
authZone = dns01.UnFqdn(authZone) authZone = dns01.UnFqdn(authZone)
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("regru: %w", err)
}
recordBody := internal.Record{ recordBody := internal.Record{
Name: subDomain, Name: subDomain,

View file

@ -4,7 +4,6 @@ package transip
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"
@ -99,10 +98,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return err return err
} }
domainName := dns01.UnFqdn(authZone)
// get the subDomain // get the subDomain
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("transip: %w", err)
}
domainName := dns01.UnFqdn(authZone)
entry := transipdomain.DNSEntry{ entry := transipdomain.DNSEntry{
Name: subDomain, Name: subDomain,
@ -128,10 +130,13 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return err return err
} }
domainName := dns01.UnFqdn(authZone)
// get the subDomain // get the subDomain
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("transip: %w", err)
}
domainName := dns01.UnFqdn(authZone)
// get all DNS entries // get all DNS entries
dnsEntries, err := d.repository.GetDNSEntries(domainName) dnsEntries, err := d.repository.GetDNSEntries(domainName)

View file

@ -121,9 +121,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("variomedia: %w", err) return fmt.Errorf("variomedia: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("variomedia: %w", err)
}
record := internal.DNSRecord{ record := internal.DNSRecord{
RecordType: "TXT", RecordType: "TXT",
Name: dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)), Name: subDomain,
Domain: dns01.UnFqdn(authZone), Domain: dns01.UnFqdn(authZone),
Data: value, Data: value,
TTL: d.config.TTL, TTL: d.config.TTL,

View file

@ -4,7 +4,6 @@ package vegadns
import ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"time" "time"
vegaClient "github.com/OpenDNS/vegadns2client" vegaClient "github.com/OpenDNS/vegadns2client"
@ -111,7 +110,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("vegadns: can't find Authoritative Zone for %s in CleanUp: %w", fqdn, err) return fmt.Errorf("vegadns: can't find Authoritative Zone for %s in CleanUp: %w", fqdn, err)
} }
txt := strings.TrimSuffix(fqdn, ".") txt := dns01.UnFqdn(fqdn)
recordID, err := d.client.GetRecordID(domainID, txt, "TXT") recordID, err := d.client.GetRecordID(domainID, txt, "TXT")
if err != nil { if err != nil {

View file

@ -4,7 +4,6 @@ package vinyldns
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"
@ -285,7 +284,10 @@ func splitDomain(fqdn string) (string, string, error) {
return "", "", err return "", "", err
} }
host := dns01.UnFqdn(strings.TrimSuffix(fqdn, zone)) subDomain, err := dns01.ExtractSubDomain(fqdn, zone)
if err != nil {
return "", "", err
}
return zone, host, nil return zone, subDomain, nil
} }

View file

@ -7,7 +7,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"
@ -112,7 +111,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("wedos: could not determine zone for domain %q: %w", domain, err) return fmt.Errorf("wedos: could not determine zone for domain %q: %w", domain, err)
} }
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("wedos: %w", err)
}
record := internal.DNSRow{ record := internal.DNSRow{
Name: subDomain, Name: subDomain,
@ -157,7 +159,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("wedos: could not determine zone for domain %q: %w", domain, err) return fmt.Errorf("wedos: could not determine zone for domain %q: %w", domain, err)
} }
subDomain := dns01.UnFqdn(strings.TrimSuffix(fqdn, authZone)) subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
if err != nil {
return fmt.Errorf("wedos: %w", err)
}
records, err := d.client.GetRecords(ctx, authZone) records, err := d.client.GetRecords(ctx, authZone)
if err != nil { if err != nil {