mirror of https://github.com/certd/certd
perf: 支持部署到阿里云WAF
parent
b805a29259
commit
c96fcb7afc
|
@ -0,0 +1,199 @@
|
|||
import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import {
|
||||
AbstractPlusTaskPlugin,
|
||||
AliyunAccess,
|
||||
AliyunClient,
|
||||
AliyunSslClient,
|
||||
createCertDomainGetterInputDefine,
|
||||
createRemoteSelectInputDefine,
|
||||
} from '@certd/plugin-plus';
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'AliyunDeployCertToWaf',
|
||||
title: '部署至阿里云WAF',
|
||||
icon: 'ant-design:aliyun-outlined',
|
||||
group: pluginGroups.aliyun.key,
|
||||
desc: '部署证书到阿里云WAF',
|
||||
needPlus: true,
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
})
|
||||
export class AliyunDeployCertToWaf extends AbstractPlusTaskPlugin {
|
||||
@TaskInput({
|
||||
title: '域名证书',
|
||||
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
cert!: CertInfo | number;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: 'WAF接入点',
|
||||
helper: '不会选就按默认',
|
||||
value: 'cn-hangzhou',
|
||||
component: {
|
||||
name: 'a-select',
|
||||
options: [
|
||||
{ value: 'cn-hangzhou', label: '中国大陆-华东1(杭州)' },
|
||||
{ value: 'ap-southeast-1', label: '新加坡' },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
regionId!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: '证书接入点',
|
||||
helper: '跟上面保持一致即可',
|
||||
value: 'cas.aliyuncs.com',
|
||||
component: {
|
||||
name: 'a-select',
|
||||
options: [
|
||||
{ value: 'cas.aliyuncs.com', label: '中国大陆' },
|
||||
{ value: 'cas.ap-southeast-1.aliyuncs.com', label: '新加坡' },
|
||||
{ value: 'cas.eu-central-1.aliyuncs.com', label: '德国(法兰克福)' },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
casEndpoint!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: 'Access授权',
|
||||
helper: '阿里云授权AccessKeyId、AccessKeySecret',
|
||||
component: {
|
||||
name: 'access-selector',
|
||||
type: 'aliyun',
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: 'CNAME站点',
|
||||
helper: '请选择要部署证书的CNAME站点',
|
||||
typeName: 'AliyunDeployCertToWaf',
|
||||
action: AliyunDeployCertToWaf.prototype.onGetCnameList.name,
|
||||
watches: ['accessId', 'regionId'],
|
||||
})
|
||||
)
|
||||
cnameDomains!: string[];
|
||||
|
||||
async onInstance() {}
|
||||
|
||||
async getWafClient(access: AliyunAccess) {
|
||||
const client = new AliyunClient({ logger: this.logger });
|
||||
await client.init({
|
||||
accessKeyId: access.accessKeyId,
|
||||
accessKeySecret: access.accessKeySecret,
|
||||
//https://wafopenapi.cn-hangzhou.aliyuncs.com
|
||||
endpoint: `https://wafopenapi.${this.regionId}.aliyuncs.com`,
|
||||
apiVersion: '2021-10-01',
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
async getInstanceId(client: AliyunClient) {
|
||||
const params = {
|
||||
RegionId: 'cn-hangzhou',
|
||||
};
|
||||
const res = await client.request('DescribeInstance', params);
|
||||
this.logger.info('获取实例ID', res.InstanceId);
|
||||
return res.InstanceId;
|
||||
}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info('开始部署证书到阿里云');
|
||||
const access = await this.accessService.getById<AliyunAccess>(this.accessId);
|
||||
let certId: any = this.cert;
|
||||
if (typeof this.cert === 'object') {
|
||||
const sslClient = new AliyunSslClient({
|
||||
access,
|
||||
logger: this.logger,
|
||||
endpoint: this.casEndpoint,
|
||||
});
|
||||
|
||||
certId = await sslClient.uploadCert({
|
||||
name: this.appendTimeSuffix('certd'),
|
||||
cert: this.cert,
|
||||
});
|
||||
}
|
||||
|
||||
const client = await this.getWafClient(access);
|
||||
const instanceId = await this.getInstanceId(client);
|
||||
for (const siteDomain of this.cnameDomains) {
|
||||
const params = {
|
||||
RegionId: this.regionId,
|
||||
InstanceId: instanceId,
|
||||
Domain: siteDomain,
|
||||
};
|
||||
const siteDetail = await client.request('DescribeDomainDetail', params);
|
||||
this.logger.info('站点详情', JSON.stringify(siteDetail));
|
||||
const listen = siteDetail.Listen;
|
||||
/**
|
||||
* "HttpsPorts": [
|
||||
* 443
|
||||
* ],
|
||||
* "CertId": "14738336-cn-hangzhou",
|
||||
*/
|
||||
const redirect = siteDetail.Redirect;
|
||||
redirect.Backends = redirect.AllBackends;
|
||||
listen.CertId = certId + '-' + this.regionId;
|
||||
if (!listen.HttpsPorts || listen.HttpsPorts.length === 0) {
|
||||
listen.HttpsPorts = [443];
|
||||
}
|
||||
const updateParams = {
|
||||
InstanceId: instanceId,
|
||||
RegionId: this.regionId,
|
||||
Redirect: JSON.stringify(redirect),
|
||||
Listen: JSON.stringify(listen),
|
||||
Domain: siteDomain,
|
||||
};
|
||||
const res = await client.request('ModifyDomain', updateParams);
|
||||
this.logger.info('部署成功', JSON.stringify(res));
|
||||
}
|
||||
}
|
||||
|
||||
async onGetCnameList(data: any) {
|
||||
if (!this.accessId) {
|
||||
throw new Error('请选择Access授权');
|
||||
}
|
||||
const access = await this.accessService.getById<AliyunAccess>(this.accessId);
|
||||
const client = await this.getWafClient(access);
|
||||
|
||||
const instanceId = await this.getInstanceId(client);
|
||||
const params = {
|
||||
RegionId: this.regionId,
|
||||
InstanceId: instanceId,
|
||||
PageSize: 50,
|
||||
};
|
||||
|
||||
const res = await client.request('DescribeDomains', params);
|
||||
if (!res?.Domains || res?.Domains.length === 0) {
|
||||
throw new Error('没有找到CNAME接入的域名站点');
|
||||
}
|
||||
|
||||
const options = res.Domains.map((item: any) => {
|
||||
return {
|
||||
label: item.Domain,
|
||||
value: item.Domain,
|
||||
title: item.Domain,
|
||||
domain: item.Domain,
|
||||
};
|
||||
});
|
||||
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
|
||||
}
|
||||
}
|
||||
|
||||
new AliyunDeployCertToWaf();
|
|
@ -2,3 +2,4 @@ export * from './deploy-to-cdn/index.js';
|
|||
export * from './deploy-to-dcdn/index.js';
|
||||
export * from './deploy-to-oss/index.js';
|
||||
export * from './upload-to-aliyun/index.js';
|
||||
export * from './deploy-to-waf/index.js';
|
||||
|
|
Loading…
Reference in New Issue