From e08cf57b72128998f487ab6469868052fbce0dba Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Mon, 26 May 2025 22:22:39 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E5=88=B0farcdn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/certd-server/src/plugins/index.ts | 1 + .../src/plugins/plugin-farcdn/access.ts | 175 ++++++++++++++++++ .../src/plugins/plugin-farcdn/index.ts | 2 + .../plugins/plugin-farcdn/plugins/index.ts | 1 + .../plugins/plugin-refresh-cert.ts | 106 +++++++++++ 5 files changed, 285 insertions(+) create mode 100644 packages/ui/certd-server/src/plugins/plugin-farcdn/access.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-farcdn/index.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/index.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/plugin-refresh-cert.ts diff --git a/packages/ui/certd-server/src/plugins/index.ts b/packages/ui/certd-server/src/plugins/index.ts index 1f49aca2..91c6961d 100644 --- a/packages/ui/certd-server/src/plugins/index.ts +++ b/packages/ui/certd-server/src/plugins/index.ts @@ -21,3 +21,4 @@ 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' diff --git a/packages/ui/certd-server/src/plugins/plugin-farcdn/access.ts b/packages/ui/certd-server/src/plugins/plugin-farcdn/access.ts new file mode 100644 index 00000000..4aacb5f3 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-farcdn/access.ts @@ -0,0 +1,175 @@ +import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline"; +import { HttpRequestConfig } from "@certd/basic"; +import { CertInfo, CertReader } from "@certd/plugin-cert"; + + +/** + */ +@IsAccess({ + name: "farcdn", + title: "farcdn授权", + desc: "", + icon: "svg:icon-lucky" +}) +export class FarcdnAccess extends BaseAccess { + @AccessInput({ + title: "接口地址", + component: { + placeholder: "https://open.farcdn.net/api/source", + name: "a-input", + vModel: "value" + }, + required: true + }) + endpoint!: string; + + + @AccessInput({ + title: "accessKeyId", + component: { + placeholder: "accessKeyId", + component: { + name: "a-input", + vModel: "value" + } + }, + encrypt: false, + required: true + }) + accessKeyId!: string; + + @AccessInput({ + title: "accessKey", + component: { + placeholder: "accessKey", + component: { + name: "a-input", + vModel: "value" + } + }, + encrypt: true, + required: true + }) + accessKey!: string; + + + @AccessInput({ + title: "测试", + component: { + name: "api-test", + action: "TestRequest" + }, + helper: "点击测试接口是否正常" + }) + testRequest = true; + + async onTestRequest() { + try{ + const data = await this.findSSLCertConfig(1); + if (data) { + return "ok"; + } + }catch (e) { + if(e.message.indexOf("null")){ + return "ok"; + } + } + + throw "测试失败,未知错误"; + } + + + async findSSLCertConfig(sslCertId: number) { + /** + * 接口地址 + * POST /findSSLCertConfig + * 🎯 功能说明 + * 根据证书ID和认证信息查询SSL证书的详细配置信息,包括证书状态、域名绑定、有效期等关键信息。 + * + * 📥 请求参数 + * 参数名 类型 必填 说明 示例值 + * sslCertId int ✅ 证书唯一标识ID 2106 + * accessKeyId string ✅ 访问密钥ID u2ZF6k63dFCOS7It + * accessKey string ✅ 访问密钥 mTGaNRGUFHj3r3YxMrrg5XSGIXd6rBWG', + * 响应结构: + * + * { + * "code": 200, + * "data": {...}, + * "message": "获取成功" + * } + */ + + const params = { + sslCertId, + }; + return await this.doRequest({ + url: "/findSSLCertConfig", + data: params + }); + } + + async updateSSLCert(req:{ + sslCertId: number, + cert:CertInfo, + }){ + /** + * isOn boolean ✅ 是否启用证书 true + * name string ✅ 证书显示名称 "example.com" + * description string ✅ 证书描述信息 "主域名SSL证书" + * serverName string ✅ 关联的服务器名称 "web-server-01" + * isCA boolean ✅ 是否为CA根证书 false + * certData string ✅ 证书内容(PEM格式) "-----BEGIN CERTIFICATE-----..." + * keyData string ✅ 私钥内容(PEM格式) "-----BEGIN PRIVATE KEY-----..." + * timeBeginAt int/long ✅ 证书生效时间(毫秒时间戳) 1719830400000 + * timeEndAt int/long ✅ 证书过期时间(毫秒时间戳) 1751366400000 + * dnsNames string[] ✅ 证书绑定的域名列表 ["example.com", "*.example.com"] + * commonNames string[] ✅ 证书的通用名称列表 ["example.com"] + */ + + const oldCert = await this.findSSLCertConfig(req.sslCertId) + const certReader = new CertReader(req.cert) + const {detail} = certReader.getCrtDetail(); + const params = { + sslCertId: req.sslCertId, + certData: req.cert.crt, + keyData: req.cert.key, + isOn: true, + isCA: false, + commonNames: [certReader.getMainDomain()], + dnsNames: certReader.getAltNames(), + timeBeginAt: detail.notBefore, + timeEndAt: detail.notAfter, + name: oldCert.name|| certReader.buildCertName(), + description:oldCert.description||"" + } + + return await this.doRequest({ + url: "/updateSSLCert", + data: params + }); + } + + async doRequest(req:HttpRequestConfig){ + const params = { + ...req.data, + accessKeyId: this.accessKeyId, + accessKey: this.accessKey + }; + const res = await this.ctx.http.request({ + url: req.url, + baseURL:this.endpoint, + method: "POST", + data: params + }); + + if (res.data.code === 200) { + return res.data.data; + } + throw new Error(res.data.message); + } +} + + + +new FarcdnAccess(); diff --git a/packages/ui/certd-server/src/plugins/plugin-farcdn/index.ts b/packages/ui/certd-server/src/plugins/plugin-farcdn/index.ts new file mode 100644 index 00000000..02dc3945 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-farcdn/index.ts @@ -0,0 +1,2 @@ +export * from "./plugins/index.js"; +export * from "./access.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/index.ts new file mode 100644 index 00000000..b8237e4f --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/index.ts @@ -0,0 +1 @@ +export * from "./plugin-refresh-cert.js"; diff --git a/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/plugin-refresh-cert.ts b/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/plugin-refresh-cert.ts new file mode 100644 index 00000000..8d91f6ec --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-farcdn/plugins/plugin-refresh-cert.ts @@ -0,0 +1,106 @@ +import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; +import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert"; +import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib"; +import { FarcdnAccess } from "../access.js"; +import { AbstractPlusTaskPlugin } from "@certd/plugin-plus"; + +@IsTaskPlugin({ + //命名规范,插件类型+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名 + name: "FarcdnRefreshCert", + title: "farcdn-更新证书", + icon: "svg:icon-lucky", + //插件分组 + group: pluginGroups.cdn.key, + needPlus: true, + default: { + //默认值配置照抄即可 + strategy: { + runStrategy: RunStrategy.SkipWhenSucceed + } + } +}) +//类名规范,跟上面插件名称(name)一致 +export class FarcdnRefreshCert extends AbstractPlusTaskPlugin { + //证书选择,此项必须要有 + @TaskInput({ + title: "域名证书", + helper: "请选择前置任务输出的域名证书", + component: { + name: "output-selector", + from: [...CertApplyPluginNames] + } + // required: true, // 必填 + }) + cert!: CertInfo; + + @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) + certDomains!: string[]; + + //授权选择框 + @TaskInput({ + title: "Farcdn授权", + component: { + name: "access-selector", + type: "farcdn" //固定授权类型 + }, + required: true //必填 + }) + accessId!: string; + // + + @TaskInput( + createRemoteSelectInputDefine({ + title: "证书Id", + helper: "要更新的Farcdn证书id", + action: FarcdnRefreshCert.prototype.onGetCertList.name + }) + ) + certList!: number[]; + + //插件实例化时执行的方法 + async onInstance() { + } + + //插件执行方法 + async execute(): Promise { + const access = await this.getAccess(this.accessId); + + for (const item of this.certList) { + this.logger.info(`----------- 开始更新证书:${item}`); + await access.updateSSLCert({ + sslCertId:item, + cert: this.cert, + }) + this.logger.info(`----------- 更新证书${item}成功`); + } + + this.logger.info("部署完成"); + } + + async onGetCertList() { + throw new Error("暂无查询证书列表接口"); + // const access = await this.getAccess(this.accessId); + + // const res = await access.doRequest({ + // url: "/SSLCertService/listSSLCerts", + // data: { size: 1000 }, + // method: "POST" + // }); + // const list = JSON.parse(this.ctx.utils.hash.base64Decode(res.sslCertsJSON)); + // if (!list || list.length === 0) { + // throw new Error("没有找到证书,请先在控制台上传一次证书且关联网站"); + // } + // + // const options = list.map((item: any) => { + // return { + // label: `${item.name}<${item.id}-${item.dnsNames[0]}>`, + // value: item.id, + // domain: item.dnsNames + // }; + // }); + // return this.ctx.utils.options.buildGroupOptions(options, this.certDomains); + } +} + +//实例化一下,注册插件 +new FarcdnRefreshCert();