feat: webhook timeout

This commit is contained in:
Fu Diwei
2025-09-06 00:16:32 +08:00
parent aaf48216af
commit 145eadad2f
9 changed files with 64 additions and 8 deletions
@@ -43,6 +43,7 @@ func init() {
WebhookData: xmaps.GetOrDefaultString(options.ProviderExtendedConfig, "webhookData", credentials.DataString),
Method: credentials.Method,
Headers: mergedHeaders,
Timeout: xmaps.GetInt32(options.ProviderExtendedConfig, "timeout"),
AllowInsecureConnections: credentials.AllowInsecureConnections,
})
return provider, err
+1
View File
@@ -43,6 +43,7 @@ func init() {
WebhookData: xmaps.GetOrDefaultString(options.ProviderExtendedConfig, "webhookData", credentials.DataString),
Method: credentials.Method,
Headers: mergedHeaders,
Timeout: xmaps.GetInt32(options.ProviderExtendedConfig, "timeout"),
AllowInsecureConnections: credentials.AllowInsecureConnections,
})
return provider, err
@@ -27,6 +27,9 @@ type NotifierProviderConfig struct {
Method string `json:"method,omitempty"`
// 请求标头。
Headers map[string]string `json:"headers,omitempty"`
// 请求超时(单位:秒)。
// 零值时默认值 30。
Timeout int32 `json:"timeout,omitempty"`
// 是否允许不安全的连接。
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
@@ -48,6 +51,9 @@ func NewNotifierProvider(config *NotifierProviderConfig) (*NotifierProvider, err
SetTimeout(30 * time.Second).
SetRetryCount(3).
SetRetryWaitTime(5 * time.Second)
if config.Timeout > 0 {
client.SetTimeout(time.Duration(config.Timeout) * time.Second)
}
if config.AllowInsecureConnections {
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
}
@@ -28,6 +28,9 @@ type SSLDeployerProviderConfig struct {
Method string `json:"method,omitempty"`
// 请求标头。
Headers map[string]string `json:"headers,omitempty"`
// 请求超时(单位:秒)。
// 零值时默认值 30。
Timeout int32 `json:"timeout,omitempty"`
// 是否允许不安全的连接。
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
@@ -49,6 +52,9 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv
SetTimeout(30 * time.Second).
SetRetryCount(3).
SetRetryWaitTime(5 * time.Second)
if config.Timeout > 0 {
client.SetTimeout(time.Duration(config.Timeout) * time.Second)
}
if config.AllowInsecureConnections {
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
}
@@ -1,5 +1,5 @@
import { getI18n, useTranslation } from "react-i18next";
import { Form } from "antd";
import { Form, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
@@ -51,6 +51,17 @@ const BizDeployNodeConfigFieldsProviderWebhook = () => {
<Form.Item>
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.webhook_data.guide") }}></span>} />
</Form.Item>
<Form.Item name={[parentNamePath, "timeout"]} label={t("workflow_node.deploy.form.webhook_timeout.label")} rules={[formRule]}>
<Input
type="number"
allowClear
min={0}
max={3600}
placeholder={t("workflow_node.deploy.form.webhook_timeout.placeholder")}
addonAfter={t("workflow_node.deploy.form.webhook_timeout.unit")}
/>
</Form.Item>
</>
);
};
@@ -76,6 +87,10 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
return false;
}
}, t("workflow_node.deploy.form.webhook_data.errmsg.json_invalid")),
timeout: z.preprocess(
(v) => (v == null || v === "" ? void 0 : Number(v)),
z.number().int(t("workflow_node.deploy.form.webhook_timeout.placeholder")).gte(1, t("workflow_node.deploy.form.webhook_timeout.placeholder")).nullish()
),
});
};
@@ -1,5 +1,5 @@
import { getI18n, useTranslation } from "react-i18next";
import { Form } from "antd";
import { Form, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
@@ -51,6 +51,17 @@ const BizNotifyNodeConfigFieldsProviderWebhook = () => {
<Form.Item>
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.notify.form.webhook_data.guide") }}></span>} />
</Form.Item>
<Form.Item name={[parentNamePath, "timeout"]} label={t("workflow_node.notify.form.webhook_timeout.label")} rules={[formRule]}>
<Input
type="number"
allowClear
min={0}
max={3600}
placeholder={t("workflow_node.notify.form.webhook_timeout.placeholder")}
addonAfter={t("workflow_node.notify.form.webhook_timeout.unit")}
/>
</Form.Item>
</>
);
};
@@ -76,6 +87,10 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
return false;
}
}, t("workflow_node.notify.form.webhook_data.errmsg.json_invalid")),
timeout: z.preprocess(
(v) => (v == null || v === "" ? void 0 : Number(v)),
z.number().int(t("workflow_node.notify.form.webhook_timeout.placeholder")).gte(1, t("workflow_node.notify.form.webhook_timeout.placeholder")).nullish()
),
});
};
+2 -2
View File
@@ -65,7 +65,7 @@
"access.form.acmedns_credentials.label": "ACME-DNS credentials",
"access.form.acmedns_credentials.placeholder": "Please enter ACME-DNS credentials",
"access.form.acmedns_credentials.tooltip": "For more information, see <a href=\"https://github.com/joohoi/acme-dns\" target=\"_blank\">https://github.com/joohoi/acme-dns</a>",
"access.form.acmedns_credentials.errmsg.json_invalid": "Please enter a valiod JSON string",
"access.form.acmedns_credentials.errmsg.json_invalid": "Please enter a valid JSON string",
"access.form.acmehttpreq_endpoint.label": "Endpoint",
"access.form.acmehttpreq_endpoint.placeholder": "Please enter endpoint",
"access.form.acmehttpreq_endpoint.tooltip": "For more information, see <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
@@ -518,7 +518,7 @@
"access.form.webhook_headers.placeholder": "Please enter Webhook request headers",
"access.form.webhook_headers.errmsg.invalid": "Please enter a valid request headers",
"access.form.webhook_headers.tooltip": "Example: <br><i>Content-Type: application/json<br>User-Agent: certimate</i>",
"access.form.webhook_data.errmsg.json_invalid": "Please enter a valiod JSON string",
"access.form.webhook_data.errmsg.json_invalid": "Please enter a valid JSON string",
"access.form.webhook_data.label": "Webhook data (Optional)",
"access.form.webhook_data.placeholder": "Please enter the default Webhook data",
"access.form.webhook_data.help": "Notes: It can be overrided in the workflows.",
+10 -4
View File
@@ -92,8 +92,8 @@
"workflow_node.apply.form.validity_lifetime.placeholder": "Please enter certificate's validity lifetime",
"workflow_node.apply.form.validity_lifetime.help": "Notes: Not all CAs support this feature.",
"workflow_node.apply.form.validity_lifetime.tooltip": "It determines the <em>NotAfter</em> field of the certificate in the ACME protocol. If you don't understand this option, just keep it by default.",
"workflow_node.apply.form.validity_lifetime.units.h": "Hour(s)",
"workflow_node.apply.form.validity_lifetime.units.d": "Day(s)",
"workflow_node.apply.form.validity_lifetime.units.h": "hours",
"workflow_node.apply.form.validity_lifetime.units.d": "days",
"workflow_node.apply.form.acme_profile.label": "Certificate ACME profile (Optional)",
"workflow_node.apply.form.acme_profile.placeholder": "Please enter certificate's ACME profile",
"workflow_node.apply.form.acme_profile.help": "Notes: Not all CAs support this feature.",
@@ -1002,7 +1002,10 @@
"workflow_node.deploy.form.webhook_data.placeholder": "Please enter Webhook data",
"workflow_node.deploy.form.webhook_data.help": "Notes: Leave it blank to use the default Webhook data provided by the credential.",
"workflow_node.deploy.form.webhook_data.guide": "<details><summary>Supported variables: </summary><ol style=\"list-style: disc;\"><li><strong>${DOMAIN}</strong>: The primary domain of the certificate (<i>CommonName</i>).</li><li><strong>${DOMAINS}</strong>: The domain list of the certificate (<i>SubjectAltNames</i>).</li><li><strong>${CERTIFICATE}</strong>: The PEM format content of the certificate file.</li><li><strong>${SERVER_CERTIFICATE}</strong>: The PEM format content of the server certificate file.</li><li><strong>${INTERMEDIA_CERTIFICATE}</strong>: The PEM format content of the intermediate CA certificate file.</li><li><strong>${PRIVATE_KEY}</strong>: The PEM format content of the private key file.</li></ol></details><br>Please visit the credentials page for addtional notes.",
"workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "Please enter a valiod JSON string",
"workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "Please enter a valid JSON string",
"workflow_node.deploy.form.webhook_timeout.label": "Webhook timeout (Optional)",
"workflow_node.deploy.form.webhook_timeout.placeholder": "Please enter Webhook timeout",
"workflow_node.deploy.form.webhook_timeout.unit": "seconds",
"workflow_node.deploy.form.skip_on_last_succeeded.label": "Repeated deployment",
"workflow_node.deploy.form.skip_on_last_succeeded.prefix": "If the last deployment was successful, ",
"workflow_node.deploy.form.skip_on_last_succeeded.suffix": " to re-deploy.",
@@ -1047,7 +1050,10 @@
"workflow_node.notify.form.webhook_data.placeholder": "Please enter Webhook data",
"workflow_node.notify.form.webhook_data.help": "Notes: Leave it blank to use the default Webhook data provided by the credential.",
"workflow_node.notify.form.webhook_data.guide": "<details><summary>Supported variables: </summary><ol style=\"list-style: disc;\"><li><strong>${SUBJECT}</strong>: The subject of notification.</li><li><strong>${MESSAGE}</strong>: The message of notification.</li></ol></details><br>Please visit the credentials page for addtional notes.",
"workflow_node.notify.form.webhook_data.errmsg.json_invalid": "Please enter a valiod JSON string",
"workflow_node.notify.form.webhook_data.errmsg.json_invalid": "Please enter a valid JSON string",
"workflow_node.notify.form.webhook_timeout.label": "Webhook timeout (Optional)",
"workflow_node.notify.form.webhook_timeout.placeholder": "Please enter Webhook timeout",
"workflow_node.notify.form.webhook_timeout.unit": "seconds",
"workflow_node.notify.form.skip_on_all_prev_skipped.label": "Silent behavior",
"workflow_node.notify.form.skip_on_all_prev_skipped.prefix": "If all the previous nodes were skipped, ",
"workflow_node.notify.form.skip_on_all_prev_skipped.suffix": " to notify.",
@@ -1001,6 +1001,9 @@
"workflow_node.deploy.form.webhook_data.help": "提示:不填写时,将使用所选部署目标授权的默认 Webhook 回调数据。",
"workflow_node.deploy.form.webhook_data.guide": "<details><summary>支持的变量:</summary><ol style=\"list-style: disc;\"><li><strong>${DOMAIN}</strong>:证书的主域名(即 <i>CommonName</i>)。</li><li><strong>${DOMAINS}</strong>:证书的多域名列表(即 <i>SubjectAltNames</i>)。</li><li><strong>${CERTIFICATE}</strong>:证书文件 PEM 格式内容。</li><li><strong>${SERVER_CERTIFICATE}</strong>:证书文件(仅含服务器证书)PEM 格式内容。</li><li><strong>${INTERMEDIA_CERTIFICATE}</strong>:证书文件(仅含中间证书)PEM 格式内容。</li><li><strong>${PRIVATE_KEY}</strong>:私钥文件 PEM 格式内容。</li></ol></details><br>其他注意事项请前往授权凭据页面查看。",
"workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "请输入有效的 JSON 格式字符串",
"workflow_node.deploy.form.webhook_timeout.label": "Webhook 超时时间(可选)",
"workflow_node.deploy.form.webhook_timeout.placeholder": "请输入 Webhook 超时时间",
"workflow_node.deploy.form.webhook_timeout.unit": "秒",
"workflow_node.deploy.form.skip_on_last_succeeded.label": "重复部署",
"workflow_node.deploy.form.skip_on_last_succeeded.prefix": "当上次部署相同证书成功时,再次运行工作流时",
"workflow_node.deploy.form.skip_on_last_succeeded.suffix": "此部署节点。",
@@ -1046,6 +1049,9 @@
"workflow_node.notify.form.webhook_data.help": "提示:不填写时,将使用所选部署目标授权的默认 Webhook 回调数据。",
"workflow_node.notify.form.webhook_data.guide": "<details><summary>支持的变量:</summary><ol style=\"list-style: disc;\"><li><strong>${SUBJECT}</strong>:通知主题。</li><li><strong>${MESSAGE}</strong>:通知内容。</ol></details><br>其他注意事项请前往授权凭据页面查看。",
"workflow_node.notify.form.webhook_data.errmsg.json_invalid": "请输入有效的 JSON 格式字符串",
"workflow_node.notify.form.webhook_timeout.label": "Webhook 超时时间(可选)",
"workflow_node.notify.form.webhook_timeout.placeholder": "请输入 Webhook 超时时间",
"workflow_node.notify.form.webhook_timeout.unit": "秒",
"workflow_node.notify.form.skip_on_all_prev_skipped.label": "静默行为",
"workflow_node.notify.form.skip_on_all_prev_skipped.prefix": "当前序申请、上传、部署等节点均已跳过执行时,",
"workflow_node.notify.form.skip_on_all_prev_skipped.suffix": "此通知节点。",