From 60a13aaf171963803f0d8277ca29654552f3c4b1 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sun, 19 Jan 2025 05:01:36 +0800 Subject: [PATCH] feat: support configuring dns ttl in application --- internal/applicant/applicant.go | 40 ++++---- internal/applicant/providers.go | 98 +++++++++++-------- internal/domain/workflow.go | 69 +++++++------ .../lego-providers/acmehttpreq/acmehttpreq.go | 14 +-- .../lego-providers/aliyun/aliyun.go | 14 ++- .../lego-providers/aws-route53/aws-route53.go | 18 ++-- .../lego-providers/azure-dns/azure-dns.go | 18 ++-- .../lego-providers/cloudflare/cloudflare.go | 12 ++- .../lego-providers/godaddy/godaddy.go | 14 ++- .../lego-providers/huaweicloud/huaweicloud.go | 16 +-- .../lego-providers/namedotcom/namedotcom.go | 14 ++- .../lego-providers/namesilo/namesilo.go | 12 ++- .../acme-dns-01/lego-providers/ns1/ns1.go | 12 ++- .../lego-providers/powerdns/powerdns.go | 14 ++- .../tencentcloud/tencentcloud.go | 14 ++- .../lego-providers/volcengine/volcengine.go | 14 ++- .../workflow/node/ApplyNodeConfigForm.tsx | 39 ++++++-- ui/src/domain/workflow.ts | 3 +- .../i18n/locales/en/nls.workflow.nodes.json | 12 ++- .../i18n/locales/zh/nls.workflow.nodes.json | 12 ++- 20 files changed, 282 insertions(+), 177 deletions(-) diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index b8b56c3f..b4536921 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -35,15 +35,17 @@ type Applicant interface { } type applicantOptions struct { - Domains []string - ContactEmail string - Provider domain.ApplyDNSProviderType - ProviderAccessConfig map[string]any - ProviderApplyConfig map[string]any - KeyAlgorithm string - Nameservers []string - PropagationTimeout int32 - DisableFollowCNAME bool + Domains []string + ContactEmail string + Provider domain.ApplyDNSProviderType + ProviderAccessConfig map[string]any + ProviderApplyConfig map[string]any + KeyAlgorithm string + Nameservers []string + DnsPropagationTimeout int32 + DnsTTL int32 + DisableFollowCNAME bool + SkipBeforeExpiryDays int32 } func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { @@ -65,15 +67,17 @@ func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { } options := &applicantOptions{ - Domains: slices.Filter(strings.Split(nodeConfig.Domains, ";"), func(s string) bool { return s != "" }), - ContactEmail: nodeConfig.ContactEmail, - Provider: domain.ApplyDNSProviderType(nodeConfig.Provider), - ProviderAccessConfig: accessConfig, - ProviderApplyConfig: nodeConfig.ProviderConfig, - KeyAlgorithm: nodeConfig.KeyAlgorithm, - Nameservers: slices.Filter(strings.Split(nodeConfig.Nameservers, ";"), func(s string) bool { return s != "" }), - PropagationTimeout: nodeConfig.PropagationTimeout, - DisableFollowCNAME: nodeConfig.DisableFollowCNAME, + Domains: slices.Filter(strings.Split(nodeConfig.Domains, ";"), func(s string) bool { return s != "" }), + ContactEmail: nodeConfig.ContactEmail, + Provider: domain.ApplyDNSProviderType(nodeConfig.Provider), + ProviderAccessConfig: accessConfig, + ProviderApplyConfig: nodeConfig.ProviderConfig, + KeyAlgorithm: nodeConfig.KeyAlgorithm, + Nameservers: slices.Filter(strings.Split(nodeConfig.Nameservers, ";"), func(s string) bool { return s != "" }), + DnsPropagationTimeout: nodeConfig.DnsPropagationTimeout, + DnsTTL: nodeConfig.DnsTTL, + DisableFollowCNAME: nodeConfig.DisableFollowCNAME, + SkipBeforeExpiryDays: nodeConfig.SkipBeforeExpiryDays, } applicant, err := createApplicant(options) diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go index 8e42f4f2..248af1b4 100644 --- a/internal/applicant/providers.go +++ b/internal/applicant/providers.go @@ -36,11 +36,11 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{ - Endpoint: access.Endpoint, - Mode: access.Mode, - Username: access.Username, - Password: access.Password, - PropagationTimeout: options.PropagationTimeout, + Endpoint: access.Endpoint, + Mode: access.Mode, + Username: access.Username, + Password: access.Password, + DnsPropagationTimeout: options.DnsPropagationTimeout, }) return applicant, err } @@ -53,9 +53,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{ - AccessKeyId: access.AccessKeyId, - AccessKeySecret: access.AccessKeySecret, - PropagationTimeout: options.PropagationTimeout, + AccessKeyId: access.AccessKeyId, + AccessKeySecret: access.AccessKeySecret, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -68,11 +69,12 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerAWSRoute53.NewChallengeProvider(&providerAWSRoute53.AWSRoute53ApplicantConfig{ - AccessKeyId: access.AccessKeyId, - SecretAccessKey: access.SecretAccessKey, - Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), - HostedZoneId: maps.GetValueAsString(options.ProviderApplyConfig, "hostedZoneId"), - PropagationTimeout: options.PropagationTimeout, + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), + HostedZoneId: maps.GetValueAsString(options.ProviderApplyConfig, "hostedZoneId"), + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -85,11 +87,12 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerAzureDNS.NewChallengeProvider(&providerAzureDNS.AzureDNSApplicantConfig{ - TenantId: access.TenantId, - ClientId: access.ClientId, - ClientSecret: access.ClientSecret, - CloudName: access.CloudName, - PropagationTimeout: options.PropagationTimeout, + TenantId: access.TenantId, + ClientId: access.ClientId, + ClientSecret: access.ClientSecret, + CloudName: access.CloudName, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -102,8 +105,9 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{ - DnsApiToken: access.DnsApiToken, - PropagationTimeout: options.PropagationTimeout, + DnsApiToken: access.DnsApiToken, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -116,9 +120,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{ - ApiKey: access.ApiKey, - ApiSecret: access.ApiSecret, - PropagationTimeout: options.PropagationTimeout, + ApiKey: access.ApiKey, + ApiSecret: access.ApiSecret, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -131,10 +136,11 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{ - AccessKeyId: access.AccessKeyId, - SecretAccessKey: access.SecretAccessKey, - Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), - PropagationTimeout: options.PropagationTimeout, + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -147,9 +153,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{ - Username: access.Username, - ApiToken: access.ApiToken, - PropagationTimeout: options.PropagationTimeout, + Username: access.Username, + ApiToken: access.ApiToken, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -162,8 +169,9 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{ - ApiKey: access.ApiKey, - PropagationTimeout: options.PropagationTimeout, + ApiKey: access.ApiKey, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -176,8 +184,9 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerNS1.NewChallengeProvider(&providerNS1.NS1ApplicantConfig{ - ApiKey: access.ApiKey, - PropagationTimeout: options.PropagationTimeout, + ApiKey: access.ApiKey, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -190,9 +199,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{ - ApiUrl: access.ApiUrl, - ApiKey: access.ApiKey, - PropagationTimeout: options.PropagationTimeout, + ApiUrl: access.ApiUrl, + ApiKey: access.ApiKey, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -205,9 +215,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{ - SecretId: access.SecretId, - SecretKey: access.SecretKey, - PropagationTimeout: options.PropagationTimeout, + SecretId: access.SecretId, + SecretKey: access.SecretKey, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } @@ -220,9 +231,10 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) { } applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{ - AccessKeyId: access.AccessKeyId, - SecretAccessKey: access.SecretAccessKey, - PropagationTimeout: options.PropagationTimeout, + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, }) return applicant, err } diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index e2454e36..c4249433 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -58,28 +58,31 @@ type WorkflowNode struct { } type WorkflowNodeConfigForApply struct { - Domains string `json:"domains"` - ContactEmail string `json:"contactEmail"` - Provider string `json:"provider"` - ProviderAccessId string `json:"providerAccessId"` - ProviderConfig map[string]any `json:"providerConfig"` - KeyAlgorithm string `json:"keyAlgorithm"` - Nameservers string `json:"nameservers"` - PropagationTimeout int32 `json:"propagationTimeout"` - DisableFollowCNAME bool `json:"disableFollowCNAME"` + Domains string `json:"domains"` // 域名列表,以半角逗号分隔 + ContactEmail string `json:"contactEmail"` // 联系邮箱 + Provider string `json:"provider"` // DNS 提供商 + ProviderAccessId string `json:"providerAccessId"` // DNS 提供商授权记录 ID + ProviderConfig map[string]any `json:"providerConfig"` // DNS 提供商额外配置 + KeyAlgorithm string `json:"keyAlgorithm"` // 密钥算法 + Nameservers string `json:"nameservers"` // DNS 服务器列表,以半角逗号分隔 + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout"` // DNS 传播超时时间(默认取决于提供商) + DnsTTL int32 `json:"dnsTTL"` // DNS TTL(默认取决于提供商) + DisableFollowCNAME bool `json:"disableFollowCNAME"` // 是否禁用 CNAME 跟随 + SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays"` // TODO: 证书到期前多少天前跳过续期(默认值:30) } type WorkflowNodeConfigForDeploy struct { - Certificate string `json:"certificate"` - Provider string `json:"provider"` - ProviderAccessId string `json:"providerAccessId"` - ProviderConfig map[string]any `json:"providerConfig"` + Certificate string `json:"certificate"` // 前序节点输出的证书,形如“${NodeId}#certificate” + Provider string `json:"provider"` // 主机提供商 + ProviderAccessId string `json:"providerAccessId"` // 主机提供商授权记录 ID + ProviderConfig map[string]any `json:"providerConfig"` // 主机提供商额外配置 + SkipOnLastSucceeded bool `json:"skipOnLastSucceeded"` // TODO: 上次部署成功时是否跳过 } type WorkflowNodeConfigForNotify struct { - Channel string `json:"channel"` - Subject string `json:"subject"` - Message string `json:"message"` + Channel string `json:"channel"` // 通知渠道 + Subject string `json:"subject"` // 通知主题 + Message string `json:"message"` // 通知内容 } func (n *WorkflowNode) getConfigValueAsString(key string) string { @@ -105,25 +108,33 @@ func (n *WorkflowNode) getConfigValueAsMap(key string) map[string]any { } func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply { + skipBeforeExpiryDays := n.getConfigValueAsInt32("skipBeforeExpiryDays") + if skipBeforeExpiryDays == 0 { + skipBeforeExpiryDays = 30 + } + return WorkflowNodeConfigForApply{ - Domains: n.getConfigValueAsString("domains"), - ContactEmail: n.getConfigValueAsString("contactEmail"), - Provider: n.getConfigValueAsString("provider"), - ProviderAccessId: n.getConfigValueAsString("providerAccessId"), - ProviderConfig: n.getConfigValueAsMap("providerConfig"), - KeyAlgorithm: n.getConfigValueAsString("keyAlgorithm"), - Nameservers: n.getConfigValueAsString("nameservers"), - PropagationTimeout: n.getConfigValueAsInt32("propagationTimeout"), - DisableFollowCNAME: n.getConfigValueAsBool("disableFollowCNAME"), + Domains: n.getConfigValueAsString("domains"), + ContactEmail: n.getConfigValueAsString("contactEmail"), + Provider: n.getConfigValueAsString("provider"), + ProviderAccessId: n.getConfigValueAsString("providerAccessId"), + ProviderConfig: n.getConfigValueAsMap("providerConfig"), + KeyAlgorithm: n.getConfigValueAsString("keyAlgorithm"), + Nameservers: n.getConfigValueAsString("nameservers"), + DnsPropagationTimeout: n.getConfigValueAsInt32("dnsPropagationTimeout"), + DnsTTL: n.getConfigValueAsInt32("dnsTTL"), + DisableFollowCNAME: n.getConfigValueAsBool("disableFollowCNAME"), + SkipBeforeExpiryDays: skipBeforeExpiryDays, } } func (n *WorkflowNode) GetConfigForDeploy() WorkflowNodeConfigForDeploy { return WorkflowNodeConfigForDeploy{ - Certificate: n.getConfigValueAsString("certificate"), - Provider: n.getConfigValueAsString("provider"), - ProviderAccessId: n.getConfigValueAsString("providerAccessId"), - ProviderConfig: n.getConfigValueAsMap("providerConfig"), + Certificate: n.getConfigValueAsString("certificate"), + Provider: n.getConfigValueAsString("provider"), + ProviderAccessId: n.getConfigValueAsString("providerAccessId"), + ProviderConfig: n.getConfigValueAsMap("providerConfig"), + SkipOnLastSucceeded: n.getConfigValueAsBool("skipOnLastSucceeded"), } } diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go index 4242809f..a25c13bb 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go @@ -10,11 +10,11 @@ import ( ) type ACMEHttpReqApplicantConfig struct { - Endpoint string `json:"endpoint"` - Mode string `json:"mode"` - Username string `json:"username"` - Password string `json:"password"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + Endpoint string `json:"endpoint"` + Mode string `json:"mode"` + Username string `json:"username"` + Password string `json:"password"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` } func NewChallengeProvider(config *ACMEHttpReqApplicantConfig) (challenge.Provider, error) { @@ -28,8 +28,8 @@ func NewChallengeProvider(config *ACMEHttpReqApplicantConfig) (challenge.Provide providerConfig.Mode = config.Mode providerConfig.Username = config.Username providerConfig.Password = config.Password - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second } provider, err := httpreq.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go index 687cc0ff..6f6d2d89 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go @@ -9,9 +9,10 @@ import ( ) type AliyunApplicantConfig struct { - AccessKeyId string `json:"accessKeyId"` - AccessKeySecret string `json:"accessKeySecret"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + AccessKeyId string `json:"accessKeyId"` + AccessKeySecret string `json:"accessKeySecret"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *AliyunApplicantConfig) (challenge.Provider, error) { @@ -22,8 +23,11 @@ func NewChallengeProvider(config *AliyunApplicantConfig) (challenge.Provider, er providerConfig := alidns.NewDefaultConfig() providerConfig.APIKey = config.AccessKeyId providerConfig.SecretKey = config.AccessKeySecret - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := alidns.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53/aws-route53.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53/aws-route53.go index bbd5a190..6799885f 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53/aws-route53.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53/aws-route53.go @@ -9,11 +9,12 @@ import ( ) type AWSRoute53ApplicantConfig struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - Region string `json:"region"` - HostedZoneId string `json:"hostedZoneId"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + HostedZoneId string `json:"hostedZoneId"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *AWSRoute53ApplicantConfig) (challenge.Provider, error) { @@ -26,8 +27,11 @@ func NewChallengeProvider(config *AWSRoute53ApplicantConfig) (challenge.Provider providerConfig.SecretAccessKey = config.SecretAccessKey providerConfig.Region = config.Region providerConfig.HostedZoneID = config.HostedZoneId - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := route53.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns/azure-dns.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns/azure-dns.go index 76389e8e..7cfce4a7 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns/azure-dns.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns/azure-dns.go @@ -12,11 +12,12 @@ import ( ) type AzureDNSApplicantConfig struct { - TenantId string `json:"tenantId"` - ClientId string `json:"clientId"` - ClientSecret string `json:"clientSecret"` - CloudName string `json:"cloudName,omitempty"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + TenantId string `json:"tenantId"` + ClientId string `json:"clientId"` + ClientSecret string `json:"clientSecret"` + CloudName string `json:"cloudName,omitempty"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *AzureDNSApplicantConfig) (challenge.Provider, error) { @@ -40,8 +41,11 @@ func NewChallengeProvider(config *AzureDNSApplicantConfig) (challenge.Provider, return nil, fmt.Errorf("azuredns: unknown environment %s", config.CloudName) } } - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := azuredns.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go index 0f1abc40..cea32e94 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go @@ -9,8 +9,9 @@ import ( ) type CloudflareApplicantConfig struct { - DnsApiToken string `json:"dnsApiToken"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + DnsApiToken string `json:"dnsApiToken"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *CloudflareApplicantConfig) (challenge.Provider, error) { @@ -20,8 +21,11 @@ func NewChallengeProvider(config *CloudflareApplicantConfig) (challenge.Provider providerConfig := cloudflare.NewDefaultConfig() providerConfig.AuthToken = config.DnsApiToken - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := cloudflare.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go index 1a85a28d..3a44616b 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go @@ -9,9 +9,10 @@ import ( ) type GoDaddyApplicantConfig struct { - ApiKey string `json:"apiKey"` - ApiSecret string `json:"apiSecret"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *GoDaddyApplicantConfig) (challenge.Provider, error) { @@ -22,8 +23,11 @@ func NewChallengeProvider(config *GoDaddyApplicantConfig) (challenge.Provider, e providerConfig := godaddy.NewDefaultConfig() providerConfig.APIKey = config.ApiKey providerConfig.APISecret = config.ApiSecret - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := godaddy.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go index a271f99c..cbdf2928 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go @@ -9,10 +9,11 @@ import ( ) type HuaweiCloudApplicantConfig struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - Region string `json:"region"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *HuaweiCloudApplicantConfig) (challenge.Provider, error) { @@ -30,8 +31,11 @@ func NewChallengeProvider(config *HuaweiCloudApplicantConfig) (challenge.Provide providerConfig.AccessKeyID = config.AccessKeyId providerConfig.SecretAccessKey = config.SecretAccessKey providerConfig.Region = region - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = config.DnsTTL } provider, err := hwc.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go index b5c8d3cb..c51b1a9b 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go @@ -9,9 +9,10 @@ import ( ) type NameDotComApplicantConfig struct { - Username string `json:"username"` - ApiToken string `json:"apiToken"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + Username string `json:"username"` + ApiToken string `json:"apiToken"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *NameDotComApplicantConfig) (challenge.Provider, error) { @@ -22,8 +23,11 @@ func NewChallengeProvider(config *NameDotComApplicantConfig) (challenge.Provider providerConfig := namedotcom.NewDefaultConfig() providerConfig.Username = config.Username providerConfig.APIToken = config.ApiToken - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := namedotcom.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go index f62201d6..0f1bf8ea 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go @@ -9,8 +9,9 @@ import ( ) type NameSiloApplicantConfig struct { - ApiKey string `json:"apiKey"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + ApiKey string `json:"apiKey"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *NameSiloApplicantConfig) (challenge.Provider, error) { @@ -20,8 +21,11 @@ func NewChallengeProvider(config *NameSiloApplicantConfig) (challenge.Provider, providerConfig := namesilo.NewDefaultConfig() providerConfig.APIKey = config.ApiKey - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := namesilo.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1/ns1.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1/ns1.go index 7403ecb8..efa40076 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1/ns1.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1/ns1.go @@ -9,8 +9,9 @@ import ( ) type NS1ApplicantConfig struct { - ApiKey string `json:"apiKey"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + ApiKey string `json:"apiKey"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *NS1ApplicantConfig) (challenge.Provider, error) { @@ -20,8 +21,11 @@ func NewChallengeProvider(config *NS1ApplicantConfig) (challenge.Provider, error providerConfig := ns1.NewDefaultConfig() providerConfig.APIKey = config.ApiKey - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := ns1.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go index b6512389..d5fa616c 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go @@ -10,9 +10,10 @@ import ( ) type PowerDNSApplicantConfig struct { - ApiUrl string `json:"apiUrl"` - ApiKey string `json:"apiKey"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + ApiUrl string `json:"apiUrl"` + ApiKey string `json:"apiKey"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *PowerDNSApplicantConfig) (challenge.Provider, error) { @@ -24,8 +25,11 @@ func NewChallengeProvider(config *PowerDNSApplicantConfig) (challenge.Provider, providerConfig := pdns.NewDefaultConfig() providerConfig.Host = host providerConfig.APIKey = config.ApiKey - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := pdns.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go index bd335fc4..f7e6bf7b 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go @@ -9,9 +9,10 @@ import ( ) type TencentCloudApplicantConfig struct { - SecretId string `json:"secretId"` - SecretKey string `json:"secretKey"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + SecretId string `json:"secretId"` + SecretKey string `json:"secretKey"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *TencentCloudApplicantConfig) (challenge.Provider, error) { @@ -22,8 +23,11 @@ func NewChallengeProvider(config *TencentCloudApplicantConfig) (challenge.Provid providerConfig := tencentcloud.NewDefaultConfig() providerConfig.SecretID = config.SecretId providerConfig.SecretKey = config.SecretKey - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := tencentcloud.NewDNSProviderConfig(providerConfig) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go index 0c9ad3c5..a8f11ff9 100644 --- a/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go @@ -9,9 +9,10 @@ import ( ) type VolcEngineApplicantConfig struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - PropagationTimeout int32 `json:"propagationTimeout,omitempty"` + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int32 `json:"dnsTTL,omitempty"` } func NewChallengeProvider(config *VolcEngineApplicantConfig) (challenge.Provider, error) { @@ -22,8 +23,11 @@ func NewChallengeProvider(config *VolcEngineApplicantConfig) (challenge.Provider providerConfig := volcengine.NewDefaultConfig() providerConfig.AccessKey = config.AccessKeyId providerConfig.SecretKey = config.SecretAccessKey - if config.PropagationTimeout != 0 { - providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = int(config.DnsTTL) } provider, err := volcengine.NewDNSProviderConfig(providerConfig) diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 67db24d2..5b08a538 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -42,7 +42,6 @@ const MULTIPLE_INPUT_DELIMITER = ";"; const initFormModel = (): ApplyNodeConfigFormFieldValues => { return { keyAlgorithm: "RSA2048", - propagationTimeout: 60, disableFollowCNAME: true, }; }; @@ -77,10 +76,16 @@ const ApplyNodeConfigForm = forwardRef validIPv4Address(e) || validIPv6Address(e) || validDomainName(e)); }, t("common.errmsg.host_invalid")), - propagationTimeout: z + dnsPropagationTimeout: z .union([ - z.number().int().gte(1, t("workflow_node.apply.form.propagation_timeout.placeholder")), - z.string().refine((v) => !v || /^[1-9]\d*$/.test(v), t("workflow_node.apply.form.propagation_timeout.placeholder")), + z.number().int().gte(1, t("workflow_node.apply.form.dns_propagation_timeout.placeholder")), + z.string().refine((v) => !v || /^[1-9]\d*$/.test(v), t("workflow_node.apply.form.dns_propagation_timeout.placeholder")), + ]) + .nullish(), + dnsTTL: z + .union([ + z.number().int().gte(1, t("workflow_node.apply.form.dns_ttl.placeholder")), + z.string().refine((v) => !v || /^[1-9]\d*$/.test(v), t("workflow_node.apply.form.dns_ttl.placeholder")), ]) .nullish(), disableFollowCNAME: z.boolean().nullish(), @@ -313,18 +318,34 @@ const ApplyNodeConfigForm = forwardRef } + tooltip={} > + + + } + > + diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index c86078ac..b6ce6db3 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -108,7 +108,8 @@ export type WorkflowNodeConfigForApply = { providerConfig?: Record; keyAlgorithm: string; nameservers?: string; - propagationTimeout?: number; + dnsPropagationTimeout?: number; + dnsTTL?: number; disableFollowCNAME?: boolean; }; diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 8dc7215a..0336319f 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -54,10 +54,14 @@ "workflow_node.apply.form.nameservers.tooltip": "It determines whether to custom DNS recursive nameservers during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.
Learn more.", "workflow_node.apply.form.nameservers.multiple_input_modal.title": "Change DNS rcursive nameservers", "workflow_node.apply.form.nameservers.multiple_input_modal.placeholder": "Please enter DNS recursive nameserver", - "workflow_node.apply.form.propagation_timeout.label": "DNS propagation timeout (Optional)", - "workflow_node.apply.form.propagation_timeout.placeholder": "Please enter DNS propagation timeout", - "workflow_node.apply.form.propagation_timeout.suffix": "seconds", - "workflow_node.apply.form.propagation_timeout.tooltip": "It determines the maximum waiting time for DNS propagation checks during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.", + "workflow_node.apply.form.dns_propagation_timeout.label": "DNS propagation timeout (Optional)", + "workflow_node.apply.form.dns_propagation_timeout.placeholder": "Please enter DNS propagation timeout", + "workflow_node.apply.form.dns_propagation_timeout.suffix": "seconds", + "workflow_node.apply.form.dns_propagation_timeout.tooltip": "It determines the maximum waiting time for DNS propagation checks during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.

Leave blank to use the default value provided by the provider.", + "workflow_node.apply.form.dns_ttl.label": "DNS TTL (Optional)", + "workflow_node.apply.form.dns_ttl.placeholder": "Please enter DNS TTL", + "workflow_node.apply.form.dns_ttl.suffix": "seconds", + "workflow_node.apply.form.dns_ttl.tooltip": "It determines the time to live for DNS record during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.

Leave blank to use the default value provided by the provider.", "workflow_node.apply.form.disable_follow_cname.label": "Disable CNAME following", "workflow_node.apply.form.disable_follow_cname.tooltip": "It determines whether to disable CNAME following during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.
Learn more.", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 96b5f5cb..8f36cd4c 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -54,10 +54,14 @@ "workflow_node.apply.form.nameservers.tooltip": "在 ACME DNS-01 认证时使用自定义的 DNS 递归服务器。如果你不了解该选项的用途,保持默认即可。
点此了解更多。", "workflow_node.apply.form.nameservers.multiple_input_modal.title": "修改 DNS 递归服务器", "workflow_node.apply.form.nameservers.multiple_input_modal.placeholder": "请输入 DNS 递归服务器", - "workflow_node.apply.form.propagation_timeout.label": "DNS 传播检查超时时间(可选)", - "workflow_node.apply.form.propagation_timeout.placeholder": "请输入 DNS 传播检查超时时间", - "workflow_node.apply.form.propagation_timeout.suffix": "秒", - "workflow_node.apply.form.propagation_timeout.tooltip": "在 ACME DNS-01 认证时等待 DNS 传播检查的最长时间。如果你不了解此选项的用途,保持默认即可。", + "workflow_node.apply.form.dns_propagation_timeout.label": "DNS 传播检查超时时间(可选)", + "workflow_node.apply.form.dns_propagation_timeout.placeholder": "请输入 DNS 传播检查超时时间", + "workflow_node.apply.form.dns_propagation_timeout.suffix": "秒", + "workflow_node.apply.form.dns_propagation_timeout.tooltip": "在 ACME DNS-01 认证时等待 DNS 传播检查的最长时间。如果你不了解此选项的用途,保持默认即可。

为空时,将使用提供商提供的默认值。", + "workflow_node.apply.form.dns_ttl.label": "DNS 解析 TTL(可选)", + "workflow_node.apply.form.dns_ttl.placeholder": "请输入 DNS 解析 TTL", + "workflow_node.apply.form.dns_ttl.suffix": "秒", + "workflow_node.apply.form.dns_ttl.tooltip": "在 ACME DNS-01 认证时 DNS 解析记录的 TTL。如果你不了解此选项的用途,保持默认即可。

为空时,将使用提供商提供的默认值。", "workflow_node.apply.form.disable_follow_cname.label": "禁止 CNAME 跟随", "workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。
点此了解更多。",