feat: deploy server certificate or intermedia certificate

This commit is contained in:
Fu Diwei 2025-05-15 01:40:37 +08:00
parent 178c62512d
commit 6c6bb78568
12 changed files with 210 additions and 70 deletions

View File

@ -698,6 +698,8 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
PostCommand: maputil.GetString(options.ProviderExtendedConfig, "postCommand"),
OutputFormat: pLocal.OutputFormatType(maputil.GetOrDefaultString(options.ProviderExtendedConfig, "format", string(pLocal.OUTPUT_FORMAT_PEM))),
OutputCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPath"),
OutputServerCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForServerOnly"),
OutputIntermediaCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForIntermediaOnly"),
OutputKeyPath: maputil.GetString(options.ProviderExtendedConfig, "keyPath"),
PfxPassword: maputil.GetString(options.ProviderExtendedConfig, "pfxPassword"),
JksAlias: maputil.GetString(options.ProviderExtendedConfig, "jksAlias"),
@ -830,6 +832,8 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
PostCommand: maputil.GetString(options.ProviderExtendedConfig, "postCommand"),
OutputFormat: pSSH.OutputFormatType(maputil.GetOrDefaultString(options.ProviderExtendedConfig, "format", string(pSSH.OUTPUT_FORMAT_PEM))),
OutputCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPath"),
OutputServerCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForServerOnly"),
OutputIntermediaCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForIntermediaOnly"),
OutputKeyPath: maputil.GetString(options.ProviderExtendedConfig, "keyPath"),
PfxPassword: maputil.GetString(options.ProviderExtendedConfig, "pfxPassword"),
JksAlias: maputil.GetString(options.ProviderExtendedConfig, "jksAlias"),

View File

@ -57,7 +57,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
// 提取 Edgio 所需的服务端证书和中间证书内容
privateCertPEM, intermediateCertPEM, err := certutil.ExtractCertificatesFromPEM(certPEM)
serverCertPEM, intermediaCertPEM, err := certutil.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, err
}
@ -66,8 +66,8 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
// REF: https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts
uploadTlsCertReq := edgiodtos.UploadTlsCertRequest{
EnvironmentID: d.config.EnvironmentId,
PrimaryCert: privateCertPEM,
IntermediateCert: intermediateCertPEM,
PrimaryCert: serverCertPEM,
IntermediateCert: intermediaCertPEM,
PrivateKey: privkeyPEM,
}
uploadTlsCertResp, err := d.sdkClient.UploadTlsCert(uploadTlsCertReq)

View File

@ -25,6 +25,12 @@ type DeployerConfig struct {
OutputFormat OutputFormatType `json:"outputFormat,omitempty"`
// 输出证书文件路径。
OutputCertPath string `json:"outputCertPath,omitempty"`
// 输出服务器证书文件路径。
// 选填。
OutputServerCertPath string `json:"outputServerCertPath,omitempty"`
// 输出中间证书文件路径。
// 选填。
OutputIntermediaCertPath string `json:"outputIntermediaCertPath,omitempty"`
// 输出私钥文件路径。
OutputKeyPath string `json:"outputKeyPath,omitempty"`
// PFX 导出密码。
@ -69,6 +75,12 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
// 提取服务器证书和中间证书
serverCertPEM, intermediaCertPEM, err := certutil.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, fmt.Errorf("failed to extract certs: %w", err)
}
// 执行前置命令
if d.config.PreCommand != "" {
stdout, stderr, err := execCommand(d.config.ShellEnv, d.config.PreCommand)
@ -86,6 +98,20 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
}
d.logger.Info("ssl certificate file saved", slog.String("path", d.config.OutputCertPath))
if d.config.OutputServerCertPath != "" {
if err := fileutil.WriteString(d.config.OutputServerCertPath, serverCertPEM); err != nil {
return nil, fmt.Errorf("failed to save server certificate file: %w", err)
}
d.logger.Info("ssl server certificate file saved", slog.String("path", d.config.OutputServerCertPath))
}
if d.config.OutputIntermediaCertPath != "" {
if err := fileutil.WriteString(d.config.OutputIntermediaCertPath, intermediaCertPEM); err != nil {
return nil, fmt.Errorf("failed to save intermedia certificate file: %w", err)
}
d.logger.Info("ssl intermedia certificate file saved", slog.String("path", d.config.OutputIntermediaCertPath))
}
if err := fileutil.WriteString(d.config.OutputKeyPath, privkeyPEM); err != nil {
return nil, fmt.Errorf("failed to save private key file: %w", err)
}

