From 90d1b68bd6cf232fbe085234efe07d29b7690044 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Sun, 17 Nov 2024 02:01:44 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=85=BE=E8=AE=AF?= =?UTF-8?q?=E4=BA=91=20cloudflare=20=E9=87=8D=E5=A4=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=97=B6=E7=9A=84=E8=BF=94=E5=9B=9E=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/basic/src/utils/util.request.ts | 5 +- .../plugins/plugin-cloudflare/dns-provider.ts | 62 ++++++++++++++----- .../dns-provider/huawei-dns-provider.ts | 4 ++ .../dns-provider/tencent-dns-provider.ts | 20 +++++- 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/packages/core/basic/src/utils/util.request.ts b/packages/core/basic/src/utils/util.request.ts index 73867523..dd1cbe49 100644 --- a/packages/core/basic/src/utils/util.request.ts +++ b/packages/core/basic/src/utils/util.request.ts @@ -178,7 +178,10 @@ export function createAxiosService({ logger }: { logger: Logger }) { ); logger.error('返回数据:', JSON.stringify(error.response?.data)); if (error.response?.data) { - error.message = error.response.data.message || error.response.data.msg || error.response.data.error || error.response.data; + const message = error.response.data.message || error.response.data.msg || error.response.data.error; + if (typeof message === 'string') { + error.message = message; + } } if (error instanceof AggregateError) { logger.error('AggregateError', error); diff --git a/packages/ui/certd-server/src/plugins/plugin-cloudflare/dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-cloudflare/dns-provider.ts index f4eedb61..d7b168ad 100644 --- a/packages/ui/certd-server/src/plugins/plugin-cloudflare/dns-provider.ts +++ b/packages/ui/certd-server/src/plugins/plugin-cloudflare/dns-provider.ts @@ -49,19 +49,31 @@ export class CloudflareDnsProvider extends AbstractDnsProvider } private async doRequestApi(url: string, data: any = null, method = 'post') { - const res = await this.http.request({ - url, - method, - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.access.apiToken}`, - }, - data, - }); - if (!res.success) { - throw new Error(`${JSON.stringify(res.errors)}`); + try { + const res = await this.http.request({ + url, + method, + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.access.apiToken}`, + }, + data, + }); + + if (!res.success) { + throw new Error(`${JSON.stringify(res.errors)}`); + } + return res; + } catch (e: any) { + const data = e.response?.data; + if (data && data.success === false && data.errors && data.errors.length > 0) { + if (data.errors[0].code === 81058) { + this.logger.info('dns解析记录重复'); + return null; + } + } + throw e; } - return res; } /** @@ -88,14 +100,30 @@ export class CloudflareDnsProvider extends AbstractDnsProvider type: type, ttl: 60, }); - const record = res.result as CloudflareRecord; - this.logger.info(`添加域名解析成功:fullRecord=${fullRecord},value=${value}`); - this.logger.info(`dns解析记录:${JSON.stringify(record)}`); - + let record: any = null; + if (res == null) { + //重复的记录 + this.logger.info(`dns解析记录重复,无需重复添加`); + record = await this.findRecord(zoneId, options); + } else { + record = res.result as CloudflareRecord; + this.logger.info(`添加域名解析成功:fullRecord=${fullRecord},value=${value}`); + this.logger.info(`dns解析记录:${JSON.stringify(record)}`); + } //本接口需要返回本次创建的dns解析记录,这个记录会在删除的时候用到 return record; } + async findRecord(zoneId: string, options: CreateRecordOptions): Promise { + const { fullRecord, value } = options; + const url = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records?type=TXT&name=${fullRecord}&content=${value}`; + const res = await this.doRequestApi(url, null, 'get'); + if (res.result.length === 0) { + return null; + } + return res.result[0] as CloudflareRecord; + } + /** * 删除dns解析记录,清理申请痕迹 * @param options @@ -105,7 +133,7 @@ export class CloudflareDnsProvider extends AbstractDnsProvider const record = options.recordRes; this.logger.info('删除域名解析:', fullRecord, value); if (!record) { - this.logger.info('record不存在'); + this.logger.info('record为空,不执行删除'); return; } //这里调用删除txt dns解析记录接口 diff --git a/packages/ui/certd-server/src/plugins/plugin-huawei/dns-provider/huawei-dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-huawei/dns-provider/huawei-dns-provider.ts index 57896c62..64092559 100644 --- a/packages/ui/certd-server/src/plugins/plugin-huawei/dns-provider/huawei-dns-provider.ts +++ b/packages/ui/certd-server/src/plugins/plugin-huawei/dns-provider/huawei-dns-provider.ts @@ -105,6 +105,10 @@ export class HuaweiDnsProvider extends AbstractDnsProvider { async removeRecord(options: RemoveRecordOptions): Promise { const { fullRecord, value } = options.recordReq; const record = options.recordRes; + if (!record) { + this.logger.info('解析记录recordId为空,不执行删除', fullRecord, value); + return; + } const req: ApiRequestOptions = { url: `${this.dnsEndpoint}/v2/zones/${record.zone_id}/recordsets/${record.id}`, method: 'DELETE', diff --git a/packages/ui/certd-server/src/plugins/plugin-tencent/dns-provider/tencent-dns-provider.ts b/packages/ui/certd-server/src/plugins/plugin-tencent/dns-provider/tencent-dns-provider.ts index 704635b0..6c50dc1a 100644 --- a/packages/ui/certd-server/src/plugins/plugin-tencent/dns-provider/tencent-dns-provider.ts +++ b/packages/ui/certd-server/src/plugins/plugin-tencent/dns-provider/tencent-dns-provider.ts @@ -65,15 +65,33 @@ export class TencentDnsProvider extends AbstractDnsProvider { } catch (e: any) { if (e?.code === 'InvalidParameter.DomainRecordExist') { this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value); - return {}; + return await this.findRecord(options); } throw e; } } + async findRecord(options: CreateRecordOptions): Promise { + const params = { + Domain: options.domain, + RecordType: [options.type], + Keyword: options.hostRecord, + RecordValue: options.value, + }; + const ret = await this.client.DescribeRecordFilterList(params); + if (ret.RecordList && ret.RecordList.length > 0) { + this.logger.info('已存在解析记录:', ret.RecordList); + return ret.RecordList[0]; + } + return {}; + } + async removeRecord(options: RemoveRecordOptions) { const { fullRecord, value, domain } = options.recordReq; const record = options.recordRes; + if (!record) { + this.logger.info('解析记录recordId为空,不执行删除', fullRecord, value); + } const params = { Domain: domain, RecordId: record.RecordId,