forked from TrueCloudLab/lego
Add DNS Provider for Tencent Cloud (#1527)
This commit is contained in:
parent
0324783e09
commit
6907a39266
10 changed files with 489 additions and 3 deletions
|
@ -68,9 +68,9 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns).
|
||||||
| [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [reg.ru](https://go-acme.github.io/lego/dns/regru/) | [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) |
|
| [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [reg.ru](https://go-acme.github.io/lego/dns/regru/) | [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) |
|
||||||
| [RimuHosting](https://go-acme.github.io/lego/dns/rimuhosting/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) | [Selectel](https://go-acme.github.io/lego/dns/selectel/) |
|
| [RimuHosting](https://go-acme.github.io/lego/dns/rimuhosting/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) | [Selectel](https://go-acme.github.io/lego/dns/selectel/) |
|
||||||
| [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Simply.com](https://go-acme.github.io/lego/dns/simply/) | [Sonic](https://go-acme.github.io/lego/dns/sonic/) | [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) |
|
| [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Simply.com](https://go-acme.github.io/lego/dns/simply/) | [Sonic](https://go-acme.github.io/lego/dns/sonic/) | [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) |
|
||||||
| [TransIP](https://go-acme.github.io/lego/dns/transip/) | [UKFast SafeDNS](https://go-acme.github.io/lego/dns/safedns/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) |
|
| [Tencent Cloud DNS](https://go-acme.github.io/lego/dns/tencentcloud/) | [TransIP](https://go-acme.github.io/lego/dns/transip/) | [UKFast SafeDNS](https://go-acme.github.io/lego/dns/safedns/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) |
|
||||||
| [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) | [WEDOS](https://go-acme.github.io/lego/dns/wedos/) |
|
| [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) | [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) |
|
||||||
| [Yandex](https://go-acme.github.io/lego/dns/yandex/) | [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) | |
|
| [WEDOS](https://go-acme.github.io/lego/dns/wedos/) | [Yandex](https://go-acme.github.io/lego/dns/yandex/) | [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) |
|
||||||
|
|
||||||
<!-- END DNS PROVIDERS LIST -->
|
<!-- END DNS PROVIDERS LIST -->
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ func allDNSCodes() string {
|
||||||
"simply",
|
"simply",
|
||||||
"sonic",
|
"sonic",
|
||||||
"stackpath",
|
"stackpath",
|
||||||
|
"tencentcloud",
|
||||||
"transip",
|
"transip",
|
||||||
"vegadns",
|
"vegadns",
|
||||||
"versio",
|
"versio",
|
||||||
|
@ -1997,6 +1998,28 @@ func displayDNSHelp(name string) error {
|
||||||
ew.writeln()
|
ew.writeln()
|
||||||
ew.writeln(`More information: https://go-acme.github.io/lego/dns/stackpath`)
|
ew.writeln(`More information: https://go-acme.github.io/lego/dns/stackpath`)
|
||||||
|
|
||||||
|
case "tencentcloud":
|
||||||
|
// generated from: providers/dns/tencentcloud/tencentcloud.toml
|
||||||
|
ew.writeln(`Configuration for Tencent Cloud DNS.`)
|
||||||
|
ew.writeln(`Code: 'tencentcloud'`)
|
||||||
|
ew.writeln(`Since: 'v4.6.0'`)
|
||||||
|
ew.writeln()
|
||||||
|
|
||||||
|
ew.writeln(`Credentials:`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_SECRET_ID": Access key ID`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_SECRET_KEY": Access Key secret`)
|
||||||
|
ew.writeln()
|
||||||
|
|
||||||
|
ew.writeln(`Additional Configuration:`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_HTTP_TIMEOUT": API request timeout`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_POLLING_INTERVAL": Time between DNS propagation check`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_REGION": Region`)
|
||||||
|
ew.writeln(` - "TENCENTCLOUD_TTL": The TTL of the TXT record used for the DNS challenge`)
|
||||||
|
|
||||||
|
ew.writeln()
|
||||||
|
ew.writeln(`More information: https://go-acme.github.io/lego/dns/tencentcloud`)
|
||||||
|
|
||||||
case "transip":
|
case "transip":
|
||||||
// generated from: providers/dns/transip/transip.toml
|
// generated from: providers/dns/transip/transip.toml
|
||||||
ew.writeln(`Configuration for TransIP.`)
|
ew.writeln(`Configuration for TransIP.`)
|
||||||
|
|
66
docs/content/dns/zz_gen_tencentcloud.md
Normal file
66
docs/content/dns/zz_gen_tencentcloud.md
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
title: "Tencent Cloud DNS"
|
||||||
|
date: 2019-03-03T16:39:46+01:00
|
||||||
|
draft: false
|
||||||
|
slug: tencentcloud
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
<!-- providers/dns/tencentcloud/tencentcloud.toml -->
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
|
||||||
|
Since: v4.6.0
|
||||||
|
|
||||||
|
Configuration for [Tencent Cloud DNS](https://cloud.tencent.com/product/cns).
|
||||||
|
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
- Code: `tencentcloud`
|
||||||
|
|
||||||
|
Here is an example bash command using the Tencent Cloud DNS provider:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
TENCENTCLOUD_SECRET_ID=abcdefghijklmnopqrstuvwx \
|
||||||
|
TENCENTCLOUD_SECRET_KEY=your-secret-key \
|
||||||
|
lego --email myemail@example.com --dns tencentcloud --domains my.example.org run
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Credentials
|
||||||
|
|
||||||
|
| Environment Variable Name | Description |
|
||||||
|
|-----------------------|-------------|
|
||||||
|
| `TENCENTCLOUD_SECRET_ID` | Access key ID |
|
||||||
|
| `TENCENTCLOUD_SECRET_KEY` | Access Key secret |
|
||||||
|
|
||||||
|
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
|
||||||
|
More information [here](/lego/dns/#configuration-and-credentials).
|
||||||
|
|
||||||
|
|
||||||
|
## Additional Configuration
|
||||||
|
|
||||||
|
| Environment Variable Name | Description |
|
||||||
|
|--------------------------------|-------------|
|
||||||
|
| `TENCENTCLOUD_HTTP_TIMEOUT` | API request timeout |
|
||||||
|
| `TENCENTCLOUD_POLLING_INTERVAL` | Time between DNS propagation check |
|
||||||
|
| `TENCENTCLOUD_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
|
||||||
|
| `TENCENTCLOUD_REGION` | Region |
|
||||||
|
| `TENCENTCLOUD_TTL` | The TTL of the TXT record used for the DNS challenge |
|
||||||
|
|
||||||
|
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
|
||||||
|
More information [here](/lego/dns/#configuration-and-credentials).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## More information
|
||||||
|
|
||||||
|
- [API documentation](https://cloud.tencent.com/document/product/1427/56153)
|
||||||
|
- [Go client](https://github.com/tencentcloud/tencentcloud-sdk-go)
|
||||||
|
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
<!-- providers/dns/tencentcloud/tencentcloud.toml -->
|
||||||
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
2
go.mod
2
go.mod
|
@ -49,6 +49,8 @@ require (
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f
|
||||||
github.com/softlayer/softlayer-go v1.0.3
|
github.com/softlayer/softlayer-go v1.0.3
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.287
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.287
|
||||||
github.com/transip/gotransip/v6 v6.6.1
|
github.com/transip/gotransip/v6 v6.6.1
|
||||||
github.com/urfave/cli v1.22.5
|
github.com/urfave/cli v1.22.5
|
||||||
github.com/vinyldns/go-vinyldns v0.9.16
|
github.com/vinyldns/go-vinyldns v0.9.16
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -465,6 +465,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.287 h1:ohsyW4WffPdd2JLPio2Sd0qGr93hzkawAt9vWdCFLgY=
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.287/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.287 h1:O/ycBVvdOAmwFlXm0fCtLz2WOr1EaWZQTDM/4pmVT+s=
|
||||||
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.287/go.mod h1:CuOaLxOQr477GhMWAQPYQFUJrsZbW+ZqkAgP2uHDZXg=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/transip/gotransip/v6 v6.6.1 h1:nsCU1ErZS5G0FeOpgGXc4FsWvBff9GPswSMggsC4564=
|
github.com/transip/gotransip/v6 v6.6.1 h1:nsCU1ErZS5G0FeOpgGXc4FsWvBff9GPswSMggsC4564=
|
||||||
github.com/transip/gotransip/v6 v6.6.1/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
github.com/transip/gotransip/v6 v6.6.1/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
||||||
|
|
|
@ -93,6 +93,7 @@ import (
|
||||||
"github.com/go-acme/lego/v4/providers/dns/simply"
|
"github.com/go-acme/lego/v4/providers/dns/simply"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/sonic"
|
"github.com/go-acme/lego/v4/providers/dns/sonic"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/stackpath"
|
"github.com/go-acme/lego/v4/providers/dns/stackpath"
|
||||||
|
"github.com/go-acme/lego/v4/providers/dns/tencentcloud"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/transip"
|
"github.com/go-acme/lego/v4/providers/dns/transip"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/vegadns"
|
"github.com/go-acme/lego/v4/providers/dns/vegadns"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/versio"
|
"github.com/go-acme/lego/v4/providers/dns/versio"
|
||||||
|
@ -286,6 +287,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) {
|
||||||
return sonic.NewDNSProvider()
|
return sonic.NewDNSProvider()
|
||||||
case "stackpath":
|
case "stackpath":
|
||||||
return stackpath.NewDNSProvider()
|
return stackpath.NewDNSProvider()
|
||||||
|
case "tencentcloud":
|
||||||
|
return tencentcloud.NewDNSProvider()
|
||||||
case "transip":
|
case "transip":
|
||||||
return transip.NewDNSProvider()
|
return transip.NewDNSProvider()
|
||||||
case "vegadns":
|
case "vegadns":
|
||||||
|
|
70
providers/dns/tencentcloud/client.go
Normal file
70
providers/dns/tencentcloud/client.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package tencentcloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
|
dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323"
|
||||||
|
)
|
||||||
|
|
||||||
|
type domainData struct {
|
||||||
|
domain string
|
||||||
|
subDomain string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDomainData(fqdn string) (*domainData, error) {
|
||||||
|
zone, err := dns01.FindZoneByFqdn(fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &domainData{
|
||||||
|
domain: zone,
|
||||||
|
subDomain: dns01.UnFqdn(strings.TrimSuffix(fqdn, zone)),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) createRecordData(domainData *domainData, value string) error {
|
||||||
|
request := dnspod.NewCreateRecordRequest()
|
||||||
|
request.Domain = common.StringPtr(domainData.domain)
|
||||||
|
request.SubDomain = common.StringPtr(domainData.subDomain)
|
||||||
|
request.RecordType = common.StringPtr("TXT")
|
||||||
|
request.RecordLine = common.StringPtr("默认")
|
||||||
|
request.Value = common.StringPtr(value)
|
||||||
|
request.TTL = common.Uint64Ptr(uint64(d.config.TTL))
|
||||||
|
|
||||||
|
_, err := d.client.CreateRecord(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) listRecordData(domainData *domainData) ([]*dnspod.RecordListItem, error) {
|
||||||
|
request := dnspod.NewDescribeRecordListRequest()
|
||||||
|
request.Domain = common.StringPtr(domainData.domain)
|
||||||
|
request.Subdomain = common.StringPtr(domainData.subDomain)
|
||||||
|
request.RecordType = common.StringPtr("TXT")
|
||||||
|
|
||||||
|
response, err := d.client.DescribeRecordList(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Response.RecordList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) deleteRecordData(domainData *domainData, item *dnspod.RecordListItem) error {
|
||||||
|
request := dnspod.NewDeleteRecordRequest()
|
||||||
|
request.Domain = common.StringPtr(domainData.domain)
|
||||||
|
request.RecordId = item.RecordId
|
||||||
|
|
||||||
|
_, err := d.client.DeleteRecord(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
142
providers/dns/tencentcloud/tencentcloud.go
Normal file
142
providers/dns/tencentcloud/tencentcloud.go
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
// Package tencentcloud implements a DNS provider for solving the DNS-01 challenge using Tencent Cloud DNS.
|
||||||
|
package tencentcloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
|
"github.com/go-acme/lego/v4/platform/config/env"
|
||||||
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||||
|
dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environment variables names.
|
||||||
|
const (
|
||||||
|
envNamespace = "TENCENTCLOUD_"
|
||||||
|
|
||||||
|
EnvSecretID = envNamespace + "SECRET_ID"
|
||||||
|
EnvSecretKey = envNamespace + "SECRET_KEY"
|
||||||
|
EnvRegion = envNamespace + "REGION"
|
||||||
|
|
||||||
|
EnvTTL = envNamespace + "TTL"
|
||||||
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
|
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
|
||||||
|
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is used to configure the creation of the DNSProvider.
|
||||||
|
type Config struct {
|
||||||
|
SecretID string
|
||||||
|
SecretKey string
|
||||||
|
Region string
|
||||||
|
|
||||||
|
PropagationTimeout time.Duration
|
||||||
|
PollingInterval time.Duration
|
||||||
|
TTL int
|
||||||
|
HTTPTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultConfig returns a default configuration for the DNSProvider.
|
||||||
|
func NewDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
TTL: env.GetOrDefaultInt(EnvTTL, 600),
|
||||||
|
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, dns01.DefaultPropagationTimeout),
|
||||||
|
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
|
||||||
|
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 10*time.Second),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider implements the challenge.Provider interface.
|
||||||
|
type DNSProvider struct {
|
||||||
|
config *Config
|
||||||
|
client *dnspod.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for Tencent Cloud DNS.
|
||||||
|
// Credentials must be passed in the environment variable: TENCENTCLOUD_SECRET_ID, TENCENTCLOUD_SECRET_KEY.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get(EnvSecretID, EnvSecretKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("tencentcloud: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.SecretID = values[EnvSecretID]
|
||||||
|
config.SecretKey = values[EnvSecretKey]
|
||||||
|
config.Region = env.GetOrDefaultString(EnvRegion, "")
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderConfig return a DNSProvider instance configured for Tencent Cloud DNS.
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("tencentcloud: the configuration of the DNS provider is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.SecretID == "" || config.SecretKey == "" {
|
||||||
|
return nil, errors.New("tencentcloud: credentials missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
credential := common.NewCredential(config.SecretID, config.SecretKey)
|
||||||
|
|
||||||
|
cpf := profile.NewClientProfile()
|
||||||
|
cpf.HttpProfile.Endpoint = "dnspod.tencentcloudapi.com"
|
||||||
|
|
||||||
|
client, err := dnspod.NewClient(credential, config.Region, cpf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("tencentcloud: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{config: config, client: client}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
// Adjusting here to cope with spikes in propagation times.
|
||||||
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record to fulfill the dns-01 challenge.
|
||||||
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
|
domainData, err := getDomainData(fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud: failed to get domain data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.createRecordData(domainData, value)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud: create record failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp removes the TXT record matching the specified parameters.
|
||||||
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
fqdn, _ := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
|
domainData, err := getDomainData(fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud: failed to get domain data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
records, err := d.listRecordData(domainData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud: list records failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range records {
|
||||||
|
err := d.deleteRecordData(domainData, item)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud: delete record failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
26
providers/dns/tencentcloud/tencentcloud.toml
Normal file
26
providers/dns/tencentcloud/tencentcloud.toml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Name = "Tencent Cloud DNS"
|
||||||
|
Description = ''''''
|
||||||
|
URL = "https://cloud.tencent.com/product/cns"
|
||||||
|
Code = "tencentcloud"
|
||||||
|
Since = "v4.6.0"
|
||||||
|
|
||||||
|
Example = '''
|
||||||
|
TENCENTCLOUD_SECRET_ID=abcdefghijklmnopqrstuvwx \
|
||||||
|
TENCENTCLOUD_SECRET_KEY=your-secret-key \
|
||||||
|
lego --email myemail@example.com --dns tencentcloud --domains my.example.org run
|
||||||
|
'''
|
||||||
|
|
||||||
|
[Configuration]
|
||||||
|
[Configuration.Credentials]
|
||||||
|
TENCENTCLOUD_SECRET_ID = "Access key ID"
|
||||||
|
TENCENTCLOUD_SECRET_KEY = "Access Key secret"
|
||||||
|
[Configuration.Additional]
|
||||||
|
TENCENTCLOUD_REGION = "Region"
|
||||||
|
TENCENTCLOUD_POLLING_INTERVAL = "Time between DNS propagation check"
|
||||||
|
TENCENTCLOUD_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
|
||||||
|
TENCENTCLOUD_TTL = "The TTL of the TXT record used for the DNS challenge"
|
||||||
|
TENCENTCLOUD_HTTP_TIMEOUT = "API request timeout"
|
||||||
|
|
||||||
|
[Links]
|
||||||
|
API = "https://cloud.tencent.com/document/product/1427/56153"
|
||||||
|
GoClient = "https://github.com/tencentcloud/tencentcloud-sdk-go"
|
150
providers/dns/tencentcloud/tencentcloud_test.go
Normal file
150
providers/dns/tencentcloud/tencentcloud_test.go
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
package tencentcloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/platform/tester"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
const envDomain = envNamespace + "DOMAIN"
|
||||||
|
|
||||||
|
var envTest = tester.NewEnvTest(EnvSecretID, EnvSecretKey).
|
||||||
|
WithDomain(envDomain)
|
||||||
|
|
||||||
|
func TestNewDNSProvider(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
envVars map[string]string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "success",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvSecretID: "123",
|
||||||
|
EnvSecretKey: "456",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing credentials",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvSecretID: "",
|
||||||
|
EnvSecretKey: "",
|
||||||
|
},
|
||||||
|
expected: "tencentcloud: some credentials information are missing: TENCENTCLOUD_SECRET_ID,TENCENTCLOUD_SECRET_KEY",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing access id",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvSecretID: "",
|
||||||
|
EnvSecretKey: "456",
|
||||||
|
},
|
||||||
|
expected: "tencentcloud: some credentials information are missing: TENCENTCLOUD_SECRET_ID",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing secret key",
|
||||||
|
envVars: map[string]string{
|
||||||
|
EnvSecretID: "123",
|
||||||
|
EnvSecretKey: "",
|
||||||
|
},
|
||||||
|
expected: "tencentcloud: some credentials information are missing: TENCENTCLOUD_SECRET_KEY",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
defer envTest.RestoreEnv()
|
||||||
|
envTest.ClearEnv()
|
||||||
|
|
||||||
|
envTest.Apply(test.envVars)
|
||||||
|
|
||||||
|
p, err := NewDNSProvider()
|
||||||
|
|
||||||
|
if test.expected == "" {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, p)
|
||||||
|
require.NotNil(t, p.config)
|
||||||
|
require.NotNil(t, p.client)
|
||||||
|
} else {
|
||||||
|
require.EqualError(t, err, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
secretID string
|
||||||
|
secretKey string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "success",
|
||||||
|
secretID: "123",
|
||||||
|
secretKey: "456",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing credentials",
|
||||||
|
expected: "tencentcloud: credentials missing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing secret id",
|
||||||
|
secretKey: "456",
|
||||||
|
expected: "tencentcloud: credentials missing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing secret key",
|
||||||
|
secretID: "123",
|
||||||
|
expected: "tencentcloud: credentials missing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.SecretID = test.secretID
|
||||||
|
config.SecretKey = test.secretKey
|
||||||
|
|
||||||
|
p, err := NewDNSProviderConfig(config)
|
||||||
|
|
||||||
|
if test.expected == "" {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, p)
|
||||||
|
require.NotNil(t, p.config)
|
||||||
|
require.NotNil(t, p.client)
|
||||||
|
} else {
|
||||||
|
require.EqualError(t, err, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLivePresent(t *testing.T) {
|
||||||
|
if !envTest.IsLiveTest() {
|
||||||
|
t.Skip("skipping live test")
|
||||||
|
}
|
||||||
|
|
||||||
|
envTest.RestoreEnv()
|
||||||
|
provider, err := NewDNSProvider()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = provider.Present(envTest.GetDomain(), "", "123d==")
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLiveCleanUp(t *testing.T) {
|
||||||
|
if !envTest.IsLiveTest() {
|
||||||
|
t.Skip("skipping live test")
|
||||||
|
}
|
||||||
|
|
||||||
|
envTest.RestoreEnv()
|
||||||
|
provider, err := NewDNSProvider()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
Loading…
Reference in a new issue