View File

@ -41,6 +41,12 @@ type DeployerConfig struct {
OutputFormat OutputFormatType `json:"outputFormat,omitempty"`
// 输出证书文件路径。
OutputCertPath string `json:"outputCertPath,omitempty"`
// 输出服务器证书文件路径。
// 选填。
OutputServerCertPath string `json:"outputServerCertPath,omitempty"`
// 输出中间证书文件路径。
// 选填。
OutputIntermediaCertPath string `json:"outputIntermediaCertPath,omitempty"`
// 输出私钥文件路径。
OutputKeyPath string `json:"outputKeyPath,omitempty"`
// PFX 导出密码。
@ -85,6 +91,12 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
// 提取服务器证书和中间证书
serverCertPEM, intermediaCertPEM, err := certutil.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, fmt.Errorf("failed to extract certs: %w", err)
}
// 连接
client, err := createSshClient(
d.config.SshHost,
@ -118,6 +130,20 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
}
d.logger.Info("ssl certificate file uploaded", slog.String("path", d.config.OutputCertPath))
if d.config.OutputServerCertPath != "" {
if err := writeFileString(client, d.config.UseSCP, d.config.OutputServerCertPath, serverCertPEM); err != nil {
return nil, fmt.Errorf("failed to save server certificate file: %w", err)
}
d.logger.Info("ssl server certificate file uploaded", slog.String("path", d.config.OutputServerCertPath))
}
if d.config.OutputIntermediaCertPath != "" {
if err := writeFileString(client, d.config.UseSCP, d.config.OutputIntermediaCertPath, intermediaCertPEM); err != nil {
return nil, fmt.Errorf("failed to save intermedia certificate file: %w", err)
}
d.logger.Info("ssl intermedia certificate file uploaded", slog.String("path", d.config.OutputIntermediaCertPath))
}
if err := writeFileString(client, d.config.UseSCP, d.config.OutputKeyPath, privkeyPEM); err != nil {
return nil, fmt.Errorf("failed to upload private key file: %w", err)
}

View File

