1
0
mirror of https://github.com/go-acme/lego.git synced 2025-07-17 12:17:44 +02:00

azion: improve zone lookup (#2564)

Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
Marcus Grando
2025-07-07 14:48:57 -03:00
committed by GitHub
parent 990f9ac601
commit 17c65de6e7
4 changed files with 175 additions and 13 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/aziontech/azionapi-go-sdk/idns"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env"
"github.com/miekg/dns"
)
// Environment variables names.
@ -182,13 +183,12 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
}
defer func() {
// Remove the record ID from our map
// Cleans the record ID.
d.recordIDsMu.Lock()
delete(d.recordIDs, token)
d.recordIDsMu.Unlock()
}()
// Find the existing TXT record
existingRecord, err := d.findExistingTXTRecord(ctxAuth, zone.GetId(), subDomain)
if err != nil {
return fmt.Errorf("azion: find existing record: %w", err)
@ -198,7 +198,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}
// Get current answers and remove the specific value
currentAnswers := existingRecord.GetAnswersList()
var updatedAnswers []string
@ -239,11 +238,6 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
}
func (d *DNSProvider) findZone(ctx context.Context, fqdn string) (*idns.Zone, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {
return nil, fmt.Errorf("could not find a zone for domain %q: %w", fqdn, err)
}
resp, _, err := d.client.ZonesAPI.GetZones(ctx).Execute()
if err != nil {
return nil, fmt.Errorf("get zones: %w", err)
@ -253,14 +247,19 @@ func (d *DNSProvider) findZone(ctx context.Context, fqdn string) (*idns.Zone, er
return nil, errors.New("get zones: no results")
}
targetZone := dns01.UnFqdn(authZone)
for _, zone := range resp.GetResults() {
if zone.GetName() == targetZone {
return &zone, nil
labelIndexes := dns.Split(fqdn)
for _, index := range labelIndexes {
domain := dns01.UnFqdn(fqdn[index:])
for _, zone := range resp.GetResults() {
if zone.GetDomain() == domain {
return &zone, nil
}
}
}
return nil, fmt.Errorf("zone %q not found (fqdn: %q)", authZone, fqdn)
return nil, fmt.Errorf("zone not found (fqdn: %q)", fqdn)
}
// findExistingTXTRecord searches for an existing TXT record with the given name in the specified zone.

View File

@ -1,9 +1,17 @@
package azion
import (
"context"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/aziontech/azionapi-go-sdk/idns"
"github.com/go-acme/lego/v4/platform/tester"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -113,3 +121,129 @@ func TestLiveCleanUp(t *testing.T) {
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
require.NoError(t, err)
}
func TestDNSProvider_findZone(t *testing.T) {
provider, mux := setupTest(t)
mux.HandleFunc("GET /intelligent_dns", writeFixtureHandler("zones.json"))
testCases := []struct {
desc string
fqdn string
expected *idns.Zone
}{
{
desc: "apex",
fqdn: "example.com.",
expected: &idns.Zone{
Id: idns.PtrInt32(1),
Domain: idns.PtrString("example.com"),
},
},
{
desc: "sub domain",
fqdn: "sub.example.com.",
expected: &idns.Zone{
Id: idns.PtrInt32(2),
Domain: idns.PtrString("sub.example.com"),
},
},
{
desc: "long sub domain",
fqdn: "_acme-challenge.api.sub.example.com.",
expected: &idns.Zone{
Id: idns.PtrInt32(2),
Domain: idns.PtrString("sub.example.com"),
},
},
{
desc: "long sub domain, apex",
fqdn: "_acme-challenge.test.example.com.",
expected: &idns.Zone{
Id: idns.PtrInt32(1),
Domain: idns.PtrString("example.com"),
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
zone, err := provider.findZone(context.Background(), test.fqdn)
require.NoError(t, err)
assert.Equal(t, test.expected, zone)
})
}
}
func TestDNSProvider_findZone_error(t *testing.T) {
testCases := []struct {
desc string
fqdn string
response string
expected string
}{
{
desc: "no parent zone found",
fqdn: "_acme-challenge.example.org.",
response: "zones.json",
expected: `zone not found (fqdn: "_acme-challenge.example.org.")`,
},
{
desc: "empty zones list",
fqdn: "example.com.",
response: "zones_empty.json",
expected: `zone not found (fqdn: "example.com.")`,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
provider, mux := setupTest(t)
mux.HandleFunc("GET /intelligent_dns", writeFixtureHandler(test.response))
zone, err := provider.findZone(context.Background(), test.fqdn)
require.EqualError(t, err, test.expected)
assert.Nil(t, zone)
})
}
}
func setupTest(t *testing.T) (*DNSProvider, *http.ServeMux) {
t.Helper()
mux := http.NewServeMux()
server := httptest.NewServer(mux)
config := NewDefaultConfig()
config.PersonalToken = "secret"
provider, err := NewDNSProviderConfig(config)
require.NoError(t, err)
clientConfig := provider.client.GetConfig()
clientConfig.HTTPClient = server.Client()
clientConfig.Servers = idns.ServerConfigurations{
{
URL: server.URL,
Description: "Production",
},
}
return provider, mux
}
func writeFixtureHandler(filename string) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Content-Type", "application/json")
file, err := os.Open(filepath.Join("fixtures", filename))
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
defer func() { _ = file.Close() }()
_, _ = io.Copy(rw, file)
}
}

View File

@ -0,0 +1,19 @@
{
"count": 2,
"links": {
"previous": null,
"next": null
},
"total_pages": 1,
"results": [
{
"id": 1,
"domain": "example.com"
},
{
"id": 2,
"domain": "sub.example.com"
}
],
"schema_version": 3
}

View File

@ -0,0 +1,10 @@
{
"count": 0,
"links": {
"previous": null,
"next": null
},
"total_pages": 0,
"results": null,
"schema_version": 3
}