wrapper.go raw

   1  package tencentcloud
   2  
   3  import (
   4  	"context"
   5  	"errors"
   6  	"fmt"
   7  
   8  	"github.com/go-acme/lego/v4/challenge/dns01"
   9  	dnspod "github.com/go-acme/tencentclouddnspod/v20210323"
  10  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
  11  	errorsdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
  12  	"golang.org/x/net/idna"
  13  )
  14  
  15  func (d *DNSProvider) getHostedZone(ctx context.Context, domain string) (*dnspod.DomainListItem, error) {
  16  	request := dnspod.NewDescribeDomainListRequest()
  17  
  18  	var domains []*dnspod.DomainListItem
  19  
  20  	for {
  21  		response, err := dnspod.DescribeDomainListWithContext(ctx, d.client, request)
  22  		if err != nil {
  23  			return nil, fmt.Errorf("API call failed: %w", err)
  24  		}
  25  
  26  		domains = append(domains, response.Response.DomainList...)
  27  
  28  		if uint64(len(domains)) >= *response.Response.DomainCountInfo.AllTotal {
  29  			break
  30  		}
  31  
  32  		request.Offset = common.Int64Ptr(int64(len(domains)))
  33  	}
  34  
  35  	authZone, err := dns01.FindZoneByFqdn(domain)
  36  	if err != nil {
  37  		return nil, fmt.Errorf("could not find zone: %w", err)
  38  	}
  39  
  40  	var hostedZone *dnspod.DomainListItem
  41  
  42  	for _, zone := range domains {
  43  		unfqdn := dns01.UnFqdn(authZone)
  44  		if *zone.Name == unfqdn || *zone.Punycode == unfqdn {
  45  			hostedZone = zone
  46  		}
  47  	}
  48  
  49  	if hostedZone == nil {
  50  		return nil, fmt.Errorf("zone %s not found in dnspod for domain %s", authZone, domain)
  51  	}
  52  
  53  	return hostedZone, nil
  54  }
  55  
  56  func (d *DNSProvider) findTxtRecords(ctx context.Context, zone *dnspod.DomainListItem, fqdn string) ([]*dnspod.RecordListItem, error) {
  57  	recordName, err := extractRecordName(fqdn, *zone.Name)
  58  	if err != nil {
  59  		return nil, err
  60  	}
  61  
  62  	request := dnspod.NewDescribeRecordListRequest()
  63  	request.Domain = zone.Name
  64  	request.DomainId = zone.DomainId
  65  	request.Subdomain = common.StringPtr(recordName)
  66  	request.RecordType = common.StringPtr("TXT")
  67  	request.RecordLine = common.StringPtr("默认")
  68  
  69  	response, err := dnspod.DescribeRecordListWithContext(ctx, d.client, request)
  70  	if err != nil {
  71  		var sdkError *errorsdk.TencentCloudSDKError
  72  		if errors.As(err, &sdkError) {
  73  			if sdkError.Code == dnspod.RESOURCENOTFOUND_NODATAOFRECORD {
  74  				return nil, nil
  75  			}
  76  		}
  77  
  78  		return nil, err
  79  	}
  80  
  81  	return response.Response.RecordList, nil
  82  }
  83  
  84  func extractRecordName(fqdn, zone string) (string, error) {
  85  	asciiDomain, err := idna.ToASCII(zone)
  86  	if err != nil {
  87  		return "", fmt.Errorf("fail to convert punycode: %w", err)
  88  	}
  89  
  90  	subDomain, err := dns01.ExtractSubDomain(fqdn, asciiDomain)
  91  	if err != nil {
  92  		return "", err
  93  	}
  94  
  95  	return subDomain, nil
  96  }
  97