mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 13:39:53 +00:00
feat: support configuring renewal interval in application
This commit is contained in:
parent
60a13aaf17
commit
c71d14cafa
@ -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 {
|
||||
|
@ -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, "已申请过证书,且证书尚未临近过期"
|
||||
}
|
||||
}
|
||||
|
@ -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<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
])
|
||||
.nullish(),
|
||||
disableFollowCNAME: z.boolean().nullish(),
|
||||
skipBeforeExpiryDays: z
|
||||
.number({ message: t("workflow_node.apply.form.skip_before_expiry_days.placeholder") })
|
||||
.int(t("workflow_node.apply.form.skip_before_expiry_days.placeholder"))
|
||||
.gte(1, t("workflow_node.apply.form.skip_before_expiry_days.placeholder"))
|
||||
.lte(60, t("workflow_node.apply.form.skip_before_expiry_days.placeholder")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
@ -329,7 +350,7 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
min={0}
|
||||
max={3600}
|
||||
placeholder={t("workflow_node.apply.form.dns_propagation_timeout.placeholder")}
|
||||
addonAfter={t("workflow_node.apply.form.dns_propagation_timeout.suffix")}
|
||||
addonAfter={t("workflow_node.apply.form.dns_propagation_timeout.unit")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
@ -345,7 +366,7 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
min={0}
|
||||
max={86400}
|
||||
placeholder={t("workflow_node.apply.form.dns_ttl.placeholder")}
|
||||
addonAfter={t("workflow_node.apply.form.dns_ttl.suffix")}
|
||||
addonAfter={t("workflow_node.apply.form.dns_ttl.unit")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
@ -358,6 +379,33 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
<Divider className="my-1">
|
||||
<Typography.Text className="text-xs font-normal" type="secondary">
|
||||
{t("workflow_node.apply.form.strategy_config.label")}
|
||||
</Typography.Text>
|
||||
</Divider>
|
||||
|
||||
<Form className={className} style={style} {...formProps} disabled={disabled} layout="vertical" scrollToFirstError onValuesChange={handleFormChange}>
|
||||
<Form.Item
|
||||
label={t("workflow_node.apply.form.skip_before_expiry_days.label")}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.skip_before_expiry_days.tooltip") }}></span>}
|
||||
>
|
||||
<Flex align="center" gap={8}>
|
||||
<div>{t("workflow_node.apply.form.skip_before_expiry_days.prefix")}</div>
|
||||
<Form.Item name="skipBeforeExpiryDays" noStyle rules={[formRule]}>
|
||||
<InputNumber
|
||||
className="flex-1"
|
||||
min={1}
|
||||
max={60}
|
||||
placeholder={t("workflow_node.apply.form.skip_before_expiry_days.placeholder")}
|
||||
addonAfter={t("workflow_node.apply.form.skip_before_expiry_days.unit")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<div>{t("workflow_node.apply.form.skip_before_expiry_days.suffix")}</div>
|
||||
</Flex>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Form.Provider>
|
||||
);
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ export type WorkflowNodeConfigForApply = {
|
||||
dnsPropagationTimeout?: number;
|
||||
dnsTTL?: number;
|
||||
disableFollowCNAME?: boolean;
|
||||
skipBeforeExpiryDays: number;
|
||||
};
|
||||
|
||||
export type WorkflowNodeConfigForDeploy = {
|
||||
|
@ -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.<br><a href=\"https://go-acme.github.io/lego/usage/cli/options/index.html#dns-resolvers-and-challenge-verification\" target=\"_blank\">Learn more</a>.",
|
||||
"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.<a href=\"https://go-acme.github.io/lego/usage/cli/options/index.html#dns-resolvers-and-challenge-verification\" target=\"_blank\">Learn more</a>.",
|
||||
"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.<br><br>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.<br><br>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.<br><a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">Learn more</a>.",
|
||||
"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.<a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">Learn more</a>.",
|
||||
"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 ...",
|
||||
|
@ -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 账户注册的速率限制。<br><a href=\"https://letsencrypt.org/zh-cn/docs/rate-limits/\" target=\"_blank\">点此了解更多</a>。",
|
||||
"workflow_node.apply.form.contact_email.tooltip": "申请签发 SSL 证书时所需的联系方式。请注意 Let's Encrypt 账户注册的速率限制。<a href=\"https://letsencrypt.org/zh-cn/docs/rate-limits/\" target=\"_blank\">点此了解更多</a>。",
|
||||
"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 递归服务器。如果你不了解该选项的用途,保持默认即可。<br><a href=\"https://go-acme.github.io/lego/usage/cli/options/index.html#dns-resolvers-and-challenge-verification\" target=\"_blank\">点此了解更多</a>。",
|
||||
"workflow_node.apply.form.nameservers.tooltip": "在 ACME DNS-01 认证时使用自定义的 DNS 递归服务器。如果你不了解该选项的用途,保持默认即可。<a href=\"https://go-acme.github.io/lego/usage/cli/options/index.html#dns-resolvers-and-challenge-verification\" target=\"_blank\">点此了解更多</a>。",
|
||||
"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 传播检查的最长时间。如果你不了解此选项的用途,保持默认即可。<br><br>为空时,将使用提供商提供的默认值。",
|
||||
"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。如果你不了解此选项的用途,保持默认即可。<br><br>为空时,将使用提供商提供的默认值。",
|
||||
"workflow_node.apply.form.disable_follow_cname.label": "禁止 CNAME 跟随",
|
||||
"workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。<br><a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">点此了解更多</a>。",
|
||||
"workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。<a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">点此了解更多</a>。",
|
||||
"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": "搜索部署目标……",
|
||||
|
Loading…
x
Reference in New Issue
Block a user