Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions providers/dns/oraclecloud/oraclecloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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},
Expand All @@ -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)
}
Loading