Files
certd/packages/ui/certd-server/src/plugins/plugin-tencent/dns-provider/dnspod-dns-provider.ts
T

128 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-06-14 01:25:30 +08:00
import { Autowire, HttpClient, ILogger } from "@certd/pipeline";
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import _ from "lodash";
import { DnspodAccess } from "../access";
2022-11-07 23:31:20 +08:00
@IsDnsProvider({
name: 'dnspod',
title: 'dnspod(腾讯云)',
desc: '腾讯云的域名解析接口已迁移到dnspod',
accessType: 'dnspod',
2022-11-07 23:31:20 +08:00
})
2024-06-14 01:25:30 +08:00
export class DnspodDnsProvider extends AbstractDnsProvider {
2023-01-11 20:39:48 +08:00
@Autowire()
2022-12-27 12:32:09 +08:00
http!: HttpClient;
2023-01-11 20:39:48 +08:00
@Autowire()
2022-12-27 12:32:09 +08:00
access!: DnspodAccess;
2023-01-11 20:39:48 +08:00
@Autowire()
2022-12-27 12:32:09 +08:00
logger!: ILogger;
2022-11-07 23:31:20 +08:00
loginToken: any;
2022-12-27 12:32:09 +08:00
endpoint = '';
2023-05-09 10:16:49 +08:00
async onInstance() {
2022-11-07 23:31:20 +08:00
const access: DnspodAccess = this.access as DnspodAccess;
this.loginToken = access.id + ',' + access.token;
this.endpoint = access.endpoint || 'https://dnsapi.cn';
2022-11-07 23:31:20 +08:00
}
async doRequest(options: any, successCodes: string[] = []) {
const config: any = {
// @ts-ignore
method: 'post',
2022-11-07 23:31:20 +08:00
formData: {
login_token: this.loginToken,
format: 'json',
lang: 'cn',
error_on_empty: 'no',
2022-11-07 23:31:20 +08:00
},
timeout: 5000,
};
_.merge(config, options);
const ret: any = await this.http.request(config);
if (!ret || !ret.status) {
const code = ret.status.code;
if (code !== '1' || !successCodes.includes(code)) {
throw new Error(
'请求失败:' + ret.status.message + ',api=' + config.url
);
2022-11-07 23:31:20 +08:00
}
}
return ret;
}
async getDomainList() {
const ret = await this.doRequest({
url: this.access.endpoint + '/Domain.List',
2022-11-07 23:31:20 +08:00
});
this.logger.info('dnspod 域名列表:', ret.domains);
2022-11-07 23:31:20 +08:00
return ret.domains;
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type } = options;
this.logger.info('添加域名解析:', fullRecord, value);
2022-11-07 23:31:20 +08:00
const domainItem = await this.matchDomain(fullRecord);
const domain = domainItem.name;
const rr = fullRecord.replace('.' + domain, '');
2022-11-07 23:31:20 +08:00
const ret = await this.doRequest(
{
url: this.access.endpoint + '/Record.Create',
2022-11-07 23:31:20 +08:00
formData: {
domain,
sub_domain: rr,
record_type: type,
record_line: '默认',
2022-11-07 23:31:20 +08:00
value: value,
mx: 1,
},
},
['104']
2022-11-07 23:31:20 +08:00
); // 104错误码为记录已存在,无需再次添加
this.logger.info(
'添加域名解析成功:',
fullRecord,
value,
JSON.stringify(ret.record)
);
2022-11-07 23:31:20 +08:00
return ret.record;
}
async removeRecord(options: RemoveRecordOptions) {
const { fullRecord, value, record } = options;
const domain = await this.matchDomain(fullRecord);
const ret = await this.doRequest({
url: this.access.endpoint + '/Record.Remove',
2022-11-07 23:31:20 +08:00
formData: {
domain,
record_id: record.id,
},
});
this.logger.info('删除域名解析成功:', fullRecord, value);
2022-11-07 23:31:20 +08:00
return ret.RecordId;
}
async matchDomain(dnsRecord: any) {
const list = await this.getDomainList();
if (list == null) {
throw new Error('域名列表不能为空');
2024-03-21 22:33:11 +08:00
}
2022-11-07 23:31:20 +08:00
let domain = null;
for (const item of list) {
if (_.endsWith(dnsRecord, '.' + item.name)) {
2022-11-07 23:31:20 +08:00
domain = item;
break;
}
}
if (!domain) {
throw new Error('找不到域名,请检查域名是否正确:' + dnsRecord);
2022-11-07 23:31:20 +08:00
}
return domain;
}
}
2023-05-09 09:56:31 +08:00
new DnspodDnsProvider();