From 12ed79ca60fad29bab9f68755bda37c3bce1cae9 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Tue, 10 Jun 2025 18:41:25 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E9=9B=A8=E4=BA=91=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/plugin-rainyun/access.ts | 90 +++++++++++++++++++ .../plugins/plugin-rainyun/dns-provider.ts | 88 ++++++++++++++++++ .../src/plugins/plugin-rainyun/index.ts | 2 + .../plugins/plugin-rainyun/plugins/index.ts | 0 4 files changed, 180 insertions(+) create mode 100644 packages/ui/certd-server/src/plugins/plugin-rainyun/access.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-rainyun/dns-provider.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts create mode 100644 packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts diff --git a/packages/ui/certd-server/src/plugins/plugin-rainyun/access.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/access.ts new file mode 100644 index 00000000..d11848d1 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-rainyun/access.ts @@ -0,0 +1,90 @@ +import {AccessInput, BaseAccess, IsAccess} from "@certd/pipeline"; +import {HttpRequestConfig} from "@certd/basic"; + + +/** + */ +@IsAccess({ + name: "rainyun", + title: "雨云授权", + desc: "https://app.rainyun.com/", + icon: "svg:icon-lucky" +}) +export class RainyunAccess extends BaseAccess { + + + @AccessInput({ + title: "ApiKey", + component: { + placeholder: "api-key", + component: { + name: "a-input", + vModel: "value" + } + }, + encrypt: true, + required: true + }) + apiKey!: string; + + + + @AccessInput({ + title: "测试", + component: { + name: "api-test", + action: "TestRequest" + }, + helper: "点击测试接口是否正常" + }) + testRequest = true; + + async onTestRequest() { + await this.getDomainList({}); + return "ok" + } + + // {"columnFilters":{"domains.Domain":"domain"},"sort":[],"page":1,"perPage":20} + async getDomainList(req:{offset?:number,size?:number,query?:string}){ + const size = req.size ?? 20; + const offset = req.offset ?? 0; + const page = offset % size === 0 ? offset / size : Math.floor(offset / size) + 1; + const options ={ + page: page, + perPage: size, + columnFilters: { + "domains.Domain": req.query??"" + }, + } + return await this.doRequest({ + url: "/product/domain/", + method: "GET", + params: { + options: JSON.stringify(options) + } + }); + } + + async doRequest(req:HttpRequestConfig){ + const res = await this.ctx.http.request({ + url: req.url, + baseURL:"https://api.v2.rainyun.com", + method: req.method|| "POST", + data: req.data, + params: req.params, + headers:{ + "x-api-key": this.apiKey + }, + // httpProxy: this.httpProxy||undefined, + }); + + if (res.code === 200) { + return res.data; + } + throw new Error(res.message || res); + } +} + + + +new RainyunAccess(); diff --git a/packages/ui/certd-server/src/plugins/plugin-rainyun/dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/dns-provider.ts new file mode 100644 index 00000000..4d0f9118 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-rainyun/dns-provider.ts @@ -0,0 +1,88 @@ +import {AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions} from '@certd/plugin-cert'; +import {RainyunAccess} from "./access.js"; + +@IsDnsProvider({ + name: 'rainyun', + title: '雨云', + desc: '雨云DNS解析提供商', + accessType: 'rainyun', + icon: 'svg:icon-lucky', + order:0, +}) +export class RainyunDnsProvider extends AbstractDnsProvider { + + client: any; + async onInstance() { + + } + + async createRecord(options: CreateRecordOptions): Promise { + + const access: RainyunAccess = this.ctx.access as RainyunAccess + console.log(access) + const { fullRecord,hostRecord, value, type, domain } = options; + this.logger.info('添加域名解析:', fullRecord, value, domain); + // const domain = await this.matchDomain(fullRecord); + const params = { + RegionId: 'cn-hangzhou', + DomainName: domain, + RR: hostRecord, + Type: type, + Value: value, + // Line: 'oversea' // 海外 + }; + + const requestOption = { + method: 'POST', + }; + try { + const ret = await this.client.request('AddDomainRecord', params, requestOption); + this.logger.info('添加域名解析成功:', JSON.stringify(options), ret.RecordId); + return ret.RecordId; + } catch (e: any) { + if (e.code === 'DomainRecordDuplicate') { + return; + } + if(e.code === "LastOperationNotFinished"){ + this.logger.info('上一个操作还未完成,5s后重试') + await this.ctx.utils.sleep(5000) + return this.createRecord(options) + } + this.logger.info('添加域名解析出错', e); + this.resolveError(e, options); + } + } + + resolveError(e: any, req: CreateRecordOptions) { + if (e.message?.indexOf('The specified domain name does not exist') > -1) { + throw new Error(`阿里云账号中不存在此域名:${req.domain}`); + } + throw e; + } + async removeRecord(options: RemoveRecordOptions): Promise { + const { fullRecord, value } = options.recordReq; + const record = options.recordRes; + const params = { + RegionId: 'cn-hangzhou', + RecordId: record, + }; + + const requestOption = { + method: 'POST', + }; + try{ + const ret = await this.client.request('DeleteDomainRecord', params, requestOption); + this.logger.info('删除域名解析成功:', fullRecord, value, ret.RecordId); + return ret.RecordId; + }catch (e) { + if(e.code === "LastOperationNotFinished"){ + this.logger.info('上一个操作还未完成,5s后重试') + await this.ctx.utils.sleep(5000) + return this.removeRecord(options) + } + throw e + } + } +} + +new RainyunDnsProvider(); diff --git a/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/index.ts new file mode 100644 index 00000000..02dc3945 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-rainyun/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-rainyun/plugins/index.ts b/packages/ui/certd-server/src/plugins/plugin-rainyun/plugins/index.ts new file mode 100644 index 00000000..e69de29b