@ -75,6 +75,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return nil, fmt.Errorf("failed to parse x509: %w", err)
}
// 提取服务器证书和中间证书
serverCertPEM, intermediaCertPEM, err := certutil.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, fmt.Errorf("failed to extract certs: %w", err)
}
// 处理 Webhook URL
webhookUrl, err := url.Parse(d.config.WebhookUrl)
if err != nil {
@ -134,6 +140,8 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
replaceJsonValueRecursively(webhookData, "${DOMAIN}", certX509.Subject.CommonName)
replaceJsonValueRecursively(webhookData, "${DOMAINS}", strings.Join(certX509.DNSNames, ";"))
replaceJsonValueRecursively(webhookData, "${CERTIFICATE}", certPEM)
replaceJsonValueRecursively(webhookData, "${SERVER_CERTIFICATE}", serverCertPEM)
replaceJsonValueRecursively(webhookData, "${INTERMEDIA_CERTIFICATE}", intermediaCertPEM)
replaceJsonValueRecursively(webhookData, "${PRIVATE_KEY}", privkeyPEM)
if webhookMethod == http.MethodGet || webhookContentType == CONTENT_TYPE_FORM || webhookContentType == CONTENT_TYPE_MULTIPART {

View File

@ -12,9 +12,9 @@ import (
//
// 出参:
// - serverCertPEM: 服务器证书的 PEM 内容。
// - interCertPEM: 中间证书的 PEM 内容。
// - intermediaCertPEM: 中间证书的 PEM 内容。
// - err: 错误。
func ExtractCertificatesFromPEM(certPEM string) (serverCertPEM string, interCertPEM string, err error) {
func ExtractCertificatesFromPEM(certPEM string) (serverCertPEM string, intermediaCertPEM string, err error) {
pemBlocks := make([]*pem.Block, 0)
pemData := []byte(certPEM)
for {
@ -28,7 +28,7 @@ func ExtractCertificatesFromPEM(certPEM string) (serverCertPEM string, interCert
}
serverCertPEM = ""
interCertPEM = ""
intermediaCertPEM = ""
if len(pemBlocks) == 0 {
return "", "", errors.New("failed to decode PEM block")
@ -40,9 +40,9 @@ func ExtractCertificatesFromPEM(certPEM string) (serverCertPEM string, interCert
if len(pemBlocks) > 1 {
for i := 1; i < len(pemBlocks); i++ {
interCertPEM += string(pem.EncodeToMemory(pemBlocks[i]))
intermediaCertPEM += string(pem.EncodeToMemory(pemBlocks[i]))
}
}
return serverCertPEM, interCertPEM, nil
return serverCertPEM, intermediaCertPEM, nil
}

View File

@ -11,14 +11,16 @@ import { CERTIFICATE_FORMATS } from "@/domain/certificate";
type DeployNodeConfigFormLocalConfigFieldValues = Nullish<{
format: string;
certPath: string;
keyPath?: string | null;
pfxPassword?: string | null;
jksAlias?: string | null;
jksKeypass?: string | null;
jksStorepass?: string | null;
shellEnv?: string | null;
preCommand?: string | null;
postCommand?: string | null;
certPathForServerOnly?: string;
certPathForIntermediaOnly?: string;
keyPath?: string;
pfxPassword?: string;
jksAlias?: string;
jksKeypass?: string;
jksStorepass?: string;
shellEnv?: string;
preCommand?: string;
postCommand?: string;
}>;
export type DeployNodeConfigFormLocalConfigProps = {
@ -160,6 +162,16 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i
.min(1, t("workflow_node.deploy.form.local_cert_path.tooltip"))
.max(256, t("common.errmsg.string_max", { max: 256 }))
.trim(),
certPathForServerOnly: z
.string()
.max(256, t("common.errmsg.string_max", { max: 256 }))
.trim()
.nullish(),
certPathForIntermediaOnly: z
.string()
.max(256, t("common.errmsg.string_max", { max: 256 }))
.trim()
.nullish(),
keyPath: z
.string()
.max(256, t("common.errmsg.string_max", { max: 256 }))
@ -326,6 +338,24 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i
>
<Input placeholder={t("workflow_node.deploy.form.local_key_path.placeholder")} />
</Form.Item>
<Form.Item
name="certPathForServerOnly"
label={t("workflow_node.deploy.form.local_servercert_path.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.local_servercert_path.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.local_servercert_path.placeholder")} />
</Form.Item>
<Form.Item
name="certPathForIntermediaOnly"
label={t("workflow_node.deploy.form.local_intermediacert_path.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.local_intermediacert_path.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.local_intermediacert_path.placeholder")} />
</Form.Item>
</Show>
<Show when={fieldFormat === FORMAT_PFX}>

View File

@ -13,13 +13,15 @@ import { initPresetScript } from "./DeployNodeConfigFormLocalConfig";
type DeployNodeConfigFormSSHConfigFieldValues = Nullish<{
format: string;
certPath: string;
keyPath?: string | null;
pfxPassword?: string | null;
jksAlias?: string | null;
jksKeypass?: string | null;
jksStorepass?: string | null;
preCommand?: string | null;
postCommand?: string | null;
certPathForServerOnly?: string;
certPathForIntermediaOnly?: string;
keyPath?: string;
pfxPassword?: string;
jksAlias?: string;
jksKeypass?: string;
jksStorepass?: string;
preCommand?: string;
postCommand?: string;
useSCP?: boolean;
}>;
@ -61,6 +63,16 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
.trim()
.nullish()
.refine((v) => fieldFormat !== FORMAT_PEM || !!v?.trim(), { message: t("workflow_node.deploy.form.ssh_key_path.tooltip") }),
certPathForServerOnly: z
.string()
.max(256, t("common.errmsg.string_max", { max: 256 }))
.trim()
.nullish(),
certPathForIntermediaOnly: z
.string()
.max(256, t("common.errmsg.string_max", { max: 256 }))
.trim()
.nullish(),
pfxPassword: z
.string()
.max(64, t("common.errmsg.string_max", { max: 256 }))
@ -207,6 +219,24 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
>
<Input placeholder={t("workflow_node.deploy.form.ssh_key_path.placeholder")} />
</Form.Item>
<Form.Item
name="certPathForServerOnly"
label={t("workflow_node.deploy.form.ssh_servercert_path.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.ssh_servercert_path.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.ssh_servercert_path.placeholder")} />
</Form.Item>
<Form.Item
name="certPathForIntermediaOnly"
label={t("workflow_node.deploy.form.ssh_intermediacert_path.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.ssh_intermediacert_path.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.ssh_intermediacert_path.placeholder")} />
</Form.Item>
</Show>
<Show when={fieldFormat === FORMAT_PFX}>
@ -249,10 +279,6 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
</Form.Item>
</Show>
<Form.Item label={t("workflow_node.deploy.form.ssh_shell_env.label")}>
<Select options={[{ value: t("workflow_node.deploy.form.ssh_shell_env.value") }]} value={t("workflow_node.deploy.form.ssh_shell_env.value")} />
</Form.Item>
<Form.Item className="mb-0" htmlFor="null">
<label className="mb-1 block">
<div className="flex w-full items-center justify-between gap-4">

View File

@ -377,7 +377,7 @@
"access.form.webhook_default_data.errmsg.json_invalid": "Please enter a valiod JSON string",
"access.form.webhook_default_data_for_deployment.label": "Webhook data for deployment (Optional)",
"access.form.webhook_default_data_for_deployment.placeholder": "Please enter Webhook data",
"access.form.webhook_default_data_for_deployment.guide": "Tips: The Webhook data should be in JSON format. <br><br>The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables: <br><ol style=\"margin-left: 1.25em; 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>${PRIVATE_KEY}</strong>: The PEM format content of the private key file.</li></ol><br>When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats: <br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json (default).</li><li>application/x-www-form-urlencoded: Nested data is not supported.</li><li>multipart/form-data: Nested data is not supported.</li>",
"access.form.webhook_default_data_for_deployment.guide": "Tips: The Webhook data should be in JSON format. <br><br>The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables: <br><ol style=\"margin-left: 1.25em; 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 intermedia certificate file.</li><li><strong>${PRIVATE_KEY}</strong>: The PEM format content of the private key file.</li></ol><br>When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats: <br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json (default).</li><li>application/x-www-form-urlencoded: Nested data is not supported.</li><li>multipart/form-data: Nested data is not supported.</li>",
"access.form.webhook_default_data_for_notification.label": "Webhook data for notification (Optional)",
"access.form.webhook_default_data_for_notification.placeholder": "Please enter Webhook data",
"access.form.webhook_default_data_for_notification.guide": "Tips: The Webhook data should be in JSON format. <br><br>The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables: <br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li><strong>${SUBJECT}</strong>: The subject of notification.</li><li><strong>${MESSAGE}</strong>: The message of notification.</li></ol><br>When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats: <br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json (default).</li><li>application/x-www-form-urlencoded: Nested data is not supported.</li><li>multipart/form-data: Nested data is not supported.</li>",

View File

@ -449,9 +449,15 @@
"workflow_node.deploy.form.local_cert_path.label": "Certificate file saving path",
"workflow_node.deploy.form.local_cert_path.placeholder": "Please enter saving path for certificate file",
"workflow_node.deploy.form.local_cert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.local_key_path.label": "Private key file saving path",
"workflow_node.deploy.form.local_key_path.placeholder": "Please enter saving path for private key file",
"workflow_node.deploy.form.local_key_path.label": "Certificate's private key file saving path",
"workflow_node.deploy.form.local_key_path.placeholder": "Please enter saving path for certificate's private key file",
"workflow_node.deploy.form.local_key_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.local_servercert_path.label": "Server certificate file saving path (Optional)",
"workflow_node.deploy.form.local_servercert_path.placeholder": "Please enter saving path for server certificate file",
"workflow_node.deploy.form.local_servercert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.local_intermediacert_path.label": "Intermedia certificate file saving path (Optional)",
"workflow_node.deploy.form.local_intermediacert_path.placeholder": "Please enter saving path for intermedia certificate file",
"workflow_node.deploy.form.local_intermediacert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.local_pfx_password.label": "PFX password",
"workflow_node.deploy.form.local_pfx_password.placeholder": "Please enter PFX password",
"workflow_node.deploy.form.local_pfx_password.tooltip": "For more information, see <a href=\"https://learn.microsoft.com/en-us/windows-hardware/drivers/install/personal-information-exchange---pfx--files\" target=\"_blank\">https://learn.microsoft.com/en-us/windows-hardware/drivers/install/personal-information-exchange---pfx--files</a>",
@ -514,9 +520,15 @@
"workflow_node.deploy.form.ssh_cert_path.label": "Certificate file uploading path",
"workflow_node.deploy.form.ssh_cert_path.placeholder": "Please enter uploading path for certificate file",
"workflow_node.deploy.form.ssh_cert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.ssh_key_path.label": "Private key file uploading path",
"workflow_node.deploy.form.ssh_key_path.placeholder": "Please enter uploading path for private key file",
"workflow_node.deploy.form.ssh_key_path.label": "Certificate's private key file uploading path",
"workflow_node.deploy.form.ssh_key_path.placeholder": "Please enter uploading path for certificate's private key file",
"workflow_node.deploy.form.ssh_key_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.ssh_servercert_path.label": "Server certificate file uploading path (Optional)",
"workflow_node.deploy.form.ssh_servercert_path.placeholder": "Please enter uploading path for server certificate file",
"workflow_node.deploy.form.ssh_servercert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.ssh_intermediacert_path.label": "Intermedia certificate file uploading path (Optional)",
"workflow_node.deploy.form.ssh_intermediacert_path.placeholder": "Please enter uploading path for intermedia certificate file",
"workflow_node.deploy.form.ssh_intermediacert_path.tooltip": "Note that the path should include the complete file name, not just the directory.",
"workflow_node.deploy.form.ssh_pfx_password.label": "PFX password",
"workflow_node.deploy.form.ssh_pfx_password.placeholder": "Please enter PFX password",
"workflow_node.deploy.form.ssh_pfx_password.tooltip": "For more information, see <a href=\"https://learn.microsoft.com/en-us/windows-hardware/drivers/install/personal-information-exchange---pfx--files\" target=\"_blank\">https://learn.microsoft.com/en-us/windows-hardware/drivers/install/personal-information-exchange---pfx--files</a>",
@ -529,8 +541,6 @@
"workflow_node.deploy.form.ssh_jks_storepass.label": "JKS store password",
"workflow_node.deploy.form.ssh_jks_storepass.placeholder": "Please enter JKS store password",
"workflow_node.deploy.form.ssh_jks_storepass.tooltip": "For more information, see <a href=\"https://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html\" target=\"_blank\">https://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html</a>",
"workflow_node.deploy.form.ssh_shell_env.label": "Shell",
"workflow_node.deploy.form.ssh_shell_env.value": "POSIX Bash (on Linux / macOS)",
"workflow_node.deploy.form.ssh_pre_command.label": "Pre-command (Optional)",
"workflow_node.deploy.form.ssh_pre_command.placeholder": "Please enter command to be executed before uploading files",
"workflow_node.deploy.form.ssh_post_command.label": "Post-command (Optional)",
@ -718,7 +728,7 @@
"workflow_node.deploy.form.webhook_data.label": "Webhook data (Optional)",
"workflow_node.deploy.form.webhook_data.placeholder": "Please enter Webhook data to override the default value",
"workflow_node.deploy.form.webhook_data.tooltip": "Leave it blank to use the default Webhook data provided by the authorization.",
"workflow_node.deploy.form.webhook_data.guide": "Supported variables: <br><ol style=\"margin-left: 1.25em; 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>${PRIVATE_KEY}</strong>: The PEM format content of the private key file.</li></ol><br>Please visit the authorization management page for addtional notes.",
"workflow_node.deploy.form.webhook_data.guide": "Supported variables: <br><ol style=\"margin-left: 1.25em; 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 intermedia certificate file.</li><li><strong>${PRIVATE_KEY}</strong>: The PEM format content of the private key file.</li></ol><br>Please visit the authorization management page for addtional notes.",
"workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "Please enter a valiod JSON string",
"workflow_node.deploy.form.strategy_config.label": "Strategy settings",
"workflow_node.deploy.form.skip_on_last_succeeded.label": "Repeated deployment",

View File

@ -377,7 +377,7 @@
"access.form.webhook_default_data.errmsg.json_invalid": "请输入有效的 JSON 格式字符串",
"access.form.webhook_default_data_for_deployment.label": "默认的 Webhook 部署证书回调数据(可选)",
"access.form.webhook_default_data_for_deployment.placeholder": "请输入默认的 Webhook 回调数据",
"access.form.webhook_default_data_for_deployment.guide": "小贴士:回调数据是一个 JSON 格式的数据。<br><br>其中值支持模板变量,将在被发送到指定的 Webhook URL 时被替换为实际值;其他内容将保持原样。支持的变量:<br><ol style=\"margin-left: 1.25em; 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>${PRIVATE_KEY}</strong>:私钥文件 PEM 格式内容。</li></ol><br>当请求谓词为 GET 时,回调数据将作为查询参数;否则,回调数据将按照请求标头中 Content-Type 所指示的格式进行编码。支持的格式:<br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json默认。</li><li>application/x-www-form-urlencoded不支持嵌套数据。</li><li>multipart/form-data不支持嵌套数据。</li>",
"access.form.webhook_default_data_for_deployment.guide": "小贴士:回调数据是一个 JSON 格式的数据。<br><br>其中值支持模板变量,将在被发送到指定的 Webhook URL 时被替换为实际值;其他内容将保持原样。支持的变量:<br><ol style=\"margin-left: 1.25em; 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><br>当请求谓词为 GET 时,回调数据将作为查询参数;否则,回调数据将按照请求标头中 Content-Type 所指示的格式进行编码。支持的格式:<br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json默认。</li><li>application/x-www-form-urlencoded不支持嵌套数据。</li><li>multipart/form-data不支持嵌套数据。</li>",
"access.form.webhook_default_data_for_notification.label": "默认的 Webhook 推送通知回调数据(可选)",
"access.form.webhook_default_data_for_notification.placeholder": "请输入默认的 Webhook 回调数据",
"access.form.webhook_default_data_for_notification.guide": "小贴士:回调数据是一个 JSON 格式的数据。<br><br>其中值支持模板变量,将在被发送到指定的 Webhook URL 时被替换为实际值;其他内容将保持原样。支持的变量:<br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li><strong>${SUBJECT}</strong>:通知主题。</li><li><strong>${MESSAGE}</strong>:通知内容。</ol><br>当请求谓词为 GET 时,回调数据将作为查询参数;否则,回调数据将按照请求标头中 Content-Type 所指示的格式进行编码。支持的格式:<br><ol style=\"margin-left: 1.25em; list-style: disc;\"><li>application/json默认。</li><li>application/x-www-form-urlencoded不支持嵌套数据。</li><li>multipart/form-data不支持嵌套数据。</li>",

View File

@ -448,9 +448,15 @@
"workflow_node.deploy.form.local_cert_path.label": "证书文件保存路径",
"workflow_node.deploy.form.local_cert_path.placeholder": "请输入证书文件保存路径",
"workflow_node.deploy.form.local_cert_path.tooltip": "注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.local_key_path.label": "私钥文件保存路径",
"workflow_node.deploy.form.local_key_path.placeholder": "请输入私钥文件保存路径",
"workflow_node.deploy.form.local_key_path.label": "证书私钥文件保存路径",
"workflow_node.deploy.form.local_key_path.placeholder": "请输入证书私钥文件保存路径",
"workflow_node.deploy.form.local_key_path.tooltip": "注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.local_servercert_path.label": "服务器证书文件保存路径(可选)",
"workflow_node.deploy.form.local_servercert_path.placeholder": "请输入服务器证书文件保存路径",
"workflow_node.deploy.form.local_servercert_path.tooltip": "不填写时将不会保存服务器证书。<br><br>注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.local_intermediacert_path.label": "中间证书文件保存路径(可选)",
"workflow_node.deploy.form.local_intermediacert_path.placeholder": "请输入中间证书文件保存路径",
"workflow_node.deploy.form.local_intermediacert_path.tooltip": "不填写时将不会保存服务器证书。<br><br>注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.local_pfx_password.label": "PFX 导出密码",
"workflow_node.deploy.form.local_pfx_password.placeholder": "请输入 PFX 导出密码",
"workflow_node.deploy.form.local_pfx_password.tooltip": "这是什么?请参阅 <a href=\"https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/personal-information-exchange---pfx--files\" target=\"_blank\">https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/personal-information-exchange---pfx--files</a>",
@ -513,10 +519,16 @@
"workflow_node.deploy.form.ssh_cert_path.label": "证书文件上传路径",
"workflow_node.deploy.form.ssh_cert_path.placeholder": "请输入证书文件上传路径",
"workflow_node.deploy.form.ssh_cert_path.tooltip": "注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.ssh_key_path.label": "私钥文件上传路径",
"workflow_node.deploy.form.ssh_key_path.placeholder": "请输入私钥文件上传路径",
"workflow_node.deploy.form.ssh_key_path.label": "证书私钥文件上传路径",
"workflow_node.deploy.form.ssh_key_path.placeholder": "请输入证书私钥文件上传路径",
"workflow_node.deploy.form.ssh_key_path.tooltip": "注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.ssh_pfx_password.label": "PFX 导出密码",
"workflow_node.deploy.form.ssh_servercert_path.label": "服务器证书文件上传路径(可选)",
"workflow_node.deploy.form.ssh_servercert_path.placeholder": "请输入服务器证书文件上传路径",
"workflow_node.deploy.form.ssh_servercert_path.tooltip": "不填写时将不上传服务器证书。<br><br>注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.ssh_intermediacert_path.label": "中间证书文件上传路径(可选)",
"workflow_node.deploy.form.ssh_intermediacert_path.placeholder": "请输入中间证书文件上传路径",
"workflow_node.deploy.form.ssh_intermediacert_path.tooltip": "不填写时将不上传服务器证书。<br><br>注意,路径需包含完整的文件名,而不是仅目录。",
"workflow_node.deploy.form.ssh_pfx_password.placeholder": "请输入 PFX 导出密码",
"workflow_node.deploy.form.ssh_pfx_password.tooltip": "这是什么?请参阅 <a href=\"https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/personal-information-exchange---pfx--files\" target=\"_blank\">https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/personal-information-exchange---pfx--files</a>",
"workflow_node.deploy.form.ssh_jks_alias.label": "JKS 别名",
@ -528,8 +540,6 @@
"workflow_node.deploy.form.ssh_jks_storepass.label": "JKS 密钥库存储口令",
"workflow_node.deploy.form.ssh_jks_storepass.placeholder": "请输入 JKS 密钥库存储口令",
"workflow_node.deploy.form.ssh_jks_storepass.tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html\" target=\"_blank\">https://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html</a>",
"workflow_node.deploy.form.ssh_shell_env.label": "命令执行环境",
"workflow_node.deploy.form.ssh_shell_env.value": "POSIX BashLinux / macOS",
"workflow_node.deploy.form.ssh_pre_command.label": "前置命令(可选)",
"workflow_node.deploy.form.ssh_pre_command.placeholder": "请输入上传文件前执行的命令",
"workflow_node.deploy.form.ssh_post_command.label": "后置命令(可选)",
@ -715,9 +725,9 @@
"workflow_node.deploy.form.wangsu_cdnpro_webhook_id.placeholder": "请输入网宿云 CDN Pro 部署任务 Webhook ID",
"workflow_node.deploy.form.wangsu_cdnpro_webhook_id.tooltip": "这是什么?请参阅 <a href=\"https://cdnpro.console.wangsu.com/v2/index/#/certificate\" target=\"_blank\">https://cdnpro.console.wangsu.com/v2/index/#/certificate</a>",
"workflow_node.deploy.form.webhook_data.label": "Webhook 回调数据(可选)",
"workflow_node.deploy.form.webhook_data.placeholder": "请输入 Webhook 回调数据",
"workflow_node.deploy.form.webhook_data.placeholder": "请输入 Webhook 回调数据以覆盖默认值",
"workflow_node.deploy.form.webhook_data.tooltip": "不填写时,将使用所选部署目标授权的默认 Webhook 回调数据。",
"workflow_node.deploy.form.webhook_data.guide": "支持的变量:<br><ol style=\"margin-left: 1.25em; 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>${PRIVATE_KEY}</strong>:私钥文件 PEM 格式内容。</li></ol><br>其他注意事项请前往授权管理页面查看。",
"workflow_node.deploy.form.webhook_data.guide": "支持的变量:<br><ol style=\"margin-left: 1.25em; 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><br>其他注意事项请前往授权管理页面查看。",
"workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "请输入有效的 JSON 格式字符串",
"workflow_node.deploy.form.strategy_config.label": "执行策略",
"workflow_node.deploy.form.skip_on_last_succeeded.label": "重复部署",