diff --git a/providers/dns/oraclecloud/oraclecloud.go b/providers/dns/oraclecloud/oraclecloud.go index 47902568c1..3177b12833 100644 --- a/providers/dns/oraclecloud/oraclecloud.go +++ b/providers/dns/oraclecloud/oraclecloud.go @@ -11,6 +11,7 @@ import ( "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/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" @@ -20,7 +21,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" @@ -59,8 +61,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 @@ -89,6 +92,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): @@ -192,21 +196,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) @@ -234,7 +245,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}, @@ -255,3 +266,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) +}