diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index c4249433..1721ddff 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -68,7 +68,7 @@ type WorkflowNodeConfigForApply struct { DnsPropagationTimeout int32 `json:"dnsPropagationTimeout"` // DNS 传播超时时间(默认取决于提供商) DnsTTL int32 `json:"dnsTTL"` // DNS TTL(默认取决于提供商) DisableFollowCNAME bool `json:"disableFollowCNAME"` // 是否禁用 CNAME 跟随 - SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays"` // TODO: 证书到期前多少天前跳过续期(默认值:30) + SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays"` // 证书到期前多少天前跳过续期(默认值:30) } type WorkflowNodeConfigForDeploy struct { diff --git a/internal/workflow/node-processor/apply_node.go b/internal/workflow/node-processor/apply_node.go index 01ed2f60..1849f15e 100644 --- a/internal/workflow/node-processor/apply_node.go +++ b/internal/workflow/node-processor/apply_node.go @@ -109,9 +109,6 @@ func (a *applyNode) Run(ctx context.Context) error { } func (a *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.WorkflowOutput) (skip bool, reason string) { - const validityDuration = time.Hour * 24 * 10 - - // TODO: 可控制是否强制申请 if lastOutput != nil && lastOutput.Succeeded { // 比较和上次申请时的关键配置(即影响证书签发的)参数是否一致 currentNodeConfig := a.node.GetConfigForApply() @@ -133,7 +130,8 @@ func (a *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workflo } lastCertificate, _ := a.certRepo.GetByWorkflowNodeId(ctx, a.node.Id) - if lastCertificate != nil && time.Until(lastCertificate.ExpireAt) > validityDuration { + renewalInterval := time.Duration(currentNodeConfig.SkipBeforeExpiryDays) * time.Hour * 24 + if lastCertificate != nil && time.Until(lastCertificate.ExpireAt) > renewalInterval { return true, "已申请过证书,且证书尚未临近过期" } } diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 5b08a538..24207654 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -2,7 +2,22 @@ import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useState } f import { useTranslation } from "react-i18next"; import { FormOutlined as FormOutlinedIcon, PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon } from "@ant-design/icons"; import { useControllableValue } from "ahooks"; -import { AutoComplete, type AutoCompleteProps, Button, Divider, Form, type FormInstance, Input, Select, Space, Switch, Tooltip, Typography } from "antd"; +import { + AutoComplete, + type AutoCompleteProps, + Button, + Divider, + Flex, + Form, + type FormInstance, + Input, + InputNumber, + Select, + Space, + Switch, + Tooltip, + Typography, +} from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; @@ -43,6 +58,7 @@ const initFormModel = (): ApplyNodeConfigFormFieldValues => { return { keyAlgorithm: "RSA2048", disableFollowCNAME: true, + skipBeforeExpiryDays: 20, }; }; @@ -89,6 +105,11 @@ const ApplyNodeConfigForm = forwardRef @@ -345,7 +366,7 @@ const ApplyNodeConfigForm = forwardRef @@ -358,6 +379,33 @@ const ApplyNodeConfigForm = forwardRef + + + + {t("workflow_node.apply.form.strategy_config.label")} + + + +
+ } + > + +
{t("workflow_node.apply.form.skip_before_expiry_days.prefix")}
+ + + +
{t("workflow_node.apply.form.skip_before_expiry_days.suffix")}
+
+
+
); } diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index b6ce6db3..fd2b44be 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -111,6 +111,7 @@ export type WorkflowNodeConfigForApply = { dnsPropagationTimeout?: number; dnsTTL?: number; disableFollowCNAME?: boolean; + skipBeforeExpiryDays: number; }; export type WorkflowNodeConfigForDeploy = { diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 0336319f..e938af0e 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -51,19 +51,26 @@ "workflow_node.apply.form.key_algorithm.placeholder": "Please select certificate key algorithm", "workflow_node.apply.form.nameservers.label": "DNS recursive nameservers (Optional)", "workflow_node.apply.form.nameservers.placeholder": "Please enter DNS recursive nameservers (separated by semicolons)", - "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.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.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.unit": "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.unit": "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.", + "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.", + "workflow_node.apply.form.strategy_config.label": "Strategy settings", + "workflow_node.apply.form.skip_before_expiry_days.label": "Renewal interval", + "workflow_node.apply.form.skip_before_expiry_days.placeholder": "Please enter renewal interval", + "workflow_node.apply.form.skip_before_expiry_days.prefix": "Skip when the certificate expiration time exceeds", + "workflow_node.apply.form.skip_before_expiry_days.suffix": "", + "workflow_node.apply.form.skip_before_expiry_days.unit": "days", + "workflow_node.apply.form.skip_before_expiry_days.tooltip": "Be careful not to exceed the validity period limit of the CA, otherwise the certificate may never be renewed.", "workflow_node.deploy.label": "Deployment", "workflow_node.deploy.search.provider.placeholder": "Search deploy target ...", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 8f36cd4c..043e8cc5 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -30,7 +30,7 @@ "workflow_node.apply.form.domains.multiple_input_modal.placeholder": "请输入域名", "workflow_node.apply.form.contact_email.label": "联系邮箱", "workflow_node.apply.form.contact_email.placeholder": "请输入联系邮箱", - "workflow_node.apply.form.contact_email.tooltip": "申请签发 SSL 证书时所需的联系方式。请注意 Let's Encrypt 账户注册的速率限制。
点此了解更多。", + "workflow_node.apply.form.contact_email.tooltip": "申请签发 SSL 证书时所需的联系方式。请注意 Let's Encrypt 账户注册的速率限制。点此了解更多。", "workflow_node.apply.form.provider.label": "DNS 提供商", "workflow_node.apply.form.provider.placeholder": "请选择 DNS 提供商", "workflow_node.apply.form.provider_access.label": "DNS 提供商授权", @@ -51,19 +51,26 @@ "workflow_node.apply.form.key_algorithm.placeholder": "请选择数字证书算法", "workflow_node.apply.form.nameservers.label": "DNS 递归服务器(可选)", "workflow_node.apply.form.nameservers.placeholder": "请输入 DNS 递归服务器(多个值请用半角分号隔开)", - "workflow_node.apply.form.nameservers.tooltip": "在 ACME DNS-01 认证时使用自定义的 DNS 递归服务器。如果你不了解该选项的用途,保持默认即可。
点此了解更多。", + "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.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.unit": "秒", "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.unit": "秒", "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 跟随。如果你不了解该选项的用途,保持默认即可。
点此了解更多。", + "workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。点此了解更多。", + "workflow_node.apply.form.strategy_config.label": "执行策略", + "workflow_node.apply.form.skip_before_expiry_days.label": "续期间隔", + "workflow_node.apply.form.skip_before_expiry_days.placeholder": "请输入续期间隔", + "workflow_node.apply.form.skip_before_expiry_days.prefix": "当距上次申请的证书到期时间前", + "workflow_node.apply.form.skip_before_expiry_days.suffix": "时跳过执行", + "workflow_node.apply.form.skip_before_expiry_days.unit": "天", + "workflow_node.apply.form.skip_before_expiry_days.tooltip": "注意不要超过 CA 的证书有效期限制,否则证书可能永远不会续期。", "workflow_node.deploy.label": "部署", "workflow_node.deploy.search.provider.placeholder": "搜索部署目标……",