diff --git a/providers/dns/oraclecloud/oraclecloud.go b/providers/dns/oraclecloud/oraclecloud.go index 730b3f212..8da54bff1 100644 --- a/providers/dns/oraclecloud/oraclecloud.go +++ b/providers/dns/oraclecloud/oraclecloud.go @@ -12,6 +12,7 @@ import ( "github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/platform/config/env" "github.com/go-acme/lego/v4/providers/dns/internal/clientdebug" + "github.com/go-acme/lego/v4/providers/dns/internal/ptr" "github.com/nrdcg/oci-go-sdk/common/v1065" "github.com/nrdcg/oci-go-sdk/common/v1065/auth" "github.com/nrdcg/oci-go-sdk/dns/v1065" @@ -21,7 +22,8 @@ import ( const ( envNamespace = "OCI_" - EnvAuthType = envNamespace + "AUTH_TYPE" + EnvAuthType = envNamespace + "AUTH_TYPE" + EnvExtendedZoneDetection = envNamespace + "EXTENDED_ZONE_DETECTION" EnvCompartmentOCID = envNamespace + "COMPARTMENT_OCID" EnvRegion = envNamespace + "REGION" @@ -60,8 +62,9 @@ var _ challenge.ProviderTimeout = (*DNSProvider)(nil) // Config is used to configure the creation of the DNSProvider. type Config struct { - CompartmentID string - OCIConfigProvider common.ConfigurationProvider + CompartmentID string + OCIConfigProvider common.ConfigurationProvider + ExtendedZoneDetection bool PropagationTimeout time.Duration PollingInterval time.Duration @@ -90,6 +93,7 @@ type DNSProvider struct { // NewDNSProvider returns a DNSProvider instance configured for OracleCloud. func NewDNSProvider() (*DNSProvider, error) { config := NewDefaultConfig() + config.ExtendedZoneDetection = env.GetOrDefaultBool(EnvExtendedZoneDetection, false) switch env.GetOrFile(EnvAuthType) { case string(common.InstancePrincipal): @@ -193,21 +197,28 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { info := dns01.GetChallengeInfo(domain, keyAuth) - zoneNameOrID, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + ctx := context.Background() + + authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) if err != nil { return fmt.Errorf("oraclecloud: could not find zone for domain %q: %w", domain, err) } + if d.config.ExtendedZoneDetection { + authZone, err = d.findZone(ctx, info.EffectiveFQDN, authZone) + if err != nil { + return fmt.Errorf("oraclecloud: %w", err) + } + } + // search to TXT record's hash to delete getRequest := dns.GetDomainRecordsRequest{ - ZoneNameOrId: common.String(zoneNameOrID), + ZoneNameOrId: common.String(authZone), Domain: common.String(dns01.UnFqdn(info.EffectiveFQDN)), CompartmentId: common.String(d.config.CompartmentID), Rtype: common.String("TXT"), } - ctx := context.Background() - domainRecords, err := d.client.GetDomainRecords(ctx, getRequest) if err != nil { return fmt.Errorf("oraclecloud: %w", err) @@ -236,7 +247,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { } patchRequest := dns.PatchDomainRecordsRequest{ - ZoneNameOrId: common.String(zoneNameOrID), + ZoneNameOrId: common.String(authZone), Domain: common.String(dns01.UnFqdn(info.EffectiveFQDN)), PatchDomainRecordsDetails: dns.PatchDomainRecordsDetails{ Items: []dns.RecordOperation{recordOperation}, @@ -257,3 +268,25 @@ 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 (d *DNSProvider) findZone(ctx context.Context, effectiveFQDN, requestedZone string) (string, error) { + zones, err := d.client.ListZones(ctx, dns.ListZonesRequest{ + CompartmentId: common.String(d.config.CompartmentID), + NameContains: common.String(requestedZone), + SortBy: dns.ListZonesSortByName, + Limit: ptr.Pointer[int64](100), + }) + if err != nil { + return "", err + } + + for name := range dns01.UnFqdnDomainsSeq(effectiveFQDN) { + for _, item := range zones.Items { + if ptr.Deref(item.Name) == name { + return ptr.Deref(item.Name), nil + } + } + } + + return "", fmt.Errorf("zone not found (%q/%q)", effectiveFQDN, requestedZone) +}