From 80159ecca895103d0495f3217311199e66056572 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Mon, 18 Nov 2024 18:23:11 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81namesilo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 需要志愿者提供apikey和domain来做测试 --- .../src/plugin/cert-plugin/base.ts | 5 +- packages/ui/certd-server/package.json | 1 + .../src/plugins/plugin-namesilo/access.ts | 28 +++++ .../plugins/plugin-namesilo/dns-provider.ts | 109 ++++++++++++++++++ .../src/plugins/plugin-namesilo/index.ts | 2 + 5 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 packages/ui/certd-server/src/plugins/plugin-namesilo/access.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-namesilo/dns-provider.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-namesilo/index.ts diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts index a1053399..e396d4db 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base.ts @@ -140,7 +140,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { } this._result.pipelinePrivateVars.cert = cert; - if (cert.pfx == null || cert.der == null || cert.jks == null) { + if (isNew) { try { const converter = new CertConverter({ logger: this.logger }); const res = await converter.convert({ @@ -151,21 +151,18 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin { const pfxBuffer = fs.readFileSync(res.pfxPath); cert.pfx = pfxBuffer.toString("base64"); fs.unlinkSync(res.pfxPath); - isNew = true; } if (cert.der == null && res.derPath) { const derBuffer = fs.readFileSync(res.derPath); cert.der = derBuffer.toString("base64"); fs.unlinkSync(res.derPath); - isNew = true; } if (cert.jks == null && res.jksPath) { const jksBuffer = fs.readFileSync(res.jksPath); cert.jks = jksBuffer.toString("base64"); fs.unlinkSync(res.jksPath); - isNew = true; } this.logger.info("转换证书格式成功"); diff --git a/packages/ui/certd-server/package.json b/packages/ui/certd-server/package.json index 750e7ed9..a3141f77 100644 --- a/packages/ui/certd-server/package.json +++ b/packages/ui/certd-server/package.json @@ -84,6 +84,7 @@ "pg": "^8.12.0", "psl": "^1.9.0", "qiniu": "^7.12.0", + "qs": "^6.13.1", "querystring": "^0.2.1", "reflect-metadata": "^0.2.2", "rimraf": "^5.0.5", diff --git a/packages/ui/certd-server/src/plugins/plugin-namesilo/access.ts b/packages/ui/certd-server/src/plugins/plugin-namesilo/access.ts new file mode 100644 index 00000000..f35ed9a9 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-namesilo/access.ts @@ -0,0 +1,28 @@ +import { IsAccess, AccessInput, BaseAccess } from '@certd/pipeline'; + +/** + * 这个注解将注册一个授权配置 + * 在certd的后台管理系统中,用户可以选择添加此类型的授权 + */ +@IsAccess({ + name: 'namesilo', + title: 'namesilo授权', + desc: '', +}) +export class NamesiloAccess extends BaseAccess { + /** + * 授权属性配置 + */ + @AccessInput({ + title: 'API Key', + component: { + placeholder: 'api key', + }, + helper: '前往 [获取API Key](https://www.namesilo.com/account/api-manager)', + required: true, + encrypt: true, + }) + apiKey = ''; +} + +new NamesiloAccess(); diff --git a/packages/ui/certd-server/src/plugins/plugin-namesilo/dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-namesilo/dns-provider.ts new file mode 100644 index 00000000..af14bed5 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-namesilo/dns-provider.ts @@ -0,0 +1,109 @@ +import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert'; +import { Autowire } from '@certd/pipeline'; +import { HttpClient, ILogger } from '@certd/basic'; +import qs from 'qs'; +import { NamesiloAccess } from './access.js'; +import { merge } from 'lodash-es'; + +export type NamesiloRecord = { + record_id: string; +}; + +// 这里通过IsDnsProvider注册一个dnsProvider +@IsDnsProvider({ + name: 'namesilo', + title: 'namesilo', + desc: 'namesilo dns provider', + // 这里是对应的 cloudflare的access类型名称 + accessType: 'namesilo', +}) +export class NamesiloDnsProvider extends AbstractDnsProvider { + // 通过Autowire传递context + @Autowire() + logger!: ILogger; + access!: NamesiloAccess; + http!: HttpClient; + async onInstance() { + //一些初始化的操作 + // 也可以通过ctx成员变量传递context, 与Autowire效果一样 + this.access = this.ctx.access as NamesiloAccess; + this.http = this.ctx.http; + } + + private async doRequest(url: string, params: any = null) { + params = merge( + { + version: 1, + type: 'json', + key: this.access.apiKey, + }, + params + ); + const qsString = qs.stringify(params); + url = `${url}?${qsString}`; + const res = await this.http.request({ + url, + baseURL: 'https://www.namesilo.com', + method: 'get', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (res.reply?.code !== '300') { + throw new Error(`${JSON.stringify(res.reply.detail)}`); + } + return res.reply; + } + + /** + * 创建dns解析记录,用于验证域名所有权 + */ + async createRecord(options: CreateRecordOptions): Promise { + /** + * fullRecord: '_acme-challenge.test.example.com', + * value: 一串uuid + * type: 'TXT', + * domain: 'example.com' + */ + const { fullRecord, hostRecord, value, type, domain } = options; + this.logger.info('添加域名解析:', fullRecord, value, type, domain); + + //domain=namesilo.com&rrtype=A&rrhost=test&rrvalue=55.55.55.55&rrttl=7207 + const record: any = await this.doRequest('/api/dnsAddRecord', { + domain, + rrtype: type, + rrhost: hostRecord, + rrvalue: value, + rrttl: 10, + }); + + //本接口需要返回本次创建的dns解析记录,这个记录会在删除的时候用到 + return record; + } + + /** + * 删除dns解析记录,清理申请痕迹 + * @param options + */ + async removeRecord(options: RemoveRecordOptions): Promise { + const { fullRecord, value } = options.recordReq; + const record = options.recordRes; + this.logger.info('删除域名解析:', fullRecord, value); + if (!record && !record.record_id) { + this.logger.info('record为空,不执行删除'); + return; + } + //这里调用删除txt dns解析记录接口 + + const recordId = record.record_id; + await this.doRequest('/api/dnsDeleteRecord', { + domain: options.recordReq.domain, + record_id: recordId, + }); + this.logger.info(`删除域名解析成功:fullRecord=${fullRecord},value=${value}`); + } +} + +//实例化这个provider,将其自动注册到系统中 +new NamesiloDnsProvider(); diff --git a/packages/ui/certd-server/src/plugins/plugin-namesilo/index.ts b/packages/ui/certd-server/src/plugins/plugin-namesilo/index.ts new file mode 100644 index 00000000..db899c71 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-namesilo/index.ts @@ -0,0 +1,2 @@ +export * from './dns-provider.js'; +export * from './access.js';