Skip to content

NEW PROVIDER: Tencent Cloud DNS (TENCENTDNS/DNSPOD) provider and registrar#4237

Open
cylonchau wants to merge 3 commits into
DNSControl:mainfrom
cylonchau:feat/tencentdns
Open

NEW PROVIDER: Tencent Cloud DNS (TENCENTDNS/DNSPOD) provider and registrar#4237
cylonchau wants to merge 3 commits into
DNSControl:mainfrom
cylonchau:feat/tencentdns

Conversation

@cylonchau
Copy link
Copy Markdown

@cylonchau cylonchau commented May 9, 2026

Summary

Hey! This PR adds support for Tencent Cloud DNS (tencentdns also known as dnspod)for DNS hosting and Tencent Domain for registrar/nameserver management.

Tencent Cloud is one of the major cloud providers in China, and DNSPod is widely used by Chinese users and companies. I also rely on DNSControl in my own projects to manage domain records for real business services, so having native Tencent Cloud support would make DNSControl much more useful for users who need to manage domains across Cloudflare, Tencent Cloud, Aliyun, and other providers in one workflow.

This provider supports both DNS and registrar use cases:

  • DNS record management for common record types: A, AAAA, CNAME, MX, NS, TXT, SRV, and CAA
  • Registrar-side nameserver delegation for domains registered with Tencent Cloud
  • ALIAS support for Tencent DNSPod's apex CNAME behavior while keeping DNSControl validation happy
  • Zone provisioning through EnsureZoneExists
  • Provider-specific validation through RecordAuditor
  • Automatic handling of DNSPod free-tier TTL limits, where the minimum TTL is 600 seconds
  • Other own files test files and documents

The implementation uses Tencent Cloud's official Go SDK with the modern API 3.0 endpoints:

  • DNSPod API: v20210323 (Tencent still continue maintain this sdk, date only a lable, this version is latest)
  • Domain API: v20180808 (Tencent still continue maintain this sdk, date only a lable, this version is latest)

Fixes #4171

Test record

$ go mod tidy
$ go build -o dnscontrol .
$ go test -v ./providers/tencentdns/...
=== RUN   TestNativeToRecord
=== RUN   TestNativeToRecord/Basic_A_record
=== RUN   TestNativeToRecord/CNAME_record
=== RUN   TestNativeToRecord/MX_record
--- PASS: TestNativeToRecord (0.00s)
    --- PASS: TestNativeToRecord/Basic_A_record (0.00s)
    --- PASS: TestNativeToRecord/CNAME_record (0.00s)
    --- PASS: TestNativeToRecord/MX_record (0.00s)
=== RUN   TestRecordToCreateRequest
--- PASS: TestRecordToCreateRequest (0.00s)
=== RUN   TestRecordToCreateRequest_MX
--- PASS: TestRecordToCreateRequest_MX (0.00s)
=== RUN   TestNewTencentDNS
--- PASS: TestNewTencentDNS (0.00s)
=== RUN   TestNewTencentDNS_MissingCreds
--- PASS: TestNewTencentDNS_MissingCreds (0.00s)
PASS
ok      github.com/DNSControl/dnscontrol/v4/providers/tencentdns        (cached) 

add record test

