diff --git a/docs/guide/plugins/deploy.md b/docs/guide/plugins/deploy.md index c6316d269..a649594b4 100644 --- a/docs/guide/plugins/deploy.md +++ b/docs/guide/plugins/deploy.md @@ -1,5 +1,5 @@ # 任务插件 -共 `111` 款任务插件 +共 `113` 款任务插件 ## 1. 证书申请 | 序号 | 名称 | 说明 | @@ -13,11 +13,13 @@ | 序号 | 名称 | 说明 | |-----|-----|-----| | 1.| **主机-执行远程主机脚本命令** | 可以执行重启nginx等操作让证书生效 | -| 2.| **主机-部署证书到SSH主机** | SFTP上传证书到主机,然后SSH执行部署脚本命令 | +| 2.| **主机-部署证书到SSH主机** | 上传证书到主机覆盖原来的证书文件,然后自动执行部署脚本命令使证书生效 | | 3.| **主机-复制到本机** | 【仅管理员使用】实际上是复制证书到docker容器内的某个路径,需要做目录映射到宿主机 | | 4.| **上传证书到对象存储OSS** | 支持阿里云OSS、腾讯云COS、七牛云KODO、S3、MinIO、FTP、SFTP | | 5.| **IIS-部署到IIS站点** | | | 6.| **FTP-上传证书到FTP** | 将证书上传到FTP服务器 | +| 7.| **Exsi-部署证书到Exsi** | | +| 8.| **Openwrt-部署证书到Openwrt** | | ## 3. CDN | 序号 | 名称 | 说明 | @@ -63,7 +65,7 @@ | 11.| **K8S-部署证书到Secret** | 部署证书到k8s的secret | | 12.| **K8S-Ingress 证书部署** | 部署证书到k8s的Ingress | | 13.| **K8S-Apply自定义yaml** | apply自定义yaml到k8s | -| 14.| **1Panel-部署证书到1Panel** | 更新1Panel的证书 | +| 14.| **1Panel-更新证书** | 更新1Panel的证书,包括面板证书和站点证书 | | 15.| **1Panel-部署面板证书** | 更新1Panel的面板证书 | | 16.| **Plesk-部署Plesk网站证书** | | | 17.| **雷池-更新证书** | 更新长亭雷池WAF的证书 | diff --git a/packages/ui/certd-server/.env b/packages/ui/certd-server/.env index 345247b4a..2a245bd94 100644 --- a/packages/ui/certd-server/.env +++ b/packages/ui/certd-server/.env @@ -1,2 +1,2 @@ LEGO_VERSION=4.30.1 -certd_plugin_loadmode=metadata \ No newline at end of file +certd_plugin_loadmode=dev \ No newline at end of file diff --git a/packages/ui/certd-server/before-build.js b/packages/ui/certd-server/before-build.js index 83729f5d1..5265c0311 100644 --- a/packages/ui/certd-server/before-build.js +++ b/packages/ui/certd-server/before-build.js @@ -17,3 +17,5 @@ function slimming(filePath, find, rep) { }); } slimming(filePath, find, rep); + +slimming("./tsconfig.json",`"sourceMap": true,`, `"sourceMap": false,`) diff --git a/packages/ui/certd-server/metadata/deploy_1PanelDeployToWebsitePlugin.yaml b/packages/ui/certd-server/metadata/deploy_1PanelDeployToWebsitePlugin.yaml index 7b2181965..a45fe4792 100644 --- a/packages/ui/certd-server/metadata/deploy_1PanelDeployToWebsitePlugin.yaml +++ b/packages/ui/certd-server/metadata/deploy_1PanelDeployToWebsitePlugin.yaml @@ -3,9 +3,9 @@ default: strategy: runStrategy: 1 name: 1PanelDeployToWebsitePlugin -title: 1Panel-部署证书到1Panel +title: 1Panel-更新证书 icon: svg:icon-onepanel -desc: 更新1Panel的证书 +desc: 更新1Panel的证书,包括面板证书和站点证书 group: panel needPlus: false input: diff --git a/packages/ui/certd-server/metadata/deploy_ExsiDeployCert.yaml b/packages/ui/certd-server/metadata/deploy_ExsiDeployCert.yaml new file mode 100644 index 000000000..2e7c94cd5 --- /dev/null +++ b/packages/ui/certd-server/metadata/deploy_ExsiDeployCert.yaml @@ -0,0 +1,30 @@ +showRunStrategy: false +default: + strategy: + runStrategy: 1 +name: ExsiDeployCert +title: Exsi-部署证书到Exsi +icon: svg:icon-lucky +group: host +needPlus: true +input: + cert: + title: 域名证书 + helper: 请选择前置任务输出的域名证书 + component: + name: output-selector + from: + - ':cert:' + required: true + order: 0 + accessId: + title: 主机SSH授权 + component: + name: access-selector + type: ssh + required: true + order: 0 +output: {} +pluginType: deploy +type: builtIn +scriptFilePath: /plugins/plugin-plus/exsi/plugin-deploy-to-exsi.js diff --git a/packages/ui/certd-server/metadata/deploy_OpenwrtDeployCert.yaml b/packages/ui/certd-server/metadata/deploy_OpenwrtDeployCert.yaml new file mode 100644 index 000000000..2c8ed1f53 --- /dev/null +++ b/packages/ui/certd-server/metadata/deploy_OpenwrtDeployCert.yaml @@ -0,0 +1,30 @@ +showRunStrategy: false +default: + strategy: + runStrategy: 1 +name: OpenwrtDeployCert +title: Openwrt-部署证书到Openwrt +icon: svg:icon-lucky +group: host +needPlus: true +input: + cert: + title: 域名证书 + helper: 请选择前置任务输出的域名证书 + component: + name: output-selector + from: + - ':cert:' + required: true + order: 0 + accessId: + title: 主机SSH授权 + component: + name: access-selector + type: ssh + required: true + order: 0 +output: {} +pluginType: deploy +type: builtIn +scriptFilePath: /plugins/plugin-plus/openwrt/plugin-deploy-to-openwrt.js diff --git a/packages/ui/certd-server/metadata/deploy_uploadCertToHost.yaml b/packages/ui/certd-server/metadata/deploy_uploadCertToHost.yaml index aaa8cf8a9..d11fb8b02 100644 --- a/packages/ui/certd-server/metadata/deploy_uploadCertToHost.yaml +++ b/packages/ui/certd-server/metadata/deploy_uploadCertToHost.yaml @@ -6,7 +6,7 @@ name: uploadCertToHost title: 主机-部署证书到SSH主机 icon: line-md:uploading-loop group: host -desc: SFTP上传证书到主机,然后SSH执行部署脚本命令 +desc: 上传证书到主机覆盖原来的证书文件,然后自动执行部署脚本命令使证书生效 order: 1 input: cert: @@ -20,12 +20,14 @@ input: order: 0 certType: title: 证书格式 - helper: 要部署的证书格式,支持pem、pfx、der、jks + helper: |- + 要部署的证书格式,支持pem/crt、pfx、der、jks、p7b + 你原来的证书是哪种格式就选择哪种 component: name: a-select options: - value: pem - label: pem(crt),Nginx等大部分应用 + label: pem/crt,用于Nginx等大部分应用,证书和私钥2个文件 - value: pfx label: pfx,一般用于IIS - value: der diff --git a/packages/ui/certd-server/src/modules/auto/auto-b-load-plugins.ts b/packages/ui/certd-server/src/modules/auto/auto-b-load-plugins.ts index 9439b0a3e..700aab8e9 100644 --- a/packages/ui/certd-server/src/modules/auto/auto-b-load-plugins.ts +++ b/packages/ui/certd-server/src/modules/auto/auto-b-load-plugins.ts @@ -16,7 +16,14 @@ export class AutoBLoadPlugins { if (process.env.certd_plugin_loadmode === "metadata") { await this.pluginService.registerFromLocal("./metadata") }else{ - await import("../../plugins/index.js") + // await import("../../plugins/index.js") + const fs = await import("fs"); + const list = fs.readdirSync("../../plugins"); + for (const file of list) { + if (file.endsWith("index.js")) { + await import(`../../plugins/${file}`); + } + } } // await import("../../plugins/index.js") await this.pluginService.registerFromDb() diff --git a/packages/ui/certd-server/src/plugins/index.ts b/packages/ui/certd-server/src/plugins/index.ts index 1644c5952..e8cfc47d7 100644 --- a/packages/ui/certd-server/src/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/index.ts @@ -1,47 +1,47 @@ -export * from './plugin-aliyun/index.js'; -export * from './plugin-tencent/index.js'; -export * from './plugin-host/index.js'; -export * from './plugin-huawei/index.js'; -export * from './plugin-demo/index.js'; -export * from './plugin-other/index.js'; -export * from './plugin-west/index.js'; -export * from './plugin-doge/index.js'; -export * from './plugin-qiniu/index.js'; -export * from './plugin-woai/index.js'; -export * from './plugin-cachefly/index.js'; -export * from './plugin-gcore/index.js'; -export * from './plugin-qnap/index.js'; -export * from './plugin-aws/index.js'; -export * from './plugin-aws-cn/index.js'; -export * from './plugin-dnsla/index.js'; -export * from './plugin-upyun/index.js'; -export * from './plugin-volcengine/index.js' -export * from './plugin-jdcloud/index.js' -export * from './plugin-51dns/index.js' -export * from './plugin-notification/index.js' -export * from './plugin-flex/index.js' -export * from './plugin-farcdn/index.js' -export * from './plugin-fnos/index.js' -export * from './plugin-rainyun/index.js' -export * from './plugin-cloudflare/index.js' -export * from './plugin-github/index.js' -export * from './plugin-namesilo/index.js' -export * from './plugin-proxmox/index.js' -export * from './plugin-wangsu/index.js' -export * from './plugin-admin/index.js' -export * from './plugin-ksyun/index.js' -export * from './plugin-apisix/index.js' -export * from './plugin-dokploy/index.js' -export * from './plugin-godaddy/index.js' -export * from './plugin-captcha/index.js' -export * from './plugin-xinnet/index.js' -export * from './plugin-xinnetconnet/index.js' -export * from './plugin-oauth/index.js' -export * from './plugin-cmcc/index.js' -export * from './plugin-template/index.js' -export * from './plugin-ucloud/index.js' -export * from './plugin-goedge/index.js' -export * from './plugin-lib/index.js' -export * from './plugin-plus/index.js' -export * from './plugin-cert/index.js' -export * from './plugin-zenlayer/index.js' \ No newline at end of file +// export * from './plugin-aliyun/index.js'; +// export * from './plugin-tencent/index.js'; +// export * from './plugin-host/index.js'; +// export * from './plugin-huawei/index.js'; +// export * from './plugin-demo/index.js'; +// export * from './plugin-other/index.js'; +// export * from './plugin-west/index.js'; +// export * from './plugin-doge/index.js'; +// export * from './plugin-qiniu/index.js'; +// export * from './plugin-woai/index.js'; +// export * from './plugin-cachefly/index.js'; +// export * from './plugin-gcore/index.js'; +// export * from './plugin-qnap/index.js'; +// export * from './plugin-aws/index.js'; +// export * from './plugin-aws-cn/index.js'; +// export * from './plugin-dnsla/index.js'; +// export * from './plugin-upyun/index.js'; +// export * from './plugin-volcengine/index.js' +// export * from './plugin-jdcloud/index.js' +// export * from './plugin-51dns/index.js' +// export * from './plugin-notification/index.js' +// export * from './plugin-flex/index.js' +// export * from './plugin-farcdn/index.js' +// export * from './plugin-fnos/index.js' +// export * from './plugin-rainyun/index.js' +// export * from './plugin-cloudflare/index.js' +// export * from './plugin-github/index.js' +// export * from './plugin-namesilo/index.js' +// export * from './plugin-proxmox/index.js' +// export * from './plugin-wangsu/index.js' +// export * from './plugin-admin/index.js' +// export * from './plugin-ksyun/index.js' +// export * from './plugin-apisix/index.js' +// export * from './plugin-dokploy/index.js' +// export * from './plugin-godaddy/index.js' +// export * from './plugin-captcha/index.js' +// export * from './plugin-xinnet/index.js' +// export * from './plugin-xinnetconnet/index.js' +// export * from './plugin-oauth/index.js' +// export * from './plugin-cmcc/index.js' +// export * from './plugin-template/index.js' +// export * from './plugin-ucloud/index.js' +// export * from './plugin-goedge/index.js' +// export * from './plugin-lib/index.js' +// export * from './plugin-plus/index.js' +// export * from './plugin-cert/index.js' +// export * from './plugin-zenlayer/index.js' \ No newline at end of file diff --git a/packages/ui/certd-server/src/plugins/plugin-plus/exsi/index.ts b/packages/ui/certd-server/src/plugins/plugin-plus/exsi/index.ts new file mode 100644 index 000000000..193261153 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-plus/exsi/index.ts @@ -0,0 +1 @@ +export * from "./plugin-deploy-to-exsi.js"; \ No newline at end of file diff --git a/packages/ui/certd-server/src/plugins/plugin-plus/exsi/plugin-deploy-to-exsi.ts b/packages/ui/certd-server/src/plugins/plugin-plus/exsi/plugin-deploy-to-exsi.ts new file mode 100644 index 000000000..255069586 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-plus/exsi/plugin-deploy-to-exsi.ts @@ -0,0 +1,90 @@ +import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; +import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert"; +import { AbstractPlusTaskPlugin, CertReader } from "@certd/plugin-lib"; +import { SshAccess } from "../../plugin-lib/ssh/ssh-access.js"; +import { SshClient } from "../../plugin-lib/ssh/ssh.js"; +@IsTaskPlugin({ + name: "ExsiDeployCert", + title: "Exsi-部署证书到Exsi", + icon: "svg:icon-lucky", + group: pluginGroups.host.key, + default: { + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed, + }, + }, + needPlus: true, +}) +export class ExsiDeployCertPlugin extends AbstractPlusTaskPlugin { + //证书选择,此项必须要有 + @TaskInput({ + title: "域名证书", + helper: "请选择前置任务输出的域名证书", + component: { + name: "output-selector", + from: [...CertApplyPluginNames], + }, + required: true, + }) + cert!: CertInfo; + + // @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) + // certDomains!: string[]; + + //授权选择框 + @TaskInput({ + title: "主机SSH授权", + component: { + name: "access-selector", + type: "ssh", + }, + required: true, + }) + accessId!: string; + + + async onInstance() { } + + async execute(): Promise { + const sshConf = await this.getAccess(this.accessId); + const sshClient = new SshClient(this.logger); + + // /etc/vmware/ssl/rui.crt + // /etc/vmware/ssl/rui.key + const certReader = new CertReader(this.cert); + + await certReader.readCertFile({ + logger: this.logger, + handle: async (ctx) => { + const crtPath = ctx.tmpCrtPath; + const keyPath = ctx.tmpKeyPath; + sshClient.uploadFiles({ + connectConf: sshConf, + transports: [ + { + localPath: crtPath, + remotePath: "/etc/vmware/ssl/rui.crt", + }, + { + localPath: keyPath, + remotePath: "/etc/vmware/ssl/rui.key", + }, + ], + mkdirs: true, + }); + }, + }); + + const cmd = `/etc/init.d/hostd restart +/etc/init.d/vpxa restart` + + await sshClient.exec({ + connectConf: sshConf, + script: cmd, + }); + + this.logger.info(`证书部署完成`); + } +} + +new ExsiDeployCertPlugin(); diff --git a/packages/ui/certd-server/src/plugins/plugin-plus/index.ts b/packages/ui/certd-server/src/plugins/plugin-plus/index.ts index db6d7be3a..f4d98f5a1 100644 --- a/packages/ui/certd-server/src/plugins/plugin-plus/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-plus/index.ts @@ -19,3 +19,5 @@ export * from "./kuocai/index.js"; export * from "./unicloud/index.js"; export * from "./maoyun/index.js"; export * from "./xinnet/index.js"; +export * from "./exsi/index.js"; +export * from "./openwrt/index.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/index.ts b/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/index.ts new file mode 100644 index 000000000..2a5313d2b --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/index.ts @@ -0,0 +1 @@ +export * from "./plugin-deploy-to-openwrt.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/plugin-deploy-to-openwrt.ts b/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/plugin-deploy-to-openwrt.ts new file mode 100644 index 000000000..9c3955836 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-plus/openwrt/plugin-deploy-to-openwrt.ts @@ -0,0 +1,90 @@ +import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; +import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert"; +import { AbstractPlusTaskPlugin, CertReader } from "@certd/plugin-lib"; +import { SshAccess } from "../../plugin-lib/ssh/ssh-access.js"; +import { SshClient } from "../../plugin-lib/ssh/ssh.js"; +@IsTaskPlugin({ + name: "OpenwrtDeployCert", + title: "Openwrt-部署证书到Openwrt", + icon: "svg:icon-lucky", + group: pluginGroups.host.key, + default: { + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed, + }, + }, + needPlus: true, +}) +export class OpenwrtDeployCertPlugin extends AbstractPlusTaskPlugin { + //证书选择,此项必须要有 + @TaskInput({ + title: "域名证书", + helper: "请选择前置任务输出的域名证书", + component: { + name: "output-selector", + from: [...CertApplyPluginNames], + }, + required: true, + }) + cert!: CertInfo; + + // @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) + // certDomains!: string[]; + + //授权选择框 + @TaskInput({ + title: "主机SSH授权", + component: { + name: "access-selector", + type: "ssh", + }, + required: true, + }) + accessId!: string; + + + async onInstance() { } + + async execute(): Promise { + const sshConf = await this.getAccess(this.accessId); + const sshClient = new SshClient(this.logger); + + // /etc/vmware/ssl/rui.crt + // /etc/vmware/ssl/rui.key + const certReader = new CertReader(this.cert); + + await certReader.readCertFile({ + logger: this.logger, + handle: async (ctx) => { + const crtPath = ctx.tmpCrtPath; + const keyPath = ctx.tmpKeyPath; + sshClient.uploadFiles({ + connectConf: sshConf, + transports: [ + { + localPath: crtPath, + remotePath: "/etc/uhttpd.crt", + }, + { + localPath: keyPath, + remotePath: "/etc/uhttpd.key", + }, + ], + mkdirs: true, + }); + }, + }); + + this.logger.info(`证书上传完成,准备重启uhttpd生效`); + const cmd = `/etc/init.d/uhttpd restart` + + await sshClient.exec({ + connectConf: sshConf, + script: cmd, + }); + + this.logger.info(`证书部署完成`); + } +} + +new OpenwrtDeployCertPlugin();