From 0a73ba1a53cc413e08d51f20bce5313a35a919ec Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Thu, 8 May 2025 20:43:09 +0800 Subject: [PATCH] feat: add preset scripts --- .../node/DeployNodeConfigFormLocalConfig.tsx | 250 +++++++++--------- .../node/DeployNodeConfigFormSSHConfig.tsx | 52 ++-- .../i18n/locales/en/nls.workflow.nodes.json | 19 +- .../i18n/locales/zh/nls.workflow.nodes.json | 19 +- 4 files changed, 181 insertions(+), 159 deletions(-) diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx index bf9386cc..2ebae25d 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx @@ -45,6 +45,108 @@ const initFormModel = (): DeployNodeConfigFormLocalConfigFieldValues => { }; }; +export const initPresetScript = ( + key: "sh_backup_files" | "ps_backup_files" | "sh_reload_nginx" | "ps_binding_iis" | "ps_binding_netsh" | "ps_binding_rdp", + params?: { + certPath?: string; + keyPath?: string; + pfxPassword?: string; + jksAlias?: string; + jksKeypass?: string; + jksStorepass?: string; + } +) => { + switch (key) { + case "sh_backup_files": + return `# 请将以下路径替换为实际值 +cp "${params?.certPath || ""}" "${params?.certPath || ""}.bak" 2>/dev/null || : +cp "${params?.keyPath || ""}" "${params?.keyPath || ""}.bak" 2>/dev/null || : + `.trim(); + + case "ps_backup_files": + return `# 请将以下路径替换为实际值 +if (Test-Path -Path "${params?.certPath || ""}" -PathType Leaf) { + Copy-Item -Path "${params?.certPath || ""}" -Destination "${params?.certPath || ""}.bak" -Force +} +if (Test-Path -Path "${params?.keyPath || ""}" -PathType Leaf) { + Copy-Item -Path "${params?.keyPath || ""}" -Destination "${params?.keyPath || ""}.bak" -Force +} + `.trim(); + + case "sh_reload_nginx": + return `sudo service nginx reload`; + + case "ps_binding_iis": + return `# 需要管理员权限 +# 请将以下变量替换为实际值 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 +$siteName = "" # IIS 网站名称 +$domain = "" # 域名 +$ipaddr = "" # 绑定 IP,“*”表示所有 IP 绑定 +$port = "" # 绑定端口 + + +# 导入证书到本地计算机的个人存储区 +$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable +# 获取 Thumbprint +$thumbprint = $cert.Thumbprint +# 导入 WebAdministration 模块 +Import-Module WebAdministration +# 检查是否已存在 HTTPS 绑定 +$existingBinding = Get-WebBinding -Name "$siteName" -Protocol "https" -Port $port -HostHeader "$domain" -ErrorAction SilentlyContinue +if (!$existingBinding) { + # 添加新的 HTTPS 绑定 + New-WebBinding -Name "$siteName" -Protocol "https" -Port $port -IPAddress "$ipaddr" -HostHeader "$domain" +} +# 获取绑定对象 +$binding = Get-WebBinding -Name "$siteName" -Protocol "https" -Port $port -IPAddress "$ipaddr" -HostHeader "$domain" +# 绑定 SSL 证书 +$binding.AddSslCertificate($thumbprint, "My") +# 删除目录下的证书文件 +Remove-Item -Path "$pfxPath" -Force + `.trim(); + + case "ps_binding_netsh": + return `# 需要管理员权限 +# 请将以下变量替换为实际值 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 +$ipaddr = "" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名。 +$port = "" # 绑定端口 + +$addr = $ipaddr + ":" + $port + +# 导入证书到本地计算机的个人存储区 +$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable +# 获取 Thumbprint +$thumbprint = $cert.Thumbprint +# 检测端口是否绑定证书,如绑定则删除绑定 +$isExist = netsh http show sslcert ipport=$addr +if ($isExist -like "*$addr*"){ netsh http delete sslcert ipport=$addr } +# 绑定到端口 +netsh http add sslcert ipport=$addr certhash=$thumbprint +# 删除目录下的证书文件 +Remove-Item -Path "$pfxPath" -Force + `.trim(); + + case "ps_binding_rdp": + return `# 需要管理员权限 +# 请将以下变量替换为实际值 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 + +# 导入证书到本地计算机的个人存储区 +$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable +# 获取 Thumbprint +$thumbprint = $cert.Thumbprint +# 绑定到 RDP +$rdpCertPath = "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp" +Set-ItemProperty -Path $rdpCertPath -Name "SSLCertificateSHA1Hash" -Value "$thumbprint" + `.trim(); + } +}; + const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormLocalConfigProps) => { const { t } = useTranslation(); @@ -136,16 +238,15 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i const handlePresetPreScriptClick = (key: string) => { switch (key) { - case "backup_files": + case "sh_backup_files": + case "ps_backup_files": { + const presetScriptParams = { + certPath: formInst.getFieldValue("certPath"), + keyPath: formInst.getFieldValue("keyPath"), + }; formInst.setFieldValue("shellEnv", SHELLENV_SH); - formInst.setFieldValue( - "preCommand", - `# 请将以下路径替换为实际值 -cp "${formInst.getFieldValue("certPath") || ""}" "${formInst.getFieldValue("certPath") || ""}.bak" 2>/dev/null || : -cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFieldValue("keyPath") || ""}.bak" 2>/dev/null || : - `.trim() - ); + formInst.setFieldValue("preCommand", initPresetScript(key, presetScriptParams)); } break; } @@ -153,97 +254,23 @@ cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFi const handlePresetPostScriptClick = (key: string) => { switch (key) { - case "reload_nginx": + case "sh_reload_nginx": { formInst.setFieldValue("shellEnv", SHELLENV_SH); - formInst.setFieldValue("postCommand", "sudo service nginx reload"); + formInst.setFieldValue("postCommand", initPresetScript(key)); } break; - case "binding_iis": + case "ps_binding_iis": + case "ps_binding_netsh": + case "ps_binding_rdp": { + const presetScriptParams = { + certPath: formInst.getFieldValue("certPath"), + pfxPassword: formInst.getFieldValue("pfxPassword"), + }; formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL); - formInst.setFieldValue( - "postCommand", - `# 请将以下变量替换为实际值 -$pfxPath = "${formInst.getFieldValue("certPath") || ""}" # PFX 文件路径 -$pfxPassword = "${formInst.getFieldValue("pfxPassword") || ""}" # PFX 密码 -$siteName = "" # IIS 网站名称 -$domain = "" # 域名 -$ipaddr = "" # 绑定 IP,“*”表示所有 IP 绑定 -$port = "" # 绑定端口 - - -# 导入证书到本地计算机的个人存储区 -$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable -# 获取 Thumbprint -$thumbprint = $cert.Thumbprint -# 导入 WebAdministration 模块 -Import-Module WebAdministration -# 检查是否已存在 HTTPS 绑定 -$existingBinding = Get-WebBinding -Name "$siteName" -Protocol "https" -Port $port -HostHeader "$domain" -ErrorAction SilentlyContinue -if (!$existingBinding) { - # 添加新的 HTTPS 绑定 - New-WebBinding -Name "$siteName" -Protocol "https" -Port $port -IPAddress "$ipaddr" -HostHeader "$domain" -} -# 获取绑定对象 -$binding = Get-WebBinding -Name "$siteName" -Protocol "https" -Port $port -IPAddress "$ipaddr" -HostHeader "$domain" -# 绑定 SSL 证书 -$binding.AddSslCertificate($thumbprint, "My") -# 删除目录下的证书文件 -Remove-Item -Path "$pfxPath" -Force - `.trim() - ); - } - break; - - case "binding_netsh": - { - formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL); - formInst.setFieldValue( - "postCommand", - `# 请将以下变量替换为实际值 -$pfxPath = "${formInst.getFieldValue("certPath") || ""}" # PFX 文件路径 -$pfxPassword = "${formInst.getFieldValue("pfxPassword") || ""}" # PFX 密码 -$ipaddr = "" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名。 -$port = "" # 绑定端口 - -$addr = $ipaddr + ":" + $port - -# 导入证书到本地计算机的个人存储区 -$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable -# 获取 Thumbprint -$thumbprint = $cert.Thumbprint -# 检测端口是否绑定证书,如绑定则删除绑定 -$isExist = netsh http show sslcert ipport=$addr -if ($isExist -like "*$addr*"){ netsh http delete sslcert ipport=$addr } -# 绑定到端口 -netsh http add sslcert ipport=$addr certhash=$thumbprint -# 删除目录下的证书文件 -Remove-Item -Path "$pfxPath" -Force - `.trim() - ); - } - break; - - case "binding_rdp": - { - formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL); - formInst.setFieldValue( - "postCommand", - `# 请将以下变量替换为实际值 -$pfxPath = "${formInst.getFieldValue("certPath") || ""}" # PFX 文件路径 -$pfxPassword = "${formInst.getFieldValue("pfxPassword") || ""}" # PFX 密码 - -# 导入证书到本地计算机的个人存储区 -$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable -# 获取 Thumbprint -$thumbprint = $cert.Thumbprint -# 绑定到 RDP -$rdpCertPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Set-ItemProperty -Path $rdpCertPath -Name "SSLCertificateSHA1Hash" -Value "$thumbprint" - `.trim() - ); + formInst.setFieldValue("postCommand", initPresetScript(key, presetScriptParams)); } break; } @@ -359,13 +386,11 @@ Set-ItemProperty -Path $rdpCertPath -Name "SSLCertificateSHA1Hash" -Value "$thum
handlePresetPreScriptClick("backup_files"), - }, - ], + items: ["sh_backup_files", "ps_backup_files"].map((key) => ({ + key, + label: t(`workflow_node.deploy.form.local_preset_scripts.option.${key}.label`), + onClick: () => handlePresetPreScriptClick(key), + })), }} trigger={["click"]} > @@ -391,28 +416,11 @@ Set-ItemProperty -Path $rdpCertPath -Name "SSLCertificateSHA1Hash" -Value "$thum
handlePresetPostScriptClick("reload_nginx"), - }, - { - key: "binding_iis", - label: t("workflow_node.deploy.form.local_preset_scripts.option.binding_iis.label"), - onClick: () => handlePresetPostScriptClick("binding_iis"), - }, - { - key: "binding_netsh", - label: t("workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label"), - onClick: () => handlePresetPostScriptClick("binding_netsh"), - }, - { - key: "binding_rdp", - label: t("workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label"), - onClick: () => handlePresetPostScriptClick("binding_rdp"), - }, - ], + items: ["sh_reload_nginx", "ps_binding_iis", "ps_binding_netsh", "ps_binding_rdp"].map((key) => ({ + key, + label: t(`workflow_node.deploy.form.local_preset_scripts.option.${key}.label`), + onClick: () => handlePresetPostScriptClick(key), + })), }} trigger={["click"]} > diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx index 5f13e29d..21d76222 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx @@ -7,6 +7,8 @@ import { z } from "zod"; import Show from "@/components/Show"; import { CERTIFICATE_FORMATS } from "@/domain/certificate"; +import { initPresetScript } from "./DeployNodeConfigFormLocalConfig"; + type DeployNodeConfigFormSSHConfigFieldValues = Nullish<{ format: string; certPath: string; @@ -129,15 +131,14 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini const handlePresetPreScriptClick = (key: string) => { switch (key) { - case "backup_files": + case "sh_backup_files": + case "ps_backup_files": { - formInst.setFieldValue( - "preCommand", - `# 请将以下路径替换为实际值 -cp "${formInst.getFieldValue("certPath") || ""}" "${formInst.getFieldValue("certPath") || ""}.bak" 2>/dev/null || : -cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFieldValue("keyPath") || ""}.bak" 2>/dev/null || : - `.trim() - ); + const presetScriptParams = { + certPath: formInst.getFieldValue("certPath"), + keyPath: formInst.getFieldValue("keyPath"), + }; + formInst.setFieldValue("preCommand", initPresetScript(key, presetScriptParams)); } break; } @@ -145,9 +146,16 @@ cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFi const handlePresetPostScriptClick = (key: string) => { switch (key) { - case "reload_nginx": + case "sh_reload_nginx": + case "ps_binding_iis": + case "ps_binding_netsh": + case "ps_binding_rdp": { - formInst.setFieldValue("postCommand", "sudo service nginx reload"); + const presetScriptParams = { + certPath: formInst.getFieldValue("certPath"), + pfxPassword: formInst.getFieldValue("pfxPassword"), + }; + formInst.setFieldValue("postCommand", initPresetScript(key, presetScriptParams)); } break; } @@ -253,13 +261,11 @@ cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFi
handlePresetPreScriptClick("backup_files"), - }, - ], + items: ["sh_backup_files", "ps_backup_files"].map((key) => ({ + key, + label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`), + onClick: () => handlePresetPreScriptClick(key), + })), }} trigger={["click"]} > @@ -285,13 +291,11 @@ cp "${formInst.getFieldValue("keyPath") || ""}" "${formInst.getFi
handlePresetPostScriptClick("reload_nginx"), - }, - ], + items: ["sh_reload_nginx", "ps_binding_iis", "ps_binding_netsh", "ps_binding_rdp"].map((key) => ({ + key, + label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`), + onClick: () => handlePresetPostScriptClick(key), + })), }} trigger={["click"]} > diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 6ebbba63..60e6641f 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -466,11 +466,12 @@ "workflow_node.deploy.form.local_post_command.label": "Post-command (Optional)", "workflow_node.deploy.form.local_post_command.placeholder": "Please enter command to be executed after saving files", "workflow_node.deploy.form.local_preset_scripts.button": "Use preset scripts", - "workflow_node.deploy.form.local_preset_scripts.option.backup_files.label": "POSIX Bash - Backup certificate files", - "workflow_node.deploy.form.local_preset_scripts.option.reload_nginx.label": "POSIX Bash - Reload nginx", - "workflow_node.deploy.form.local_preset_scripts.option.binding_iis.label": "PowerShell - Binding IIS", - "workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - Binding netsh", - "workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label": "PowerShell - Binding RDP", + "workflow_node.deploy.form.local_preset_scripts.option.sh_backup_files.label": "POSIX Bash - Backup certificate files", + "workflow_node.deploy.form.local_preset_scripts.option.ps_backup_files.label": "PowerShell - Backup certificate files", + "workflow_node.deploy.form.local_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - Reload nginx", + "workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - Binding IIS", + "workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - Binding netsh", + "workflow_node.deploy.form.local_preset_scripts.option.ps_.label": "PowerShell - Binding RDP", "workflow_node.deploy.form.qiniu_cdn_domain.label": "Qiniu CDN domain", "workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "Please enter Qiniu CDN domain name", "workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "For more information, see https://portal.qiniu.com/cdn", @@ -524,8 +525,12 @@ "workflow_node.deploy.form.ssh_post_command.label": "Post-command (Optional)", "workflow_node.deploy.form.ssh_post_command.placeholder": "Please enter command to be executed after uploading files", "workflow_node.deploy.form.ssh_preset_scripts.button": "Use preset scripts", - "workflow_node.deploy.form.ssh_preset_scripts.option.backup_files.label": "POSIX Bash - Backup certificate files", - "workflow_node.deploy.form.ssh_preset_scripts.option.reload_nginx.label": "POSIX Bash - Reload nginx", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_backup_files.label": "POSIX Bash - Backup certificate files", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_backup_files.label": "PowerShell - Backup certificate files", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - Reload nginx", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_iis.label": "PowerShell - Binding IIS", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_netsh.label": "PowerShell - Binding netsh", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - Binding RDP", "workflow_node.deploy.form.ssh_use_scp.label": "Fallback to use SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "If the remote server does not support SFTP, please enable this option to fallback to SCP.", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "Tencent Cloud CDN domain", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 28e4b54d..cdff1cf9 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -465,11 +465,12 @@ "workflow_node.deploy.form.local_post_command.label": "后置命令(可选)", "workflow_node.deploy.form.local_post_command.placeholder": "请输入保存文件后执行的命令", "workflow_node.deploy.form.local_preset_scripts.button": "使用预设脚本", - "workflow_node.deploy.form.local_preset_scripts.option.backup_files.label": "POSIX Bash - 备份原证书文件", - "workflow_node.deploy.form.local_preset_scripts.option.reload_nginx.label": "POSIX Bash - 重启 nginx 进程", - "workflow_node.deploy.form.local_preset_scripts.option.binding_iis.label": "PowerShell - 导入并绑定到 IIS(需管理员权限)", - "workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - 导入并绑定到 netsh(需管理员权限)", - "workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label": "PowerShell - 导入并绑定到 远程桌面连接(需管理员权限)", + "workflow_node.deploy.form.local_preset_scripts.option.sh_backup_files.label": "POSIX Bash - 备份原证书文件", + "workflow_node.deploy.form.local_preset_scripts.option.ps_backup_files.label": "PowerShell - 备份原证书文件", + "workflow_node.deploy.form.local_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - 重启 nginx 进程", + "workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - 导入并绑定到 IIS", + "workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - 导入并绑定到 netsh", + "workflow_node.deploy.form.local_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP", "workflow_node.deploy.form.qiniu_cdn_domain.label": "七牛云 CDN 加速域名", "workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "请输入七牛云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "这是什么?请参阅 https://portal.qiniu.com/cdn", @@ -523,8 +524,12 @@ "workflow_node.deploy.form.ssh_post_command.label": "后置命令(可选)", "workflow_node.deploy.form.ssh_post_command.placeholder": "请输入保存文件后执行的命令", "workflow_node.deploy.form.ssh_preset_scripts.button": "使用预设脚本", - "workflow_node.deploy.form.ssh_preset_scripts.option.backup_files.label": "POSIX Bash - 备份原证书文件", - "workflow_node.deploy.form.ssh_preset_scripts.option.reload_nginx.label": "POSIX Bash - 重启 nginx 进程", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_backup_files.label": "POSIX Bash - 备份原证书文件", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_backup_files.label": "PowerShell - 备份原证书文件", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - 重启 nginx 进程", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_iis.label": "PowerShell - 导入并绑定到 IIS", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_netsh.label": "PowerShell - 导入并绑定到 netsh", + "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP", "workflow_node.deploy.form.ssh_use_scp.label": "回退使用 SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "如果你的远程服务器不支持 SFTP,请开启此选项回退为 SCP。", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "腾讯云 CDN 加速域名",