$ dnscontrol % ./dnscontrol push
INFO: In dnsconfig.js NewRegistrar("tencentdns", "TENCENTDNS") can be simplified to NewRegistrar("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
INFO: In dnsconfig.js NewDnsProvider("tencentdns", "TENCENTDNS") can be simplified to NewDnsProvider("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
CONCURRENTLY checking for 0 zone(s)
SERIALLY checking for 1 zone(s)
Serially checking for zone: "oomkill.com"
CONCURRENTLY gathering records of 0 zone(s)
SERIALLY gathering records of 1 zone(s)
Serially Gathering: "oomkill.com"
******************** Domain: oomkill.com
9 corrections (tencentdns)
INFO#1: 5 records not being deleted because of NO_PURGE:
    CNAME("www.oomkill.com.", "www.oomkill.com.cdn.dnsv1.com."),
    CNAME("k8s-origin.web.oomkill.com.", "lb-fhodvg4u-64alogb8n2k1vt79.clb.sg-tencentclb.com."),
    CNAME("oomkill.com.", "oomkill.com.cdn.dnsv1.com."),
    TXT("_dnsauth.oomkill.com.", "202605010943194753vkhn1adx9mtpvjc4blyg48wfpzs0b15zy3sf7oc9qrxqq2"),
    TXT("_dnsauth.oomkill.com.", "202605010944363rbshgzl45kt0jwze9ydfasfzgijk2jarurfzm57mnigmz63sj"),
#1: + CREATE oomkill.com NS a.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=b88d8aa1-1061-47f0-9fc6-690d76e2488f
#2: + CREATE oomkill.com NS b.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=dd59d7e8-53e1-429c-a2fb-78c065abc933
#3: + CREATE oomkill.com NS c.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=98c2cd8e-392d-46ca-80a3-cb61982097f0
#4: + CREATE oomkill.com MX 10 mail.yourtestdomain.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=95e5677e-cda4-47d0-a62e-7621a67e6071
#5: + CREATE blog.oomkill.com CNAME yourtestdomain.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=5410d07a-9d4f-4fea-8475-efccd5d3149f
#6: + CREATE ksss.oomkill.com A 1.2.3.4 ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=82d30e87-041e-41d9-b605-971b53d05ef2
#7: + CREATE test.oomkill.com A 5.6.7.8 ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=7b75f910-4a2a-4847-b685-6a561202aa63
#8: + CREATE verif.oomkill.com TXT "dnscontrol-test-123" ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=64ff1cbe-3fe3-469d-bbba-417517a9f4bd
#9: Update nameservers A.DNSPOD.COM,B.DNSPOD.COM,C.DNSPOD.COM -> a.dnspod.com,b.dnspod.com,c.dnspod.com
SUCCESS!
Done. 9 corrections.
completed with errors

delete record test

$ % ./dnscontrol push       
INFO: In dnsconfig.js NewRegistrar("tencentdns", "TENCENTDNS") can be simplified to NewRegistrar("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
INFO: In dnsconfig.js NewDnsProvider("tencentdns", "TENCENTDNS") can be simplified to NewDnsProvider("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
CONCURRENTLY checking for 0 zone(s)
SERIALLY checking for 1 zone(s)
Serially checking for zone: "oomkill.com"
CONCURRENTLY gathering records of 0 zone(s)
SERIALLY gathering records of 1 zone(s)
Serially Gathering: "oomkill.com"
******************** Domain: oomkill.com
9 corrections (tencentdns)
INFO#1: 5 records not being deleted because of NO_PURGE:
    CNAME("www.oomkill.com.", "www.oomkill.com.cdn.dnsv1.com."),
    CNAME("k8s-origin.web.oomkill.com.", "lb-fhodvg4u-64alogb8n2k1vt79.clb.sg-tencentclb.com."),
    CNAME("oomkill.com.", "oomkill.com.cdn.dnsv1.com."),
    TXT("_dnsauth.oomkill.com.", "202605010943194753vkhn1adx9mtpvjc4blyg48wfpzs0b15zy3sf7oc9qrxqq2"),
    TXT("_dnsauth.oomkill.com.", "202605010944363rbshgzl45kt0jwze9ydfasfzgijk2jarurfzm57mnigmz63sj"),
#1: + CREATE oomkill.com NS a.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=04552fc0-9af2-429b-bb97-d48b56fae223
#2: + CREATE oomkill.com NS b.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=f2c383c9-4dda-4ac4-8499-9c0a2bc26456
#3: + CREATE oomkill.com NS c.dnspod.com. ttl=300
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=83aff47e-514b-4273-9e94-8fb1080333fb
#4: + CREATE oomkill.com MX 10 mail.yourtestdomain.com. ttl=600
SUCCESS!
#5: + CREATE blog.oomkill.com CNAME yourtestdomain.com. ttl=600
SUCCESS!
#6: + CREATE ksss.oomkill.com A 1.2.3.4 ttl=600
SUCCESS!
#7: + CREATE test.oomkill.com A 5.6.7.8 ttl=600
SUCCESS!
#8: + CREATE verif.oomkill.com TXT "dnscontrol-test-123" ttl=600
SUCCESS!
#9: Update nameservers A.DNSPOD.COM,B.DNSPOD.COM,C.DNSPOD.COM -> a.dnspod.com,b.dnspod.com,c.dnspod.com
SUCCESS!
Done. 9 corrections.
completed with errors

add zone test

$ dnscontrol % ./dnscontrol preview
INFO: In dnsconfig.js NewRegistrar("tencentdns", "TENCENTDNS") can be simplified to NewRegistrar("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
INFO: In dnsconfig.js NewDnsProvider("tencentdns", "TENCENTDNS") can be simplified to NewDnsProvider("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
CONCURRENTLY checking for 0 zone(s)
SERIALLY checking for 1 zone(s)
Serially checking for zone: "oomkill.com"
******************** Domain: oomkill.com
1 correction (tencentdns)
#1: Ensuring zone "oomkill.com" exists in "tencentdns"
CONCURRENTLY gathering records of 0 zone(s)
SERIALLY gathering records of 1 zone(s)
Serially Gathering: "oomkill.com"
******************** Domain: oomkill.com
1 correction (tencentdns)
#1: + CREATE oomkill.com A 127.0.0.1 ttl=600
INFO#1: Skipping registrar "tencentdns": No nameservers declared for domain "oomkill.com". Add {no_ns: 'true'} to force
Done. 2 corrections.

$ % ./dnscontrol push   
INFO: In dnsconfig.js NewRegistrar("tencentdns", "TENCENTDNS") can be simplified to NewRegistrar("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
INFO: In dnsconfig.js NewDnsProvider("tencentdns", "TENCENTDNS") can be simplified to NewDnsProvider("tencentdns") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
CONCURRENTLY checking for 0 zone(s)
SERIALLY checking for 1 zone(s)
Serially checking for zone: "oomkill.com"
******************** Domain: oomkill.com
1 correction (tencentdns)
#1: Ensuring zone "oomkill.com" exists in "tencentdns"
SUCCESS!
CONCURRENTLY gathering records of 0 zone(s)
SERIALLY gathering records of 1 zone(s)
Serially Gathering: "oomkill.com"
******************** Domain: oomkill.com
5 corrections (tencentdns)
#1: ± MODIFY-TTL oomkill.com NS ttl=(86400->300) a.dnspod.com.
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=9aa40b9a-108e-4195-9cd5-a295b745cbc1
#2: ± MODIFY-TTL oomkill.com NS ttl=(86400->300) b.dnspod.com.
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=5d6f3be1-4243-408e-98fb-07771a104053
#3: ± MODIFY-TTL oomkill.com NS ttl=(86400->300) c.dnspod.com.
FAILURE! [TencentCloudSDKError] Code=LimitExceeded.RecordTtlLimit, Message=记录的TTL值超出了限制。, RequestId=d9695fcf-b48a-4845-ba05-2926530a4f70
#4: + CREATE oomkill.com A 127.0.0.1 ttl=600
SUCCESS!
#5: Update nameservers dns1.registrar-servers.com,dns2.registrar-servers.com -> a.dnspod.com,b.dnspod.com,c.dnspod.com
SUCCESS!
Done. 6 corrections.

cylonchau added 3 commits May 10, 2026 01:32
…registrar

Add support for Tencent Cloud DNS (encentdns/dnspod) as both DNS provider
and registrar using the official Tencent Cloud API 3.0.
Features:
- DNS Provider: Full CRUD for A, AAAA, CNAME, MX, NS, TXT, CAA, SRV records
- Registrar: Nameserver delegation management at the registry level
- Apex CNAME support: Seamlessly maps ALIAS records to Tencent's apex CNAME
- Zone management: Supports automatic zone creation (EnsureZoneExists)
- Zone listing: Supports the get-zones command for easy migration
- Incremental updates: Full support for NO_PURGE and IGNORE via diff2 engine
Technical details:
- Based on tencentcloud-sdk-go (API 3.0)
- Implements RecordAuditor to comply with DNSControl v4 requirements
- Handles free-tier limitations (TTL minimum 600s) automatically
Documentation and CI/CD configuration (GitHub Actions profiles) included.
@TomOnTime
Copy link
Copy Markdown
Collaborator

Greetings! Thank you for your patience while we migrated to the new GitHub org.

Now that the migration is complete, please rebase. Thank you.

@cafferata cafferata added the provider-TENCENTDNS Tencent Cloud DNS provider label May 13, 2026
@cylonchau
Copy link
Copy Markdown
Author

Greetings! Thank you for your patience while we migrated to the new GitHub org.

Now that the migration is complete, please rebase. Thank you.

Hi, thanks for the reply.

Could you please confirm which branch I should rebase onto? Should I rebase against the latest main branch or is there another target branch I should use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

provider-request provider-TENCENTDNS Tencent Cloud DNS provider

Development

Successfully merging this pull request may close these issues.

Add Tencent Cloud DNS

4 participants