refactor: plugins

This commit is contained in:
xiaojunnuo
2022-11-08 22:10:42 +08:00
parent d66bc33761
commit b04d4cb5c5
113 changed files with 2815 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
import { AbstractAccess, IsAccess } from "@certd/pipeline";
@IsAccess({
name: "aliyun",
title: "阿里云授权",
desc: "",
input: {
accessKeyId: {
title: "accessKeyId",
component: {
placeholder: "accessKeyId",
},
required: true,
},
accessKeySecret: {
title: "accessKeySecret",
component: {
placeholder: "accessKeySecret",
},
required: true,
},
},
})
export class AliyunAccess extends AbstractAccess {
accessKeyId = "";
accessKeySecret = "";
}

View File

@@ -0,0 +1 @@
export * from "./aliyun-access";

View File

@@ -0,0 +1,119 @@
import Core from "@alicloud/pop-core";
import _ from "lodash";
import { AbstractDnsProvider, CreateRecordOptions, IDnsProvider, IsDnsProvider, RemoveRecordOptions } from "@certd/pipeline";
@IsDnsProvider({
name: "aliyun",
title: "阿里云",
desc: "阿里云DNS解析提供商",
accessType: "aliyun",
})
export class AliyunDnsProvider extends AbstractDnsProvider implements IDnsProvider {
client: any;
constructor() {
super();
}
async onInit() {
const access: any = this.access;
this.client = new Core({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: "https://alidns.aliyuncs.com",
apiVersion: "2015-01-09",
});
}
async getDomainList() {
const params = {
RegionId: "cn-hangzhou",
};
const requestOption = {
method: "POST",
};
const ret = await this.client.request("DescribeDomains", params, requestOption);
return ret.Domains.Domain;
}
async matchDomain(dnsRecord: string) {
const list = await this.getDomainList();
let domain = null;
for (const item of list) {
if (_.endsWith(dnsRecord, item.DomainName)) {
domain = item.DomainName;
break;
}
}
if (!domain) {
throw new Error("can not find Domain ," + dnsRecord);
}
return domain;
}
async getRecords(domain: string, rr: string, value: string) {
const params: any = {
RegionId: "cn-hangzhou",
DomainName: domain,
RRKeyWord: rr,
ValueKeyWord: undefined,
};
if (value) {
params.ValueKeyWord = value;
}
const requestOption = {
method: "POST",
};
const ret = await this.client.request("DescribeDomainRecords", params, requestOption);
return ret.DomainRecords.Record;
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type } = options;
this.logger.info("添加域名解析:", fullRecord, value);
const domain = await this.matchDomain(fullRecord);
const rr = fullRecord.replace("." + domain, "");
const params = {
RegionId: "cn-hangzhou",
DomainName: domain,
RR: rr,
Type: type,
Value: value,
// Line: 'oversea' // 海外
};
const requestOption = {
method: "POST",
};
try {
const ret = await this.client.request("AddDomainRecord", params, requestOption);
this.logger.info("添加域名解析成功:", value, value, ret.RecordId);
return ret.RecordId;
} catch (e: any) {
if (e.code === "DomainRecordDuplicate") {
return;
}
this.logger.info("添加域名解析出错", e);
throw e;
}
}
async removeRecord(options: RemoveRecordOptions): Promise<any> {
const { fullRecord, value, record } = options;
const params = {
RegionId: "cn-hangzhou",
RecordId: record,
};
const requestOption = {
method: "POST",
};
const ret = await this.client.request("DeleteDomainRecord", params, requestOption);
this.logger.info("删除域名解析成功:", fullRecord, value, ret.RecordId);
return ret.RecordId;
}
}

View File

@@ -0,0 +1 @@
import "./aliyun-dns-provider";

View File

@@ -0,0 +1,3 @@
export * from "./access";
export * from "./dns-provider";
export * from "./plugin";

View File

@@ -0,0 +1,97 @@
import { AbstractPlugin, IsTask, RunStrategy, TaskInput, TaskOutput, TaskPlugin } from "@certd/pipeline";
import dayjs from "dayjs";
import Core from "@alicloud/pop-core";
import RPCClient from "@alicloud/pop-core";
import { AliyunAccess } from "../../access";
@IsTask(() => {
return {
name: "DeployCertToAliyunCDN",
title: "部署证书至阿里云CDN",
desc: "依赖证书申请前置任务自动部署域名证书至阿里云CDN",
input: {
domainName: {
title: "CDN加速域名",
helper: "你在阿里云上配置的CDN加速域名比如certd.docmirror.cn",
required: true,
},
certName: {
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
},
cert: {
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: "pi-output-selector",
},
required: true,
},
accessId: {
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "pi-access-selector",
type: "aliyun",
},
required: true,
},
},
output: {},
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
};
})
export class DeployCertToAliyunCDN extends AbstractPlugin implements TaskPlugin {
async execute(input: TaskInput): Promise<TaskOutput> {
console.log("开始部署证书到阿里云cdn");
const access = (await this.accessService.getById(input.accessId)) as AliyunAccess;
const client = this.getClient(access);
const params = await this.buildParams(input);
await this.doRequest(client, params);
console.log("部署完成");
return {};
}
getClient(access: AliyunAccess) {
return new Core({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: "https://cdn.aliyuncs.com",
apiVersion: "2018-05-10",
});
}
async buildParams(input: TaskInput) {
const { certName, domainName } = input;
const CertName = (certName ?? "certd") + "-" + dayjs().format("YYYYMMDDHHmmss");
const cert = input.cert;
return {
RegionId: "cn-hangzhou",
DomainName: domainName,
ServerCertificateStatus: "on",
CertName: CertName,
CertType: "upload",
ServerCertificate: cert.crt,
PrivateKey: cert.key,
};
}
async doRequest(client: RPCClient, params: any) {
const requestOption = {
method: "POST",
};
const ret: any = await client.request("SetDomainServerCertificate", params, requestOption);
this.checkRet(ret);
this.logger.info("设置cdn证书成功:", ret.RequestId);
}
checkRet(ret: any) {
if (ret.code != null) {
throw new Error("执行失败:" + ret.Message);
}
}
}

View File

@@ -0,0 +1 @@
export * from "./deploy-to-cdn";