mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 05:29:51 +00:00
feat: add tencentcloud-eo dns-01 applicant
This commit is contained in:
parent
fd8ac3ae37
commit
fa63f2a838
@ -30,6 +30,7 @@ import (
|
|||||||
pPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns"
|
pPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns"
|
||||||
pRainYun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/rainyun"
|
pRainYun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/rainyun"
|
||||||
pTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud"
|
pTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud"
|
||||||
|
pTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud-eo"
|
||||||
pVercel "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/vercel"
|
pVercel "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/vercel"
|
||||||
pVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine"
|
pVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine"
|
||||||
pWestcn "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/westcn"
|
pWestcn "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/westcn"
|
||||||
@ -294,7 +295,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
|
|||||||
applicant, err := pJDCloud.NewChallengeProvider(&pJDCloud.ChallengeProviderConfig{
|
applicant, err := pJDCloud.NewChallengeProvider(&pJDCloud.ChallengeProviderConfig{
|
||||||
AccessKeyId: access.AccessKeyId,
|
AccessKeyId: access.AccessKeyId,
|
||||||
AccessKeySecret: access.AccessKeySecret,
|
AccessKeySecret: access.AccessKeySecret,
|
||||||
RegionId: maputil.GetString(options.ProviderApplyConfig, "region_id"),
|
RegionId: maputil.GetString(options.ProviderApplyConfig, "regionId"),
|
||||||
DnsPropagationTimeout: options.DnsPropagationTimeout,
|
DnsPropagationTimeout: options.DnsPropagationTimeout,
|
||||||
DnsTTL: options.DnsTTL,
|
DnsTTL: options.DnsTTL,
|
||||||
})
|
})
|
||||||
@ -410,13 +411,15 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
|
|||||||
return applicant, err
|
return applicant, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS:
|
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS, domain.ApplyDNSProviderTypeTencentCloudEO:
|
||||||
{
|
{
|
||||||
access := domain.AccessConfigForTencentCloud{}
|
access := domain.AccessConfigForTencentCloud{}
|
||||||
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
|
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
|
||||||
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch options.Provider {
|
||||||
|
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS:
|
||||||
applicant, err := pTencentCloud.NewChallengeProvider(&pTencentCloud.ChallengeProviderConfig{
|
applicant, err := pTencentCloud.NewChallengeProvider(&pTencentCloud.ChallengeProviderConfig{
|
||||||
SecretId: access.SecretId,
|
SecretId: access.SecretId,
|
||||||
SecretKey: access.SecretKey,
|
SecretKey: access.SecretKey,
|
||||||
@ -424,6 +427,20 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
|
|||||||
DnsTTL: options.DnsTTL,
|
DnsTTL: options.DnsTTL,
|
||||||
})
|
})
|
||||||
return applicant, err
|
return applicant, err
|
||||||
|
|
||||||
|
case domain.ApplyDNSProviderTypeTencentCloudEO:
|
||||||
|
applicant, err := pTencentCloudEO.NewChallengeProvider(&pTencentCloudEO.ChallengeProviderConfig{
|
||||||
|
SecretId: access.SecretId,
|
||||||
|
SecretKey: access.SecretKey,
|
||||||
|
ZoneId: maputil.GetString(options.ProviderApplyConfig, "zoneId"),
|
||||||
|
DnsPropagationTimeout: options.DnsPropagationTimeout,
|
||||||
|
DnsTTL: options.DnsTTL,
|
||||||
|
})
|
||||||
|
return applicant, err
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case domain.ApplyDNSProviderTypeVercel:
|
case domain.ApplyDNSProviderTypeVercel:
|
||||||
|
@ -101,6 +101,7 @@ const (
|
|||||||
ApplyDNSProviderTypeRainYun = ApplyDNSProviderType("rainyun")
|
ApplyDNSProviderTypeRainYun = ApplyDNSProviderType("rainyun")
|
||||||
ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType("tencentcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS]
|
ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType("tencentcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS]
|
||||||
ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType("tencentcloud-dns")
|
ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType("tencentcloud-dns")
|
||||||
|
ApplyDNSProviderTypeTencentCloudEO = ApplyDNSProviderType("tencentcloud-eo")
|
||||||
ApplyDNSProviderTypeVercel = ApplyDNSProviderType("vercel")
|
ApplyDNSProviderTypeVercel = ApplyDNSProviderType("vercel")
|
||||||
ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType("volcengine") // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS]
|
ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType("volcengine") // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS]
|
||||||
ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType("volcengine-dns")
|
ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType("volcengine-dns")
|
||||||
|
@ -106,6 +106,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if record == nil {
|
if record == nil {
|
||||||
// add new record
|
// add new record
|
||||||
resp, err := d.client.CreateRecordOpenapi(&model.CreateRecordOpenapiRequest{
|
resp, err := d.client.CreateRecordOpenapi(&model.CreateRecordOpenapiRequest{
|
||||||
|
@ -0,0 +1,207 @@
|
|||||||
|
package lego_tencentcloudeo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"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/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||||
|
teo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
envNamespace = "TENCENTCLOUDEO_"
|
||||||
|
|
||||||
|
EnvSecretID = envNamespace + "SECRET_ID"
|
||||||
|
EnvSecretKey = envNamespace + "SECRET_KEY"
|
||||||
|
EnvZoneId = envNamespace + "ZONE_ID"
|
||||||
|
|
||||||
|
EnvTTL = envNamespace + "TTL"
|
||||||
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
|
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
|
||||||
|
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
SecretID string
|
||||||
|
SecretKey string
|
||||||
|
ZoneId string
|
||||||
|
|
||||||
|
PropagationTimeout time.Duration
|
||||||
|
PollingInterval time.Duration
|
||||||
|
TTL int32
|
||||||
|
HTTPTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type DNSProvider struct {
|
||||||
|
client *teo.Client
|
||||||
|
config *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
TTL: int32(env.GetOrDefaultInt(EnvTTL, 300)),
|
||||||
|
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
|
||||||
|
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
|
||||||
|
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get(EnvSecretID, EnvSecretKey, EnvZoneId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("tencentcloud-eo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.SecretID = values[EnvSecretID]
|
||||||
|
config.SecretKey = values[EnvSecretKey]
|
||||||
|
config.ZoneId = values[EnvSecretKey]
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("tencentcloud-eo: the configuration of the DNS provider is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
credential := common.NewCredential(config.SecretID, config.SecretKey)
|
||||||
|
cpf := profile.NewClientProfile()
|
||||||
|
cpf.HttpProfile.ReqTimeout = int(math.Round(config.HTTPTimeout.Seconds()))
|
||||||
|
client, err := teo.NewClient(credential, "", cpf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{
|
||||||
|
client: client,
|
||||||
|
config: config,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
|
if err := d.addOrUpdateDNSRecord(strings.TrimRight(info.EffectiveFQDN, "."), info.Value); err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud-eo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
|
if err := d.removeDNSRecord(strings.TrimRight(info.EffectiveFQDN, ".")); err != nil {
|
||||||
|
return fmt.Errorf("tencentcloud-eo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) getDNSRecord(effectiveFQDN string) (*teo.DnsRecord, error) {
|
||||||
|
pageOffset := 0
|
||||||
|
pageLimit := 1000
|
||||||
|
for {
|
||||||
|
request := teo.NewDescribeDnsRecordsRequest()
|
||||||
|
request.ZoneId = common.StringPtr(d.config.ZoneId)
|
||||||
|
request.Offset = common.Int64Ptr(int64(pageOffset))
|
||||||
|
request.Limit = common.Int64Ptr(int64(pageLimit))
|
||||||
|
request.Filters = []*teo.AdvancedFilter{
|
||||||
|
{
|
||||||
|
Name: common.StringPtr("type"),
|
||||||
|
Values: []*string{common.StringPtr("TXT")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := d.client.DescribeDnsRecords(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.Response == nil {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
for _, record := range response.Response.DnsRecords {
|
||||||
|
if *record.Name == effectiveFQDN {
|
||||||
|
return record, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(response.Response.DnsRecords) < int(pageLimit) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
pageOffset += len(response.Response.DnsRecords)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) addOrUpdateDNSRecord(effectiveFQDN, value string) error {
|
||||||
|
record, err := d.getDNSRecord(effectiveFQDN)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if record == nil {
|
||||||
|
request := teo.NewCreateDnsRecordRequest()
|
||||||
|
request.ZoneId = common.StringPtr(d.config.ZoneId)
|
||||||
|
request.Name = common.StringPtr(effectiveFQDN)
|
||||||
|
request.Type = common.StringPtr("TXT")
|
||||||
|
request.Content = common.StringPtr(value)
|
||||||
|
request.TTL = common.Int64Ptr(int64(d.config.TTL))
|
||||||
|
_, err := d.client.CreateDnsRecord(request)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
record.Content = common.StringPtr(value)
|
||||||
|
request := teo.NewModifyDnsRecordsRequest()
|
||||||
|
request.ZoneId = common.StringPtr(d.config.ZoneId)
|
||||||
|
request.DnsRecords = []*teo.DnsRecord{record}
|
||||||
|
if _, err := d.client.ModifyDnsRecords(request); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if *record.Status == "disable" {
|
||||||
|
request := teo.NewModifyDnsRecordsStatusRequest()
|
||||||
|
request.ZoneId = common.StringPtr(d.config.ZoneId)
|
||||||
|
request.RecordsToEnable = []*string{record.RecordId}
|
||||||
|
if _, err = d.client.ModifyDnsRecordsStatus(request); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) removeDNSRecord(effectiveFQDN string) error {
|
||||||
|
record, err := d.getDNSRecord(effectiveFQDN)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if record == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
request := teo.NewDeleteDnsRecordsRequest()
|
||||||
|
request.ZoneId = common.StringPtr(d.config.ZoneId)
|
||||||
|
request.RecordIds = []*string{record.RecordId}
|
||||||
|
_, err = d.client.DeleteDnsRecords(request)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package tencentcloudeo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/challenge"
|
||||||
|
|
||||||
|
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud-eo/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChallengeProviderConfig struct {
|
||||||
|
SecretId string `json:"secretId"`
|
||||||
|
SecretKey string `json:"secretKey"`
|
||||||
|
ZoneId string `json:"zoneId"`
|
||||||
|
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
|
||||||
|
DnsTTL int32 `json:"dnsTTL,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
|
||||||
|
if config == nil {
|
||||||
|
panic("config is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
providerConfig := internal.NewDefaultConfig()
|
||||||
|
providerConfig.SecretID = config.SecretId
|
||||||
|
providerConfig.SecretKey = config.SecretKey
|
||||||
|
providerConfig.ZoneId = config.ZoneId
|
||||||
|
if config.DnsPropagationTimeout != 0 {
|
||||||
|
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
|
||||||
|
}
|
||||||
|
if config.DnsTTL != 0 {
|
||||||
|
providerConfig.TTL = config.DnsTTL
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := internal.NewDNSProviderConfig(providerConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
@ -45,7 +45,7 @@ func (n *applyNode) Process(ctx context.Context) error {
|
|||||||
n.logger.Info(fmt.Sprintf("skip this application, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("skip this application, because %s", skipReason))
|
||||||
return nil
|
return nil
|
||||||
} else if skipReason != "" {
|
} else if skipReason != "" {
|
||||||
n.logger.Info(fmt.Sprintf("continue to apply, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("re-apply, because %s", skipReason))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化申请器
|
// 初始化申请器
|
||||||
|
@ -58,7 +58,7 @@ func (n *deployNode) Process(ctx context.Context) error {
|
|||||||
n.logger.Info(fmt.Sprintf("skip this deployment, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("skip this deployment, because %s", skipReason))
|
||||||
return nil
|
return nil
|
||||||
} else if skipReason != "" {
|
} else if skipReason != "" {
|
||||||
n.logger.Info(fmt.Sprintf("continue to deploy, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("re-deploy, because %s", skipReason))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func (n *uploadNode) Process(ctx context.Context) error {
|
|||||||
n.logger.Info(fmt.Sprintf("skip this upload, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("skip this upload, because %s", skipReason))
|
||||||
return nil
|
return nil
|
||||||
} else if skipReason != "" {
|
} else if skipReason != "" {
|
||||||
n.logger.Info(fmt.Sprintf("continue to upload, because %s", skipReason))
|
n.logger.Info(fmt.Sprintf("re-upload, because %s", skipReason))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成证书实体
|
// 生成证书实体
|
||||||
|
@ -36,6 +36,7 @@ import { validDomainName, validIPv4Address, validIPv6Address } from "@/utils/val
|
|||||||
import ApplyNodeConfigFormAWSRoute53Config from "./ApplyNodeConfigFormAWSRoute53Config";
|
import ApplyNodeConfigFormAWSRoute53Config from "./ApplyNodeConfigFormAWSRoute53Config";
|
||||||
import ApplyNodeConfigFormHuaweiCloudDNSConfig from "./ApplyNodeConfigFormHuaweiCloudDNSConfig";
|
import ApplyNodeConfigFormHuaweiCloudDNSConfig from "./ApplyNodeConfigFormHuaweiCloudDNSConfig";
|
||||||
import ApplyNodeConfigFormJDCloudDNSConfig from "./ApplyNodeConfigFormJDCloudDNSConfig";
|
import ApplyNodeConfigFormJDCloudDNSConfig from "./ApplyNodeConfigFormJDCloudDNSConfig";
|
||||||
|
import ApplyNodeConfigFormTencentCloudEOConfig from "./ApplyNodeConfigFormTencentCloudEOConfig";
|
||||||
|
|
||||||
type ApplyNodeConfigFormFieldValues = Partial<WorkflowNodeConfigForApply>;
|
type ApplyNodeConfigFormFieldValues = Partial<WorkflowNodeConfigForApply>;
|
||||||
|
|
||||||
@ -125,6 +126,19 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
|||||||
const fieldDomains = Form.useWatch<string>("domains", formInst);
|
const fieldDomains = Form.useWatch<string>("domains", formInst);
|
||||||
const fieldNameservers = Form.useWatch<string>("nameservers", formInst);
|
const fieldNameservers = Form.useWatch<string>("nameservers", formInst);
|
||||||
|
|
||||||
|
const [showProvider, setShowProvider] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
// 通常情况下每个授权信息只对应一个 DNS 提供商,此时无需显示 DNS 提供商字段;
|
||||||
|
// 如果对应多个(如 AWS 的 Route53、Lightsail,腾讯云的 DNS、EdgeOne 等),则显示。
|
||||||
|
if (fieldProviderAccessId) {
|
||||||
|
const access = accesses.find((e) => e.id === fieldProviderAccessId);
|
||||||
|
const providers = Array.from(applyDNSProvidersMap.values()).filter((e) => e.provider === access?.provider);
|
||||||
|
setShowProvider(providers.length > 1);
|
||||||
|
} else {
|
||||||
|
setShowProvider(false);
|
||||||
|
}
|
||||||
|
}, [accesses, fieldProviderAccessId]);
|
||||||
|
|
||||||
const [nestedFormInst] = Form.useForm();
|
const [nestedFormInst] = Form.useForm();
|
||||||
const nestedFormName = useAntdFormName({ form: nestedFormInst, name: "workflowNodeApplyConfigFormProviderConfigForm" });
|
const nestedFormName = useAntdFormName({ form: nestedFormInst, name: "workflowNodeApplyConfigFormProviderConfigForm" });
|
||||||
const nestedFormEl = useMemo(() => {
|
const nestedFormEl = useMemo(() => {
|
||||||
@ -149,12 +163,15 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
|||||||
case APPLY_DNS_PROVIDERS.JDCLOUD:
|
case APPLY_DNS_PROVIDERS.JDCLOUD:
|
||||||
case APPLY_DNS_PROVIDERS.JDCLOUD_DNS:
|
case APPLY_DNS_PROVIDERS.JDCLOUD_DNS:
|
||||||
return <ApplyNodeConfigFormJDCloudDNSConfig {...nestedFormProps} />;
|
return <ApplyNodeConfigFormJDCloudDNSConfig {...nestedFormProps} />;
|
||||||
|
case APPLY_DNS_PROVIDERS.TENCENTCLOUD_EO:
|
||||||
|
return <ApplyNodeConfigFormTencentCloudEOConfig {...nestedFormProps} />;
|
||||||
}
|
}
|
||||||
}, [disabled, initialValues?.providerConfig, fieldProvider, nestedFormInst, nestedFormName]);
|
}, [disabled, initialValues?.providerConfig, fieldProvider, nestedFormInst, nestedFormName]);
|
||||||
|
|
||||||
const handleProviderSelect = (value: string) => {
|
const handleProviderSelect = (value: string) => {
|
||||||
if (fieldProvider === value) return;
|
if (fieldProvider === value) return;
|
||||||
|
|
||||||
|
// 切换 DNS 提供商时联动授权信息
|
||||||
if (initialValues?.provider === value) {
|
if (initialValues?.provider === value) {
|
||||||
formInst.setFieldValue("providerAccessId", initialValues?.providerAccessId);
|
formInst.setFieldValue("providerAccessId", initialValues?.providerAccessId);
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
onValuesChange?.(formInst.getFieldsValue(true));
|
||||||
@ -169,10 +186,13 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
|||||||
const handleProviderAccessSelect = (value: string) => {
|
const handleProviderAccessSelect = (value: string) => {
|
||||||
if (fieldProviderAccessId === value) return;
|
if (fieldProviderAccessId === value) return;
|
||||||
|
|
||||||
// DNS 提供商和授权提供商目前一一对应,因此切换授权时,自动切换到相应提供商
|
// 切换授权信息时联动 DNS 提供商
|
||||||
const access = accesses.find((access) => access.id === value);
|
const access = accesses.find((access) => access.id === value);
|
||||||
formInst.setFieldValue("provider", Array.from(applyDNSProvidersMap.values()).find((provider) => provider.provider === access?.provider)?.type);
|
const provider = Array.from(applyDNSProvidersMap.values()).find((provider) => provider.provider === access?.provider);
|
||||||
|
if (fieldProvider !== provider?.type) {
|
||||||
|
formInst.setFieldValue("provider", provider?.type);
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
onValuesChange?.(formInst.getFieldsValue(true));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFormProviderChange = (name: string) => {
|
const handleFormProviderChange = (name: string) => {
|
||||||
@ -252,10 +272,16 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="provider" label={t("workflow_node.apply.form.provider.label")} hidden rules={[formRule]}>
|
<Form.Item name="provider" label={t("workflow_node.apply.form.provider.label")} hidden={!showProvider} rules={[formRule]}>
|
||||||
<ApplyDNSProviderSelect
|
<ApplyDNSProviderSelect
|
||||||
allowClear
|
disabled={!showProvider}
|
||||||
disabled
|
filter={(record) => {
|
||||||
|
if (fieldProviderAccessId) {
|
||||||
|
return accesses.find((e) => e.id === fieldProviderAccessId)?.provider === record.provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}}
|
||||||
placeholder={t("workflow_node.apply.form.provider.placeholder")}
|
placeholder={t("workflow_node.apply.form.provider.placeholder")}
|
||||||
showSearch
|
showSearch
|
||||||
onSelect={handleProviderSelect}
|
onSelect={handleProviderSelect}
|
||||||
@ -294,11 +320,11 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
|||||||
</label>
|
</label>
|
||||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||||
<AccessSelect
|
<AccessSelect
|
||||||
placeholder={t("workflow_node.apply.form.provider_access.placeholder")}
|
|
||||||
filter={(record) => {
|
filter={(record) => {
|
||||||
const provider = accessProvidersMap.get(record.provider);
|
const provider = accessProvidersMap.get(record.provider);
|
||||||
return !!provider?.usages?.includes(ACCESS_USAGES.APPLY);
|
return !!provider?.usages?.includes(ACCESS_USAGES.APPLY);
|
||||||
}}
|
}}
|
||||||
|
placeholder={t("workflow_node.apply.form.provider_access.placeholder")}
|
||||||
onChange={handleProviderAccessSelect}
|
onChange={handleProviderAccessSelect}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Form, type FormInstance, Input } from "antd";
|
||||||
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
type ApplyNodeConfigFormTencentCloudEOConfigFieldValues = Nullish<{
|
||||||
|
zoneId: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type ApplyNodeConfigFormTencentCloudEOConfigProps = {
|
||||||
|
form: FormInstance;
|
||||||
|
formName: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
initialValues?: ApplyNodeConfigFormTencentCloudEOConfigFieldValues;
|
||||||
|
onValuesChange?: (values: ApplyNodeConfigFormTencentCloudEOConfigFieldValues) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const initFormModel = (): ApplyNodeConfigFormTencentCloudEOConfigFieldValues => {
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
const ApplyNodeConfigFormTencentCloudEOConfig = ({
|
||||||
|
form: formInst,
|
||||||
|
formName,
|
||||||
|
disabled,
|
||||||
|
initialValues,
|
||||||
|
onValuesChange,
|
||||||
|
}: ApplyNodeConfigFormTencentCloudEOConfigProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const formSchema = z.object({
|
||||||
|
zoneId: z
|
||||||
|
.string({ message: t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder") })
|
||||||
|
.nonempty(t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder"))
|
||||||
|
.trim(),
|
||||||
|
});
|
||||||
|
const formRule = createSchemaFieldRule(formSchema);
|
||||||
|
|
||||||
|
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||||
|
onValuesChange?.(values);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
form={formInst}
|
||||||
|
disabled={disabled}
|
||||||
|
initialValues={initialValues ?? initFormModel()}
|
||||||
|
layout="vertical"
|
||||||
|
name={formName}
|
||||||
|
onValuesChange={handleFormChange}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name="zoneId"
|
||||||
|
label={t("workflow_node.apply.form.tencentcloud_eo_zone_id.label")}
|
||||||
|
rules={[formRule]}
|
||||||
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.tencentcloud_eo_zone_id.tooltip") }}></span>}
|
||||||
|
>
|
||||||
|
<Input placeholder={t("workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder")} />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ApplyNodeConfigFormTencentCloudEOConfig;
|
@ -165,6 +165,7 @@ export const APPLY_DNS_PROVIDERS = Object.freeze({
|
|||||||
RAINYUN: `${ACCESS_PROVIDERS.RAINYUN}`,
|
RAINYUN: `${ACCESS_PROVIDERS.RAINYUN}`,
|
||||||
TENCENTCLOUD: `${ACCESS_PROVIDERS.TENCENTCLOUD}`, // 兼容旧值,等同于 `TENCENTCLOUD_DNS`
|
TENCENTCLOUD: `${ACCESS_PROVIDERS.TENCENTCLOUD}`, // 兼容旧值,等同于 `TENCENTCLOUD_DNS`
|
||||||
TENCENTCLOUD_DNS: `${ACCESS_PROVIDERS.TENCENTCLOUD}-dns`,
|
TENCENTCLOUD_DNS: `${ACCESS_PROVIDERS.TENCENTCLOUD}-dns`,
|
||||||
|
TENCENTCLOUD_EO: `${ACCESS_PROVIDERS.TENCENTCLOUD}-eo`,
|
||||||
VERCEL: `${ACCESS_PROVIDERS.VERCEL}`,
|
VERCEL: `${ACCESS_PROVIDERS.VERCEL}`,
|
||||||
VOLCENGINE: `${ACCESS_PROVIDERS.VOLCENGINE}`, // 兼容旧值,等同于 `VOLCENGINE_DNS`
|
VOLCENGINE: `${ACCESS_PROVIDERS.VOLCENGINE}`, // 兼容旧值,等同于 `VOLCENGINE_DNS`
|
||||||
VOLCENGINE_DNS: `${ACCESS_PROVIDERS.VOLCENGINE}-dns`,
|
VOLCENGINE_DNS: `${ACCESS_PROVIDERS.VOLCENGINE}-dns`,
|
||||||
@ -188,6 +189,7 @@ export const applyDNSProvidersMap: Map<ApplyDNSProvider["type"] | string, ApplyD
|
|||||||
[
|
[
|
||||||
[APPLY_DNS_PROVIDERS.ALIYUN_DNS, "provider.aliyun.dns"],
|
[APPLY_DNS_PROVIDERS.ALIYUN_DNS, "provider.aliyun.dns"],
|
||||||
[APPLY_DNS_PROVIDERS.TENCENTCLOUD_DNS, "provider.tencentcloud.dns"],
|
[APPLY_DNS_PROVIDERS.TENCENTCLOUD_DNS, "provider.tencentcloud.dns"],
|
||||||
|
[APPLY_DNS_PROVIDERS.TENCENTCLOUD_EO, "provider.tencentcloud.eo"],
|
||||||
[APPLY_DNS_PROVIDERS.BAIDUCLOUD_DNS, "provider.baiducloud.dns"],
|
[APPLY_DNS_PROVIDERS.BAIDUCLOUD_DNS, "provider.baiducloud.dns"],
|
||||||
[APPLY_DNS_PROVIDERS.HUAWEICLOUD_DNS, "provider.huaweicloud.dns"],
|
[APPLY_DNS_PROVIDERS.HUAWEICLOUD_DNS, "provider.huaweicloud.dns"],
|
||||||
[APPLY_DNS_PROVIDERS.VOLCENGINE_DNS, "provider.volcengine.dns"],
|
[APPLY_DNS_PROVIDERS.VOLCENGINE_DNS, "provider.volcengine.dns"],
|
||||||
@ -208,7 +210,7 @@ export const applyDNSProvidersMap: Map<ApplyDNSProvider["type"] | string, ApplyD
|
|||||||
[APPLY_DNS_PROVIDERS.NS1, "provider.ns1"],
|
[APPLY_DNS_PROVIDERS.NS1, "provider.ns1"],
|
||||||
[APPLY_DNS_PROVIDERS.PORKBUN, "provider.porkbun"],
|
[APPLY_DNS_PROVIDERS.PORKBUN, "provider.porkbun"],
|
||||||
[APPLY_DNS_PROVIDERS.VERCEL, "provider.vercel"],
|
[APPLY_DNS_PROVIDERS.VERCEL, "provider.vercel"],
|
||||||
[APPLY_DNS_PROVIDERS.CMCCCLOUD, "provider.cmcc"],
|
[APPLY_DNS_PROVIDERS.CMCCCLOUD, "provider.cmcccloud"],
|
||||||
[APPLY_DNS_PROVIDERS.RAINYUN, "provider.rainyun"],
|
[APPLY_DNS_PROVIDERS.RAINYUN, "provider.rainyun"],
|
||||||
[APPLY_DNS_PROVIDERS.WESTCN, "provider.westcn"],
|
[APPLY_DNS_PROVIDERS.WESTCN, "provider.westcn"],
|
||||||
[APPLY_DNS_PROVIDERS.POWERDNS, "provider.powerdns"],
|
[APPLY_DNS_PROVIDERS.POWERDNS, "provider.powerdns"],
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
"workflow_node.apply.form.jdcloud_dns_region_id.label": "JD Cloud DNS region ID",
|
"workflow_node.apply.form.jdcloud_dns_region_id.label": "JD Cloud DNS region ID",
|
||||||
"workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "Please enter JD Cloud DNS region ID (e.g. cn-north-1)",
|
"workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "Please enter JD Cloud DNS region ID (e.g. cn-north-1)",
|
||||||
"workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/common-declaration/api/introduction\" target=\"_blank\">https://docs.jdcloud.com/en/common-declaration/api/introduction</a>",
|
"workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/common-declaration/api/introduction\" target=\"_blank\">https://docs.jdcloud.com/en/common-declaration/api/introduction</a>",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.label": "Tencent Cloud EdgeOne zone ID",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder": "Please enter Tencent Cloud EdgeOne zone ID",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.tooltip": "For more information, see <a href=\"https://console.tencentcloud.com/edgeone\" target=\"_blank\">https://console.tencentcloud.com/edgeone</a>",
|
||||||
"workflow_node.apply.form.advanced_config.label": "Advanced settings",
|
"workflow_node.apply.form.advanced_config.label": "Advanced settings",
|
||||||
"workflow_node.apply.form.key_algorithm.label": "Certificate key algorithm",
|
"workflow_node.apply.form.key_algorithm.label": "Certificate key algorithm",
|
||||||
"workflow_node.apply.form.key_algorithm.placeholder": "Please select certificate key algorithm",
|
"workflow_node.apply.form.key_algorithm.placeholder": "Please select certificate key algorithm",
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
"workflow_node.apply.form.jdcloud_dns_region_id.label": "京东云 DNS 服务地域 ID",
|
"workflow_node.apply.form.jdcloud_dns_region_id.label": "京东云 DNS 服务地域 ID",
|
||||||
"workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "请输入京东云 DNS 服务地域 ID(例如:cn-north-1)",
|
"workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "请输入京东云 DNS 服务地域 ID(例如:cn-north-1)",
|
||||||
"workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/common-declaration/api/introduction\" target=\"_blank\">https://docs.jdcloud.com/cn/common-declaration/api/introduction</a>",
|
"workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/common-declaration/api/introduction\" target=\"_blank\">https://docs.jdcloud.com/cn/common-declaration/api/introduction</a>",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.placeholder": "请输入腾讯云 EdgeOne 站点 ID",
|
||||||
|
"workflow_node.apply.form.tencentcloud_eo_zone_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
|
||||||
"workflow_node.apply.form.advanced_config.label": "高级设置",
|
"workflow_node.apply.form.advanced_config.label": "高级设置",
|
||||||
"workflow_node.apply.form.key_algorithm.label": "数字证书算法",
|
"workflow_node.apply.form.key_algorithm.label": "数字证书算法",
|
||||||
"workflow_node.apply.form.key_algorithm.placeholder": "请选择数字证书算法",
|
"workflow_node.apply.form.key_algorithm.placeholder": "请选择数字证书算法",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user