chore: format

This commit is contained in:
xiaojunnuo
2026-05-31 01:41:33 +08:00
parent acd440106b
commit 4b57a0d729
557 changed files with 12530 additions and 14039 deletions
@@ -1,15 +1,15 @@
import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { AbstractPlusTaskPlugin } from "@certd/plugin-plus";
import dayjs from 'dayjs';
import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js';
import { AliyunSslClient } from '../../../plugin-lib/aliyun/lib/index.js';
import dayjs from "dayjs";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'AliyunDeleteExpiringCert',
title: '阿里云-删除即将过期证书',
icon: 'ant-design:aliyun-outlined',
name: "AliyunDeleteExpiringCert",
title: "阿里云-删除即将过期证书",
icon: "ant-design:aliyun-outlined",
group: pluginGroups.aliyun.key,
desc: '仅删除未使用的证书',
desc: "仅删除未使用的证书",
default: {
strategy: {
runStrategy: RunStrategy.AlwaysRun,
@@ -19,28 +19,28 @@ import { AliyunSslClient } from '../../../plugin-lib/aliyun/lib/index.js';
})
export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '地域',
helper: '阿里云CAS证书服务地域',
title: "地域",
helper: "阿里云CAS证书服务地域",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cas.aliyuncs.com', label: '中国大陆' },
{ value: 'cas.ap-southeast-1.aliyuncs.com', label: '新加坡' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
],
},
required: true,
value: 'cas.aliyuncs.com',
value: "cas.aliyuncs.com",
})
endpoint!: string;
@@ -55,36 +55,36 @@ export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
// searchKey!: string;
@TaskInput({
title: '最大删除数量',
helper: '单次运行最大删除数量',
title: "最大删除数量",
helper: "单次运行最大删除数量",
value: 100,
component: {
name: 'a-input-number',
vModel: 'value',
name: "a-input-number",
vModel: "value",
},
required: true,
})
maxCount!: number;
@TaskInput({
title: '即将过期天数',
helper: '仅删除有效期小于此天数的证书,0表示完全过期时才删除',
title: "即将过期天数",
helper: "仅删除有效期小于此天数的证书,0表示完全过期时才删除",
value: 0,
component: {
name: 'a-input-number',
vModel: 'value',
name: "a-input-number",
vModel: "value",
},
required: true,
})
expiringDays!: number;
@TaskInput({
title: '检查超时时间',
helper: '检查删除任务结果超时时间,单位分钟',
title: "检查超时时间",
helper: "检查删除任务结果超时时间,单位分钟",
value: 10,
component: {
name: 'a-input-number',
vModel: 'value',
name: "a-input-number",
vModel: "value",
},
required: true,
})
@@ -106,17 +106,17 @@ export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
// Keyword: this.searchKey,
};
const certificates: any[] = [];
while(true){
const res = await sslClient.doRequest('ListCertificates', params, {
method: 'POST',
});
while (true) {
const res = await sslClient.doRequest("ListCertificates", params, {
method: "POST",
});
let list = res?.CertificateList;
if (!list || list.length === 0) {
break;
}
this.logger.info(`查询第${params.CurrentPage}页,每页${params.ShowSize}个证书,当前页共${list.length}个证书`);
const lastDay = dayjs().add(this.expiringDays, 'day');
const lastDay = dayjs().add(this.expiringDays, "day");
list = list.filter((item: any) => {
const notAfter = item.NotAfter;
const usingProducts = item.UsingProductList;
@@ -131,7 +131,7 @@ export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
this.logger.info(`即将过期的证书数量:${certificates.length}`);
if (certificates.length === 0) {
this.logger.info('没有即将过期的证书, 无需删除');
this.logger.info("没有即将过期的证书, 无需删除");
return;
}
this.logger.info(`开始删除证书,共${certificates.length}个证书`);
@@ -140,12 +140,15 @@ export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
for (const certificate of certificates) {
try {
const deleteRes = await sslClient.doRequest('DeleteUserCertificate', {
CertId: certificate.CertificateId,
}, { method: 'POST' });
const deleteRes = await sslClient.doRequest(
"DeleteUserCertificate",
{
CertId: certificate.CertificateId,
},
{ method: "POST" }
);
this.logger.info(`删除证书成功,证书ID:${certificate.CertificateId}, 名称:${certificate.CertificateName}, requestId:${deleteRes?.RequestId}`);
successCount++;
} catch (error: any) {
this.logger.error(`删除证书失败,证书ID:${certificate.CertificateId}, 名称:${certificate.CertificateName}, 错误:${error.message}`);
failedCount++;
@@ -156,4 +159,4 @@ export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin {
}
}
new AliyunDeleteExpiringCert();
new AliyunDeleteExpiringCert();
@@ -1,9 +1,6 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
import { AliyunClientV2 } from "../../../plugin-lib/aliyun/lib/aliyun-client-v2.js";
@@ -17,9 +14,9 @@ import { AliyunClientV2 } from "../../../plugin-lib/aliyun/lib/aliyun-client-v2.
needPlus: false,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class AliyunDeployCertToALB extends AbstractTaskPlugin {
@TaskInput({
@@ -27,9 +24,9 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
helper: "请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",
component: {
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"]
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true
required: true,
})
cert!: CertInfo | CasCertId | number;
@@ -45,10 +42,10 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
options: [
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" }
]
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true
required: true,
})
casEndpoint!: string;
@@ -57,9 +54,9 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "access-selector",
type: "aliyun"
type: "aliyun",
},
required: true
required: true,
})
accessId!: string;
@@ -69,7 +66,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
typeName: "AliyunDeployCertToALB",
single: true,
action: AliyunDeployCertToALB.prototype.onGetRegionList.name,
watches: ["accessId"]
watches: ["accessId"],
})
)
regionId: string;
@@ -80,7 +77,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
helper: "要部署证书的负载均衡ID",
typeName: "AliyunDeployCertToALB",
action: AliyunDeployCertToALB.prototype.onGetLoadBalanceList.name,
watches: ["regionId"]
watches: ["regionId"],
})
)
loadBalancers!: string[];
@@ -91,12 +88,11 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
helper: "要部署证书的监听器列表",
typeName: "AliyunDeployCertToALB",
action: AliyunDeployCertToALB.prototype.onGetListenerList.name,
watches: ["loadBalancers"]
watches: ["loadBalancers"],
})
)
listeners!: string[];
@TaskInput({
title: "部署证书类型",
value: "default",
@@ -106,18 +102,17 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
options: [
{
label: "默认证书",
value: "default"
value: "default",
},
{
label: "扩展证书",
value: "extension"
}
]
value: "extension",
},
],
},
required: true
}
)
deployType: string = "default";
required: true,
})
deployType = "default";
@TaskInput({
title: "是否清理过期证书",
@@ -126,14 +121,11 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
name: "a-switch",
vModel: "checked",
},
required: true
}
)
required: true,
})
clearExpiredCert: boolean;
async onInstance() {
}
async onInstance() {}
async getLBClient(access: AliyunAccess, region: string) {
const client = new AliyunClient({ logger: this.logger });
@@ -144,7 +136,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
accessKeySecret: access.accessKeySecret,
//https://wafopenapi.cn-hangzhou.aliyuncs.com
endpoint: `https://alb.${region}.aliyuncs.com`,
apiVersion: version
apiVersion: version,
});
return client;
}
@@ -166,9 +158,9 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
const client = await this.getLBClient(access, this.regionId);
await this.deployDefaultCert(certId, client);
}
if (this.clearExpiredCert!==false) {
if (this.clearExpiredCert !== false) {
this.logger.info(`准备开始清理过期证书`);
await this.ctx.utils.sleep(30000)
await this.ctx.utils.sleep(30000);
for (const listener of this.listeners) {
try {
await this.clearInvalidCert(albClientV2, listener);
@@ -188,9 +180,9 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
ListenerId: listener,
Certificates: [
{
CertificateId: certId
}
]
CertificateId: certId,
},
],
};
const res = await client.request("UpdateListenerAttribute", params);
@@ -212,11 +204,11 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
ListenerId: listenerId,
Certificates: [
{
CertificateId: certId
}
]
}
}
CertificateId: certId,
},
],
},
},
});
this.logger.info(`部署监听器${listenerId}的扩展证书成功`);
@@ -232,24 +224,23 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
version: "2020-06-16",
data: {
query: {
ListenerId: listener
}
}
ListenerId: listener,
},
},
};
const res = await client.doRequest(req);
const list = res.Certificates;
if (list.length === 0) {
this.logger.info(`监听器${listener}没有绑定证书`);
return
return;
}
const sslClient = new AliyunSslClient({
access: client.access,
logger: this.logger,
endpoint: this.casEndpoint
endpoint: this.casEndpoint,
});
const certIds = [];
for (const item of list) {
this.logger.info(`监听器${listener}绑定的证书${item.CertificateId},status:${item.Status},IsDefault:${item.IsDefault}`);
@@ -273,7 +264,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
}
if (invalidCertIds.length === 0) {
this.logger.info(`监听器${listener}没有过期的证书`);
return
return;
}
this.logger.info(`开始解绑过期的证书:${invalidCertIds}listener:${listener}`);
await client.doRequest({
@@ -284,13 +275,13 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
data: {
query: {
ListenerId: listener,
Certificates: invalidCertIds.map((item) => {
Certificates: invalidCertIds.map(item => {
return {
CertificateId: item
}
})
}
}
CertificateId: item,
};
}),
},
},
});
this.logger.info(`解绑过期证书成功`);
}
@@ -298,13 +289,12 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
async getAliyunCertId(access: AliyunAccess) {
let certId: any = this.cert;
if (typeof this.cert === "object") {
const certInfo = this.cert as CertInfo;
const casCert = this.cert as CasCertId;
const casCert = this.cert as CasCertId;
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
endpoint: this.casEndpoint
endpoint: this.casEndpoint,
});
if (certInfo.crt) {
@@ -313,11 +303,11 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
name: certName,
cert: certInfo,
});
certId = certIdRes.certId as any;
}else if (casCert.certId){
certId = certIdRes.certId as any;
} else if (casCert.certId) {
certId = casCert.certId;
}else{
throw new Error('证书格式错误'+JSON.stringify(this.cert));
} else {
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
@@ -341,7 +331,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
return {
label: item.LocalName,
value: item.RegionId,
endpoint: item.RegionEndpoint
endpoint: item.RegionEndpoint,
};
});
}
@@ -357,7 +347,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
const client = await this.getLBClient(access, this.regionId);
const params = {
MaxResults: 100
MaxResults: 100,
};
const res = await client.request("ListLoadBalancers", params);
this.checkRet(res);
@@ -369,7 +359,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
const label = `${item.LoadBalancerId}<${item.LoadBalancerName}}>`;
return {
label: label,
value: item.LoadBalancerId
value: item.LoadBalancerId,
};
});
}
@@ -385,7 +375,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
const client = await this.getLBClient(access, this.regionId);
const params: any = {
MaxResults: 100
MaxResults: 100,
};
if (this.loadBalancers && this.loadBalancers.length > 0) {
params.LoadBalancerIds = this.loadBalancers;
@@ -401,19 +391,16 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
return {
label: label,
value: item.ListenerId,
lbid: item.LoadBalancerId
lbid: item.LoadBalancerId,
};
});
}
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error(ret.Message);
}
}
}
new AliyunDeployCertToALB();
@@ -1,19 +1,16 @@
import {AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline';
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/ssl-client.js";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {optionsUtils} from "@certd/basic";
import { optionsUtils } from "@certd/basic";
@IsTaskPlugin({
name: 'DeployCertToAliyunApig',
title: '阿里云-部署至云原生API网关/AI网关',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunApig",
title: "阿里云-部署至云原生API网关/AI网关",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '自动部署域名证书至云原生API网关、AI网关',
desc: "自动部署域名证书至云原生API网关、AI网关",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -22,27 +19,25 @@ import {optionsUtils} from "@certd/basic";
})
export class DeployCertToAliyunApig extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
cert!: CertInfo | CasCertId |number;
cert!: CertInfo | CasCertId | number;
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: 'Access授权',
helper: '阿里云授权',
title: "Access授权",
helper: "阿里云授权",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
@@ -50,88 +45,83 @@ export class DeployCertToAliyunApig extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: '区域',
helper: '请选择区域',
title: "区域",
helper: "请选择区域",
action: DeployCertToAliyunApig.prototype.onGetRegionList.name,
watches: ['certDomains', 'accessId'],
watches: ["certDomains", "accessId"],
required: true,
component:{
name:"remote-auto-complete"
}
component: {
name: "remote-auto-complete",
},
})
)
regionEndpoint!: string;
@TaskInput({
title: "网关类型",
component: {
name: "a-select",
vModel:"value",
options:[
{value:"AI",label:"AI"},
{value:"API",label:"API"},
]
vModel: "value",
options: [
{ value: "AI", label: "AI" },
{ value: "API", label: "API" },
],
},
required: true //必填
required: true, //必填
})
gatewayType!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '绑定域名',
helper: '请选择域名',
title: "绑定域名",
helper: "请选择域名",
action: DeployCertToAliyunApig.prototype.onGetDomainList.name,
watches: ['region', 'accessId','gatewayType'],
watches: ["region", "accessId", "gatewayType"],
required: true,
})
)
domainList!: string[];
@TaskInput({
title: "强制HTTPS",
component: {
name: "a-select",
vModel:"value",
options:[
{value:true,label:"强制HTTPS"},
{value:false,label:"不强制HTTPS"},
]
vModel: "value",
options: [
{ value: true, label: "强制HTTPS" },
{ value: false, label: "不强制HTTPS" },
],
},
required: true //必填
required: true, //必填
})
forceHttps!: boolean;
@TaskInput({
title: '证书服务接入点',
helper: '不会选就按默认',
value: 'cn-hangzhou',
title: "证书服务接入点",
helper: "不会选就按默认",
value: "cn-hangzhou",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cn-hangzhou', label: '中国大陆' },
{ value: 'ap-southeast-1', label: '新加坡' },
{ value: "cn-hangzhou", label: "中国大陆" },
{ value: "ap-southeast-1", label: "新加坡" },
],
},
required: true,
})
casRegion!: string;
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始部署证书到云原生Api网关');
if(!this.domainList){
throw new Error('您还未选择域名');
this.logger.info("开始部署证书到云原生Api网关");
if (!this.domainList) {
throw new Error("您还未选择域名");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient(this.regionEndpoint)
const client = access.getClient(this.regionEndpoint);
let certId: any = this.cert;
if (typeof this.cert === 'object') {
if (typeof this.cert === "object") {
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
@@ -146,25 +136,23 @@ export class DeployCertToAliyunApig extends AbstractTaskPlugin {
name: this.buildCertName(CertReader.getMainDomain(certInfo.crt)),
cert: certInfo,
});
}else{
throw new Error('证书格式错误'+JSON.stringify(this.cert));
} else {
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
const certIdentify = `${certId}-${this.casRegion}`
const certIdentify = `${certId}-${this.casRegion}`;
for (const domainId of this.domainList ) {
this.logger.info(`[${domainId}]开始部署`)
await this.updateCert(client, domainId,certIdentify);
this.logger.info(`[${domainId}]部署成功`)
for (const domainId of this.domainList) {
this.logger.info(`[${domainId}]开始部署`);
await this.updateCert(client, domainId, certIdentify);
this.logger.info(`[${domainId}]部署成功`);
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async updateCert(client: any, domainId: string,certIdentify:string) {
async updateCert(client: any, domainId: string, certIdentify: string) {
const domainInfoRes = await client.doRequest({
action: "GetDomain",
version: "2024-03-27",
@@ -175,57 +163,56 @@ export class DeployCertToAliyunApig extends AbstractTaskPlugin {
pathname: `/v1/domains/${domainId}`,
});
const tlsCipherSuitesConfig = domainInfoRes.data?.tlsCipherSuitesConfig
const tlsCipherSuitesConfig = domainInfoRes.data?.tlsCipherSuitesConfig;
const ret = await client.doRequest({
action: "UpdateDomain",
version: "2024-03-27",
method: "PUT",
style: "ROA",
pathname: `/v1/domains/${domainId}`,
data:{
body:{
const ret = await client.doRequest({
action: "UpdateDomain",
version: "2024-03-27",
method: "PUT",
style: "ROA",
pathname: `/v1/domains/${domainId}`,
data: {
body: {
certIdentifier: certIdentify,
protocol: "HTTPS",
forceHttps:this.forceHttps,
tlsCipherSuitesConfig
}
}
})
forceHttps: this.forceHttps,
tlsCipherSuitesConfig,
},
},
});
this.logger.info(`设置${domainId}证书成功:`, ret.requestId);
}
async onGetDomainList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
if (!this.regionEndpoint) {
throw new Error('请选择区域');
throw new Error("请选择区域");
}
if (!this.gatewayType) {
throw new Error('请选择网关类型');
throw new Error("请选择网关类型");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient(this.regionEndpoint)
const client = access.getClient(this.regionEndpoint);
const res =await client.doRequest({
action: "ListDomains",
version: "2024-03-27",
method: "GET",
style: "ROA",
pathname: `/v1/domains`,
data:{
query:{
pageSize: 100,
gatewayType: this.gatewayType ,
}
}
})
const res = await client.doRequest({
action: "ListDomains",
version: "2024-03-27",
method: "GET",
style: "ROA",
pathname: `/v1/domains`,
data: {
query: {
pageSize: 100,
gatewayType: this.gatewayType,
},
},
});
const list = res?.data?.items;
if (!list || list.length === 0) {
return []
return [];
}
const options = list.map((item: any) => {
return {
@@ -237,43 +224,42 @@ export class DeployCertToAliyunApig extends AbstractTaskPlugin {
return optionsUtils.buildGroupOptions(options, this.certDomains);
}
async onGetRegionList(data: any) {
const list = [
{value:"cn-qingdao",label:"华北1(青岛)",endpoint:"apig.cn-qingdao.aliyuncs.com"},
{value:"cn-beijing",label:"华北2(北京)",endpoint:"apig.cn-beijing.aliyuncs.com"},
{value:"cn-zhangjiakou",label:"华北3(张家口)",endpoint:"apig.cn-zhangjiakou.aliyuncs.com"},
{value:"cn-wulanchabu",label:"华北6(乌兰察布)",endpoint:"apig.cn-wulanchabu.aliyuncs.com"},
{value:"cn-hangzhou",label:"华东1(杭州)",endpoint:"apig.cn-hangzhou.aliyuncs.com"},
{value:"cn-shanghai",label:"华东2(上海)",endpoint:"apig.cn-shanghai.aliyuncs.com"},
{value:"cn-shenzhen",label:"华南1(深圳)",endpoint:"apig.cn-shenzhen.aliyuncs.com"},
{value:"cn-heyuan",label:"华南2(河源)",endpoint:"apig.cn-heyuan.aliyuncs.com"},
{value:"cn-guangzhou",label:"华南3(广州)",endpoint:"apig.cn-guangzhou.aliyuncs.com"},
{value:"ap-southeast-2",label:"澳大利亚(悉尼)已关停",endpoint:"apig.ap-southeast-2.aliyuncs.com"},
{value:"ap-southeast-6",label:"菲律宾(马尼拉)",endpoint:"apig.ap-southeast-6.aliyuncs.com"},
{value:"ap-northeast-2",label:"韩国(首尔)",endpoint:"apig.ap-northeast-2.aliyuncs.com"},
{value:"ap-southeast-3",label:"马来西亚(吉隆坡)",endpoint:"apig.ap-southeast-3.aliyuncs.com"},
{value:"ap-northeast-1",label:"日本(东京)",endpoint:"apig.ap-northeast-1.aliyuncs.com"},
{value:"ap-southeast-7",label:"泰国(曼谷)",endpoint:"apig.ap-southeast-7.aliyuncs.com"},
{value:"cn-chengdu",label:"西南1(成都)",endpoint:"apig.cn-chengdu.aliyuncs.com"},
{value:"ap-southeast-1",label:"新加坡",endpoint:"apig.ap-southeast-1.aliyuncs.com"},
{value:"ap-southeast-5",label:"印度尼西亚(雅加达)",endpoint:"apig.ap-southeast-5.aliyuncs.com"},
{value:"cn-hongkong",label:"中国香港",endpoint:"apig.cn-hongkong.aliyuncs.com"},
{value:"eu-central-1",label:"德国(法兰克福)",endpoint:"apig.eu-central-1.aliyuncs.com"},
{value:"us-east-1",label:"美国(弗吉尼亚)",endpoint:"apig.us-east-1.aliyuncs.com"},
{value:"us-west-1",label:"美国(硅谷)",endpoint:"apig.us-west-1.aliyuncs.com"},
{value:"eu-west-1",label:"英国(伦敦)",endpoint:"apig.eu-west-1.aliyuncs.com"},
{value:"me-east-1",label:"阿联酋(迪拜)",endpoint:"apig.me-east-1.aliyuncs.com"},
{value:"me-central-1",label:"沙特(利雅得)",endpoint:"apig.me-central-1.aliyuncs.com"},
]
{ value: "cn-qingdao", label: "华北1(青岛)", endpoint: "apig.cn-qingdao.aliyuncs.com" },
{ value: "cn-beijing", label: "华北2(北京)", endpoint: "apig.cn-beijing.aliyuncs.com" },
{ value: "cn-zhangjiakou", label: "华北3(张家口)", endpoint: "apig.cn-zhangjiakou.aliyuncs.com" },
{ value: "cn-wulanchabu", label: "华北6(乌兰察布)", endpoint: "apig.cn-wulanchabu.aliyuncs.com" },
{ value: "cn-hangzhou", label: "华东1(杭州)", endpoint: "apig.cn-hangzhou.aliyuncs.com" },
{ value: "cn-shanghai", label: "华东2(上海)", endpoint: "apig.cn-shanghai.aliyuncs.com" },
{ value: "cn-shenzhen", label: "华南1(深圳)", endpoint: "apig.cn-shenzhen.aliyuncs.com" },
{ value: "cn-heyuan", label: "华南2(河源)", endpoint: "apig.cn-heyuan.aliyuncs.com" },
{ value: "cn-guangzhou", label: "华南3(广州)", endpoint: "apig.cn-guangzhou.aliyuncs.com" },
{ value: "ap-southeast-2", label: "澳大利亚(悉尼)已关停", endpoint: "apig.ap-southeast-2.aliyuncs.com" },
{ value: "ap-southeast-6", label: "菲律宾(马尼拉)", endpoint: "apig.ap-southeast-6.aliyuncs.com" },
{ value: "ap-northeast-2", label: "韩国(首尔)", endpoint: "apig.ap-northeast-2.aliyuncs.com" },
{ value: "ap-southeast-3", label: "马来西亚(吉隆坡)", endpoint: "apig.ap-southeast-3.aliyuncs.com" },
{ value: "ap-northeast-1", label: "日本(东京)", endpoint: "apig.ap-northeast-1.aliyuncs.com" },
{ value: "ap-southeast-7", label: "泰国(曼谷)", endpoint: "apig.ap-southeast-7.aliyuncs.com" },
{ value: "cn-chengdu", label: "西南1(成都)", endpoint: "apig.cn-chengdu.aliyuncs.com" },
{ value: "ap-southeast-1", label: "新加坡", endpoint: "apig.ap-southeast-1.aliyuncs.com" },
{ value: "ap-southeast-5", label: "印度尼西亚(雅加达)", endpoint: "apig.ap-southeast-5.aliyuncs.com" },
{ value: "cn-hongkong", label: "中国香港", endpoint: "apig.cn-hongkong.aliyuncs.com" },
{ value: "eu-central-1", label: "德国(法兰克福)", endpoint: "apig.eu-central-1.aliyuncs.com" },
{ value: "us-east-1", label: "美国(弗吉尼亚)", endpoint: "apig.us-east-1.aliyuncs.com" },
{ value: "us-west-1", label: "美国(硅谷)", endpoint: "apig.us-west-1.aliyuncs.com" },
{ value: "eu-west-1", label: "英国(伦敦)", endpoint: "apig.eu-west-1.aliyuncs.com" },
{ value: "me-east-1", label: "阿联酋(迪拜)", endpoint: "apig.me-east-1.aliyuncs.com" },
{ value: "me-central-1", label: "沙特(利雅得)", endpoint: "apig.me-central-1.aliyuncs.com" },
];
return list.map((item: any) => {
return {
value: item.endpoint,
label: item.label,
endpoint: item.endpoint,
regionId : item.value
regionId: item.value,
};
})
});
}
}
new DeployCertToAliyunApig();
@@ -1,15 +1,15 @@
import {AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline';
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine} from "@certd/plugin-lib";
import {CertApplyPluginNames, CertInfo} from '@certd/plugin-cert';
import {optionsUtils} from "@certd/basic";
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { optionsUtils } from "@certd/basic";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
@IsTaskPlugin({
name: 'DeployCertToAliyunApiGateway',
title: '阿里云-部署证书至API网关',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunApiGateway",
title: "阿里云-部署证书至API网关",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '自动部署域名证书至阿里云API网关(APIGateway',
desc: "自动部署域名证书至阿里云API网关(APIGateway",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -18,10 +18,10 @@ import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
})
export class DeployCertToAliyunApiGateway extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
@@ -32,122 +32,117 @@ export class DeployCertToAliyunApiGateway extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
})
certName!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '区域',
helper: '请选择区域',
title: "区域",
helper: "请选择区域",
action: DeployCertToAliyunApiGateway.prototype.onGetRegionList.name,
watches: ['certDomains', 'accessId'],
watches: ["certDomains", "accessId"],
required: true,
component:{
name:"remote-auto-complete"
}
component: {
name: "remote-auto-complete",
},
})
)
regionEndpoint!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: 'API分组',
helper: '请选择API分组',
title: "API分组",
helper: "请选择API分组",
action: DeployCertToAliyunApiGateway.prototype.onGetGroupList.name,
watches: ['regionEndpoint', 'accessId'],
watches: ["regionEndpoint", "accessId"],
required: true,
component:{
name:"remote-auto-complete"
}
component: {
name: "remote-auto-complete",
},
})
)
groupId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '绑定域名',
helper: '在API分组上配置的绑定域名',
title: "绑定域名",
helper: "在API分组上配置的绑定域名",
action: DeployCertToAliyunApiGateway.prototype.onGetDomainList.name,
watches: ['groupId','regionEndpoint', 'accessId'],
watches: ["groupId", "regionEndpoint", "accessId"],
required: true,
})
)
customDomains!: string[];
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云Api网关');
if(!this.customDomains){
throw new Error('您还未选择域名');
this.logger.info("开始部署证书到阿里云Api网关");
if (!this.customDomains) {
throw new Error("您还未选择域名");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient(this.regionEndpoint)
const client = access.getClient(this.regionEndpoint);
for (const domainName of this.customDomains ) {
this.logger.info(`[${domainName}]开始部署`)
for (const domainName of this.customDomains) {
this.logger.info(`[${domainName}]开始部署`);
await this.updateCert(client, domainName);
this.logger.info(`[${domainName}]部署成功`)
this.logger.info(`[${domainName}]部署成功`);
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async updateCert(client: any, domainName: string) {
const ret = await client.doRequest({
const ret = await client.doRequest({
// 接口名称
action: "SetDomainCertificate",
// 接口版本
version: "2016-07-14",
data:{
query:{
data: {
query: {
GroupId: this.groupId,
DomainName: domainName,
CertificateName: this.buildCertName(domainName),
CertificateBody: this.cert.crt,
CertificatePrivateKey: this.cert.key
}
}
})
CertificatePrivateKey: this.cert.key,
},
},
});
this.logger.info(`设置${domainName}证书成功:`, ret.RequestId);
}
async onGetGroupList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
if (!this.regionEndpoint) {
throw new Error('请选择区域');
throw new Error("请选择区域");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient(this.regionEndpoint)
const res =await client.doRequest({
const client = access.getClient(this.regionEndpoint);
const res = await client.doRequest({
// 接口名称
action: "DescribeApiGroups",
// 接口版本
version: "2016-07-14",
data:{}
})
data: {},
});
const list = res?.ApiGroupAttributes?.ApiGroupAttribute;
if (!list || list.length === 0) {
throw new Error('没有数据,您可以手动输入API网关ID');
throw new Error("没有数据,您可以手动输入API网关ID");
}
return list.map((item: any) => {
return {
@@ -159,32 +154,32 @@ export class DeployCertToAliyunApiGateway extends AbstractTaskPlugin {
async onGetDomainList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
if (!this.regionEndpoint) {
throw new Error('请选择区域');
throw new Error("请选择区域");
}
if (!this.groupId) {
throw new Error('请选择分组');
throw new Error("请选择分组");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient(this.regionEndpoint)
const client = access.getClient(this.regionEndpoint);
const res =await client.doRequest({
// 接口名称
action: "DescribeApiGroup",
// 接口版本
version: "2016-07-14",
data:{
query:{
GroupId: this.groupId
}
}
})
const res = await client.doRequest({
// 接口名称
action: "DescribeApiGroup",
// 接口版本
version: "2016-07-14",
data: {
query: {
GroupId: this.groupId,
},
},
});
const list = res?.CustomDomains?.DomainItem;
if (!list || list.length === 0) {
throw new Error('没有数据,您可以手动输入');
throw new Error("没有数据,您可以手动输入");
}
const options = list.map((item: any) => {
return {
@@ -196,32 +191,31 @@ export class DeployCertToAliyunApiGateway extends AbstractTaskPlugin {
return optionsUtils.buildGroupOptions(options, this.certDomains);
}
async onGetRegionList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = access.getClient("apigateway.cn-hangzhou.aliyuncs.com")
const client = access.getClient("apigateway.cn-hangzhou.aliyuncs.com");
const res =await client.doRequest({
const res = await client.doRequest({
// 接口名称
action: "DescribeRegions",
// 接口版本
version: "2016-07-14",
data:{}
})
const list = res.Regions.Region ;
data: {},
});
const list = res.Regions.Region;
if (!list || list.length === 0) {
throw new Error('没有数据,您可以手动输入');
throw new Error("没有数据,您可以手动输入");
}
return list.map((item: any) => {
return {
value: item.RegionEndpoint,
label: item.LocalName,
endpoint: item.RegionEndpoint,
regionId: item.RegionId
regionId: item.RegionId,
};
});
}
@@ -1,15 +1,15 @@
import { optionsUtils } from '@certd/basic';
import { AbstractTaskPlugin, CertTargetItem, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import { optionsUtils } from "@certd/basic";
import { AbstractTaskPlugin, CertTargetItem, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput, TaskOutput } from "@certd/pipeline";
import { CertApplyPluginNames, CertReader } from "@certd/plugin-cert";
import { CertInfo, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
import { CertInfo, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'DeployCertToAliyunCDN',
title: '阿里云-部署证书至CDN',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunCDN",
title: "阿里云-部署证书至CDN",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '自动部署域名证书至阿里云CDN',
desc: "自动部署域名证书至阿里云CDN",
runStrategy: RunStrategy.AlwaysRun,
// default: {
// strategy: {
@@ -19,15 +19,15 @@ import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/al
})
export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
@TaskInput({
title: '证书服务接入点',
helper: '不会选就按默认',
value: 'cas.aliyuncs.com',
title: "证书服务接入点",
helper: "不会选就按默认",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true,
@@ -35,11 +35,11 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
endpoint!: string;
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
template: false,
required: true,
@@ -50,62 +50,61 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书所在地域',
helper: 'cn-hangzhou和ap-southeast-1,默认cn-hangzhou。国际站用户建议使用ap-southeast-1。',
title: "证书所在地域",
helper: "cn-hangzhou和ap-southeast-1,默认cn-hangzhou。国际站用户建议使用ap-southeast-1。",
value: "cn-hangzhou",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cn-hangzhou', label: '中国大陆' },
{ value: 'ap-southeast-1', label: '新加坡' }
]
{ value: "cn-hangzhou", label: "中国大陆" },
{ value: "ap-southeast-1", label: "新加坡" },
],
},
required: true,
})
certRegion: string
certRegion: string;
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
})
certName!: string;
@TaskInput({
title: '域名匹配模式',
helper: '根据证书匹配:根据证书域名自动匹配DCDN加速域名自动部署,新增加速域名自动感知,自动新增部署',
title: "域名匹配模式",
helper: "根据证书匹配:根据证书域名自动匹配DCDN加速域名自动部署,新增加速域名自动感知,自动新增部署",
component: {
name: 'a-select',
name: "a-select",
options: [
{ label: '手动选择', value: 'manual' },
{ label: '根据证书匹配', value: 'auto' },
{ label: "手动选择", value: "manual" },
{ label: "根据证书匹配", value: "auto" },
],
},
value: 'manual',
value: "manual",
})
domainMatchMode!: 'manual' | 'auto';
domainMatchMode!: "manual" | "auto";
@TaskInput(
createRemoteSelectInputDefine({
title: 'CDN加速域名',
helper: '你在阿里云上配置的CDN加速域名,比如:certd.docmirror.cn',
typeName: 'DeployCertToAliyunCDN',
title: "CDN加速域名",
helper: "你在阿里云上配置的CDN加速域名,比如:certd.docmirror.cn",
typeName: "DeployCertToAliyunCDN",
action: DeployCertToAliyunCDN.prototype.onGetDomainList.name,
watches: ['certDomains', 'accessId'],
watches: ["certDomains", "accessId"],
required: true,
pageSize: 100,
search:true,
search: true,
mergeScript: `
return {
show: ctx.compute(({form})=>{
@@ -113,72 +112,70 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
})
}
`,
pager:true,
pager: true,
})
)
domainName!: string | string[];
@TaskOutput({
title: '已部署过的DCDN加速域名',
title: "已部署过的DCDN加速域名",
})
deployedList!: string[];
async onInstance() { }
async onInstance() {}
async execute(): Promise<any> {
this.logger.info('开始部署证书到阿里云cdn');
this.logger.info("开始部署证书到阿里云cdn");
const access = await this.getAccess<AliyunAccess>(this.accessId);
if (this.cert == null) {
throw new Error('域名证书参数为空,请检查前置任务')
throw new Error("域名证书参数为空,请检查前置任务");
}
const client = await this.getClient(access);
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
endpoint: this.endpoint || 'cas.aliyuncs.com',
endpoint: this.endpoint || "cas.aliyuncs.com",
});
if (this.domainMatchMode === 'auto') {
if (this.domainMatchMode === "auto") {
const { result, deployedList } = await this.autoMatchedDeploy({
targetName: 'DCDN加速域名',
targetName: "DCDN加速域名",
uploadCert: async () => {
return await sslClient.uploadCertOrGet(this.cert);
},
deployOne: async (req: { target: CertTargetItem, cert: any }) => {
deployOne: async (req: { target: CertTargetItem; cert: any }) => {
return await this.deployOne(client, req.target.value, req.cert);
},
getCertDomains:async ()=>{
return sslClient.getCertDomains(this.cert);
getCertDomains: async () => {
return sslClient.getCertDomains(this.cert);
},
getDeployTargetList: this.onGetDomainList.bind(this)
getDeployTargetList: this.onGetDomainList.bind(this),
});
this.deployedList = deployedList;
return result;
} else {
if (this.isNotChanged()) {
this.logger.info('输入参数未变更,跳过');
this.logger.info("输入参数未变更,跳过");
return "skip";
}
const certId = await this.getOrUploadCasCert(sslClient);
if (typeof this.domainName === 'string') {
if (typeof this.domainName === "string") {
this.domainName = [this.domainName];
}
for (const domain of this.domainName) {
await this.deployOne(client, domain, certId );
await this.deployOne(client, domain, certId);
}
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async getOrUploadCasCert(sslClient: AliyunSslClient) {
let certId: any = this.cert;
let certName = this.appendTimeSuffix(this.certName);
if (typeof this.cert === 'object') {
if (typeof this.cert === "object") {
const certInfo = this.cert as CertInfo;
const casCert = this.cert as CasCertId;
if (casCert.certId) {
@@ -191,23 +188,23 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
});
certId = certIdRes.certId as any;
} else {
throw new Error('证书格式错误' + JSON.stringify(this.cert));
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
return {
certId,
certName,
}
};
}
async deployOne(client: any, domain: string, cert: any ) {
async deployOne(client: any, domain: string, cert: any) {
const { certId, certName } = cert;
await this.SetCdnDomainSSLCertificate(client, {
CertId: certId,
DomainName: domain,
CertName: certName,
CertRegion: this.certRegion || 'cn-hangzhou',
CertRegion: this.certRegion || "cn-hangzhou",
});
}
@@ -216,23 +213,23 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
await client.init({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: 'https://cdn.aliyuncs.com',
apiVersion: '2018-05-10',
endpoint: "https://cdn.aliyuncs.com",
apiVersion: "2018-05-10",
});
return client;
}
async SetCdnDomainSSLCertificate(client: any, params: { CertId: number; DomainName: string, CertName: string, CertRegion: string }) {
this.logger.info('设置CDN: ', JSON.stringify(params));
async SetCdnDomainSSLCertificate(client: any, params: { CertId: number; DomainName: string; CertName: string; CertRegion: string }) {
this.logger.info("设置CDN: ", JSON.stringify(params));
const requestOption = {
method: 'POST',
method: "POST",
formatParams: false,
};
const ret: any = await client.request(
'SetCdnDomainSSLCertificate',
"SetCdnDomainSSLCertificate",
{
SSLProtocol: 'on',
SSLProtocol: "on",
CertType: "cas",
...params,
},
@@ -244,41 +241,41 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error('执行失败:' + ret.Message);
throw new Error("执行失败:" + ret.Message);
}
}
async onGetDomainList(data: PageSearch) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
const pager = new Pager(data)
const pager = new Pager(data);
const params = {
DomainName: data.searchKey,
PageSize: pager.pageSize || 100,
PageNumber: pager.pageNo || 1,
DomainSearchType: "fuzzy_match"
DomainSearchType: "fuzzy_match",
};
const requestOption = {
method: 'POST',
method: "POST",
formatParams: false,
};
const res = await client.request('DescribeUserDomains', params, requestOption);
const res = await client.request("DescribeUserDomains", params, requestOption);
this.checkRet(res);
const pageData = res?.Domains?.PageData;
if (!pageData || pageData.length === 0) {
return {
list: [],
total: 0,
};
return {
list: [],
total: 0,
};
}
const total = res?.TotalCount || 0;
const total = res?.TotalCount || 0;
const options = pageData.map((item: any) => {
return {
value: item.DomainName,
@@ -1,20 +1,17 @@
import { AbstractTaskPlugin, CertTargetItem, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import dayjs from 'dayjs';
import { AbstractTaskPlugin, CertTargetItem, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput, TaskOutput } from "@certd/pipeline";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import dayjs from "dayjs";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { optionsUtils } from "@certd/basic";
import { CertApplyPluginNames, CertInfo } from '@certd/plugin-cert';
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'DeployCertToAliyunDCDN',
title: '阿里云-部署证书至DCDN',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunDCDN",
title: "阿里云-部署证书至DCDN",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '依赖证书申请前置任务,自动部署域名证书至阿里云DCDN',
desc: "依赖证书申请前置任务,自动部署域名证书至阿里云DCDN",
runStrategy: RunStrategy.AlwaysRun,
// default: {
// strategy: {
@@ -24,11 +21,11 @@ import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/al
})
export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -38,47 +35,46 @@ export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
})
certName!: string;
@TaskInput({
title: '域名匹配模式',
helper: '根据证书匹配:根据证书域名自动匹配DCDN加速域名自动部署,新增加速域名自动感知,自动新增部署',
title: "域名匹配模式",
helper: "根据证书匹配:根据证书域名自动匹配DCDN加速域名自动部署,新增加速域名自动感知,自动新增部署",
component: {
name: 'a-select',
name: "a-select",
options: [
{ label: '手动选择', value: 'manual' },
{ label: '根据证书匹配', value: 'auto' },
{ label: "手动选择", value: "manual" },
{ label: "根据证书匹配", value: "auto" },
],
},
value: 'manual',
value: "manual",
})
domainMatchMode!: 'manual' | 'auto';
domainMatchMode!: "manual" | "auto";
@TaskInput(
createRemoteSelectInputDefine({
title: 'DCDN加速域名',
helper: '你在阿里云上配置的DCDN加速域名,比如:certd.docmirror.cn',
title: "DCDN加速域名",
helper: "你在阿里云上配置的DCDN加速域名,比如:certd.docmirror.cn",
action: DeployCertToAliyunDCDN.prototype.onGetDomainList.name,
watches: ['certDomains', 'accessId'],
watches: ["certDomains", "accessId"],
required: true,
pageSize: 100,
search:true,
pager:true,
search: true,
pager: true,
mergeScript: `
return {
show: ctx.compute(({form})=>{
@@ -91,63 +87,59 @@ export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
domainName!: string | string[];
@TaskOutput({
title: '已部署过的DCDN加速域名',
title: "已部署过的DCDN加速域名",
})
deployedList!: string[];
async onInstance() { }
async onInstance() {}
async execute(): Promise<any> {
this.logger.info('开始部署证书到阿里云DCDN');
this.logger.info("开始部署证书到阿里云DCDN");
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
const client = await this.getClient(access);
const sslClient = new AliyunSslClient({ access, logger: this.logger });
if (this.domainMatchMode === 'auto') {
if (this.domainMatchMode === "auto") {
const { result, deployedList } = await this.autoMatchedDeploy({
targetName: 'CDN加速域名',
targetName: "CDN加速域名",
uploadCert: async () => {
return await sslClient.uploadCertOrGet(this.cert);
},
deployOne: async (req: { target: CertTargetItem, cert: any }) => {
deployOne: async (req: { target: CertTargetItem; cert: any }) => {
return await this.deployOne(client, req.target.value, req.cert);
},
getCertDomains: async ()=>{
getCertDomains: async () => {
return sslClient.getCertDomains(this.cert);
},
getDeployTargetList: this.onGetDomainList.bind(this)
getDeployTargetList: this.onGetDomainList.bind(this),
});
this.deployedList = deployedList;
return result;
} else {
if (this.isNotChanged()) {
this.logger.info('输入参数未变更,跳过');
this.logger.info("输入参数未变更,跳过");
return "skip";
}
if (!this.domainName) {
throw new Error('您还未选择DCDN域名');
throw new Error("您还未选择DCDN域名");
}
let domains: string[] = [];
domains = typeof this.domainName === 'string' ? [this.domainName] : this.domainName;
domains = typeof this.domainName === "string" ? [this.domainName] : this.domainName;
const aliCrtId = await sslClient.uploadCertOrGet(this.cert);
for (const domainName of domains) {
await this.deployOne(client, domainName, aliCrtId);
}
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async deployOne(client: any, domainName: string, aliCrtId: CasCertId) {
this.logger.info(`[${domainName}]开始部署`)
this.logger.info(`[${domainName}]开始部署`);
const params = await this.buildParams(domainName, aliCrtId);
await this.doRequest(client, params);
await this.ctx.utils.sleep(1000);
this.logger.info(`[${domainName}]部署成功`)
this.logger.info(`[${domainName}]部署成功`);
}
async getClient(access: AliyunAccess) {
@@ -155,20 +147,20 @@ export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
await client.init({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: 'https://dcdn.aliyuncs.com',
apiVersion: '2018-01-15',
endpoint: "https://dcdn.aliyuncs.com",
apiVersion: "2018-01-15",
});
return client;
}
async buildParams(domainName: string, aliCrtId: CasCertId) {
const CertName = (this.certName ?? 'certd') + '-' + dayjs().format('YYYYMMDDHHmmss');
const CertName = (this.certName ?? "certd") + "-" + dayjs().format("YYYYMMDDHHmmss");
const certId = aliCrtId.certId;
this.logger.info('使用已上传的证书:', certId);
this.logger.info("使用已上传的证书:", certId);
return {
DomainName: domainName,
SSLProtocol: 'on',
CertType: 'cas',
SSLProtocol: "on",
CertType: "cas",
CertName: CertName,
CertId: certId,
};
@@ -176,42 +168,41 @@ export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
async doRequest(client: any, params: any) {
const requestOption = {
method: 'POST',
method: "POST",
formatParams: false,
};
const ret: any = await client.request('SetDcdnDomainSSLCertificate', params, requestOption);
const ret: any = await client.request("SetDcdnDomainSSLCertificate", params, requestOption);
this.checkRet(ret);
this.logger.info('设置Dcdn证书成功:', ret.RequestId);
this.logger.info("设置Dcdn证书成功:", ret.RequestId);
}
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error('执行失败:' + ret.Message);
throw new Error("执行失败:" + ret.Message);
}
}
async onGetDomainList(data: PageSearch): Promise<{ list: CertTargetItem[], total: number }> {
async onGetDomainList(data: PageSearch): Promise<{ list: CertTargetItem[]; total: number }> {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
const pager = new Pager(data)
const pager = new Pager(data);
const params = {
DomainName: data.searchKey,
PageSize: pager.pageSize || 200,
PageNumber: pager.pageNo || 1,
DomainSearchType: "fuzzy_match"
DomainSearchType: "fuzzy_match",
};
const requestOption = {
method: 'POST',
method: "POST",
formatParams: false,
};
const res = await client.request('DescribeDcdnUserDomains', params, requestOption);
const res = await client.request("DescribeDcdnUserDomains", params, requestOption);
this.checkRet(res);
const pageData = res?.Domains?.PageData || [];
const total = res?.TotalCount || 0;
@@ -1,9 +1,6 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/ssl-client.js";
import { AliyunClientV2 } from "../../../plugin-lib/aliyun/lib/aliyun-client-v2.js";
@@ -18,9 +15,9 @@ import dayjs from "dayjs";
needPlus: false,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class AliyunDeployCertToESA extends AbstractTaskPlugin {
@TaskInput({
@@ -28,9 +25,9 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
helper: "请选择证书申请任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames, 'uploadCertToAliyun']
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true
required: true,
})
cert!: CertInfo | CasCertId | number;
@@ -45,10 +42,10 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
vModel: "value",
options: [
{ value: "cn-hangzhou", label: "华东1(杭州)" },
{ value: "ap-southeast-1", label: "新加坡" }
]
{ value: "ap-southeast-1", label: "新加坡" },
],
},
required: true
required: true,
})
regionId!: string;
@@ -60,23 +57,22 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
name: "a-select",
options: [
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" }
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
// { value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" }
]
],
},
required: true
required: true,
})
casEndpoint!: string;
@TaskInput({
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "access-selector",
type: "aliyun"
type: "aliyun",
},
required: true
required: true,
})
accessId!: string;
@@ -85,7 +81,7 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
title: "站点",
helper: "请选择要部署证书的站点",
action: AliyunDeployCertToESA.prototype.onGetSiteList.name,
watches: ["accessId", "regionId"]
watches: ["accessId", "regionId"],
})
)
siteIds!: string[];
@@ -95,15 +91,14 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
value: 2,
component: {
name: "a-input-number",
vModel: "value"
vModel: "value",
},
helper: "将检查证书数量限制,如果超限将删除最旧的那张证书",
required: true
required: true,
})
certLimit: number = 2;
certLimit = 2;
async onInstance() {
}
async onInstance() {}
async getAliyunCertId(access: AliyunAccess) {
let certId: any = this.cert;
@@ -112,7 +107,7 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
endpoint: this.casEndpoint
endpoint: this.casEndpoint,
});
const certInfo = this.cert as CertInfo;
@@ -121,21 +116,21 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
certId = casCert.certId;
certName = casCert.certName;
} else if (certInfo.crt) {
certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt),"certd");
certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt), "certd");
const certIdRes = await sslClient.uploadCertificate({
name: certName,
cert: certInfo
cert: certInfo,
});
certId = certIdRes.certId as any;
this.logger.info("上传证书成功", certId, certName);
}else{
throw new Error('证书格式错误'+JSON.stringify(this.cert));
} else {
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
return {
certId,
certName
certName,
};
}
@@ -160,12 +155,11 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
SiteId: siteId,
CasId: certId,
Type: "cas",
Name: certName
}
}
Name: certName,
},
},
});
this.logger.info(`部署站点[${siteId}]证书成功:${JSON.stringify(res)}`);
} catch (e) {
if (e.message.includes("Certificate.Duplicated")) {
this.logger.info(`站点[${siteId}]证书已存在,无需重复部署`);
@@ -176,13 +170,12 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
try {
await this.clearSiteExpiredCert(client, siteId);
} catch (e) {
this.logger.error(`清理站点[${siteId}]过期证书失败`, e)
this.logger.error(`清理站点[${siteId}]过期证书失败`, e);
}
}
}
}
async getClient(access: AliyunAccess) {
const endpoint = `esa.${this.regionId}.aliyuncs.com`;
return access.getClient(endpoint);
@@ -199,7 +192,7 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
action: "ListSites",
version: "2024-09-10",
method: "GET",
data: {}
data: {},
});
const list = res?.Sites;
@@ -211,7 +204,7 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
return {
label: item.SiteName,
value: item.SiteId,
domain: item.SiteName
domain: item.SiteName,
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
@@ -226,9 +219,9 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
data: {
query: {
SiteId: siteId,
PageSize: 100
}
}
PageSize: 100,
},
},
});
const list = certListRes.Result;
@@ -245,21 +238,19 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
data: {
query: {
SiteId: siteId,
Id: item.id
}
}
Id: item.id,
},
},
});
this.logger.info(`证书${item.Name}已删除`);
} catch (e) {
this.logger.error(`过期证书${item.Name}删除失败:`, e.message)
this.logger.error(`过期证书${item.Name}删除失败:`, e.message);
}
}
}
}
async clearSiteLimitCert(client: AliyunClientV2, siteId: string) {
//删除最旧的证书
const certLimit = this.certLimit || 2;
this.logger.info(`站点[${siteId}]证书数量检查,当前限制${certLimit}`);
@@ -270,31 +261,31 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
data: {
query: {
SiteId: siteId,
PageSize: 100
}
}
PageSize: 100,
},
},
});
let list = certListRes.Result || [];
list = list.filter((item: any) => item.Type === "cas");
if (!list || list.length === 0) {
this.logger.info(`站点[${siteId}]没有CAS证书, 无需删除`);
return
return;
}
if (list.length < certLimit) {
this.logger.info(`站点[${siteId}]证书数量(${list.length})未超限制, 无需删除`);
return;
}
this.logger.info(`站点[${siteId}]证书数量(${list.length})已超限制, 开始删除最旧的证书`);
let oldly:any = null;
let oldly: any = null;
for (const item of list) {
if (!oldly) {
oldly = item;
continue;
}
if (dayjs(item.CreateTime).valueOf() < (dayjs(oldly.CreateTime)).valueOf()){
if (dayjs(item.CreateTime).valueOf() < dayjs(oldly.CreateTime).valueOf()) {
oldly = item;
}
}
@@ -306,9 +297,9 @@ export class AliyunDeployCertToESA extends AbstractTaskPlugin {
data: {
query: {
SiteId: siteId,
Id: oldly.Id
}
}
Id: oldly.Id,
},
},
});
this.logger.info(`最旧证书${oldly.Name}已删除`);
}
@@ -1,6 +1,6 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import fs from "fs";
import path from "path";
import { tmpdir } from "node:os";
@@ -8,11 +8,11 @@ import { sp } from "@certd/basic";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
@IsTaskPlugin({
name: 'AliyunDeployCertToFC',
title: '阿里云-部署至阿里云FC(3.0)',
icon: 'svg:icon-aliyun',
name: "AliyunDeployCertToFC",
title: "阿里云-部署至阿里云FC(3.0)",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署证书到阿里云函数计算(FC3.0',
desc: "部署证书到阿里云函数计算(FC3.0",
needPlus: false,
default: {
strategy: {
@@ -22,10 +22,10 @@ import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
})
export class AliyunDeployCertToFC extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择证书申请任务输出的域名证书',
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书",
component: {
name: 'output-selector',
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
@@ -36,56 +36,55 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'FC大区',
value: 'cn-hangzhou',
title: "FC大区",
value: "cn-hangzhou",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: [
{ value: 'cn-qingdao', label: '华北1(青岛)' },
{ value: 'cn-beijing', label: '华北2(北京)' },
{ value: 'cn-zhangjiakou', label: '华北 3(张家口)' },
{ value: 'cn-huhehaote', label: '华北5(呼和浩特)' },
{ value: 'cn-hangzhou', label: '华东1(杭州)' },
{ value: 'cn-shanghai', label: '华东2(上海)' },
{ value: 'cn-shenzhen', label: '华南1(深圳)' },
{ value: 'ap-southeast-2', label: '澳大利亚(悉尼)' },
{ value: 'eu-central-1', label: '德国(法兰克福)' },
{ value: 'ap-southeast-3', label: '马来西亚(吉隆坡)' },
{ value: 'us-east-1', label: '美国(弗吉尼亚)' },
{ value: 'us-west-1', label: '美国(硅谷)' },
{ value: 'ap-northeast-1', label: '日本(东京)' },
{ value: 'ap-southeast-7', label: '泰国(曼谷)' },
{ value: 'cn-chengdu', label: '西南1(成都)' },
{ value: 'ap-southeast-1', label: '新加坡' },
{ value: 'ap-south-1', label: '印度(孟买)' },
{ value: 'ap-southeast-5', label: '印度尼西亚(雅加达)' },
{ value: 'eu-west-1', label: '英国(伦敦)' },
{ value: 'cn-hongkong', label: '中国香港' },
{ value: "cn-qingdao", label: "华北1(青岛)" },
{ value: "cn-beijing", label: "华北2(北京)" },
{ value: "cn-zhangjiakou", label: "华北 3(张家口)" },
{ value: "cn-huhehaote", label: "华北5(呼和浩特)" },
{ value: "cn-hangzhou", label: "华东1(杭州)" },
{ value: "cn-shanghai", label: "华东2(上海)" },
{ value: "cn-shenzhen", label: "华南1(深圳)" },
{ value: "ap-southeast-2", label: "澳大利亚(悉尼)" },
{ value: "eu-central-1", label: "德国(法兰克福)" },
{ value: "ap-southeast-3", label: "马来西亚(吉隆坡)" },
{ value: "us-east-1", label: "美国(弗吉尼亚)" },
{ value: "us-west-1", label: "美国(硅谷)" },
{ value: "ap-northeast-1", label: "日本(东京)" },
{ value: "ap-southeast-7", label: "泰国(曼谷)" },
{ value: "cn-chengdu", label: "西南1(成都)" },
{ value: "ap-southeast-1", label: "新加坡" },
{ value: "ap-south-1", label: "印度(孟买)" },
{ value: "ap-southeast-5", label: "印度尼西亚(雅加达)" },
{ value: "eu-west-1", label: "英国(伦敦)" },
{ value: "cn-hongkong", label: "中国香港" },
],
},
required: true,
})
regionId!: string;
@TaskInput({
title: '阿里云账号id',
helper: '阿里云主账号ID,右上角头像下方获取',
title: "阿里云账号id",
helper: "阿里云主账号ID,右上角头像下方获取",
component: {
name: 'a-input',
vModel:"value"
name: "a-input",
vModel: "value",
},
required: true,
})
accountId!: string;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
@@ -93,33 +92,33 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'FC域名',
title: "FC域名",
helper: "请选择要部署证书的域名",
typeName: 'AliyunDeployCertToFC',
typeName: "AliyunDeployCertToFC",
action: AliyunDeployCertToFC.prototype.onGetDomainList.name,
watches: ['accessId', 'regionId'],
watches: ["accessId", "regionId"],
})
)
fcDomains!: string[];
@TaskInput({
title: '域名支持的协议类型',
value: '',
title: "域名支持的协议类型",
value: "",
component: {
name: 'a-select',
vModel:"value",
name: "a-select",
vModel: "value",
options: [
{ value: '', label: '保持原样(适用于原来已经开启了HTTPS)' },
{ value: 'HTTPS', label: '仅HTTPS' },
{ value: 'HTTP,HTTPS', label: 'HTTP与HTTPS同时支持' },
{ value: "", label: "保持原样(适用于原来已经开启了HTTPS)" },
{ value: "HTTPS", label: "仅HTTPS" },
{ value: "HTTP,HTTPS", label: "HTTP与HTTPS同时支持" },
],
},
})
protocol!: string;
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
})
certName!: string;
@@ -133,17 +132,16 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
});
}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云');
this.logger.info("开始部署证书到阿里云");
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
const $Util = await import('@alicloud/tea-util');
const $OpenApi = await import('@alicloud/openapi-client');
const $Util = await import("@alicloud/tea-util");
const $OpenApi = await import("@alicloud/openapi-client");
let privateKey = this.cert.key
try{
let privateKey = this.cert.key;
try {
// openssl rsa -in private_key.pem -out private_key_pkcs1.pem
const tempDir = path.join(tmpdir(), "certd");
if (!fs.existsSync(tempDir)) {
@@ -151,7 +149,7 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
}
const keyFileName = this.ctx.utils.id.randomNumber(10);
const tempPem = `${tempDir}/${keyFileName}.pem`;
const tempPkcs1Pem =`${tempDir}/${keyFileName}_pkcs1.pem`;
const tempPkcs1Pem = `${tempDir}/${keyFileName}_pkcs1.pem`;
fs.writeFileSync(tempPem, this.cert.key);
const oldPfxCmd = `openssl rsa -in ${tempPem} -traditional -out ${tempPkcs1Pem}`;
await this.exec(oldPfxCmd);
@@ -159,34 +157,31 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
privateKey = fileBuffer.toString();
fs.unlinkSync(tempPem);
fs.unlinkSync(tempPkcs1Pem);
}catch (e) {
this.logger.warn("私钥转换为PKCS#1格式失败",e);
} catch (e) {
this.logger.warn("私钥转换为PKCS#1格式失败", e);
}
for (const domainName of this.fcDomains) {
const params = new $OpenApi.Params({
// 接口名称
action: 'UpdateCustomDomain',
action: "UpdateCustomDomain",
// 接口版本
version: '2023-03-30',
version: "2023-03-30",
// 接口协议
protocol: 'HTTPS',
protocol: "HTTPS",
// 接口 HTTP 方法
method: 'PUT',
authType: 'AK',
style: 'FC',
method: "PUT",
authType: "AK",
style: "FC",
// 接口 PATH
pathname: `/2023-03-30/custom-domains/${domainName}`,
// 接口请求体内容格式
reqBodyType: 'json',
reqBodyType: "json",
// 接口响应体内容格式
bodyType: 'json',
bodyType: "json",
});
// body params
const certName = this.buildCertName(CertReader.getMainDomain(this.cert.crt),this.certName??"")
const certName = this.buildCertName(CertReader.getMainDomain(this.cert.crt), this.certName ?? "");
const body: { [key: string]: any } = {
certConfig: {
@@ -209,7 +204,7 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
}
async getClient(access: AliyunAccess) {
const $OpenApi = await import('@alicloud/openapi-client');
const $OpenApi = await import("@alicloud/openapi-client");
const config = new $OpenApi.Config({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
@@ -221,30 +216,30 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
async onGetDomainList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
const $OpenApi = await import('@alicloud/openapi-client');
const $Util = await import('@alicloud/tea-util');
const $OpenApi = await import("@alicloud/openapi-client");
const $Util = await import("@alicloud/tea-util");
const params = new $OpenApi.Params({
// 接口名称
action: 'ListCustomDomains',
action: "ListCustomDomains",
// 接口版本
version: '2023-03-30',
version: "2023-03-30",
// 接口协议
protocol: 'HTTPS',
protocol: "HTTPS",
// 接口 HTTP 方法
method: 'GET',
authType: 'AK',
style: 'FC',
method: "GET",
authType: "AK",
style: "FC",
// 接口 PATH
pathname: `/2023-03-30/custom-domains`,
// 接口请求体内容格式
reqBodyType: 'json',
reqBodyType: "json",
// 接口响应体内容格式
bodyType: 'json',
bodyType: "json",
});
const runtime = new $Util.RuntimeOptions({});
@@ -255,7 +250,7 @@ export class AliyunDeployCertToFC extends AbstractTaskPlugin {
const list = res?.body?.customDomains;
if (!list || list.length === 0) {
throw new Error('没有找到FC域名,请先创建FC域名');
throw new Error("没有找到FC域名,请先创建FC域名");
}
const options = list.map((item: any) => {
@@ -1,9 +1,6 @@
import { AbstractTaskPlugin, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/ssl-client.js";
@@ -16,9 +13,9 @@ import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/ssl-c
needPlus: false,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class AliyunDeployCertToGA extends AbstractTaskPlugin {
@TaskInput({
@@ -26,11 +23,11 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
helper: "请选择证书申请任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames, 'uploadCertToAliyun']
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true
required: true,
})
cert!: CertInfo|number | CasCertId;
cert!: CertInfo | number | CasCertId;
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@@ -43,10 +40,10 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
name: "a-select",
options: [
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" }
]
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
],
},
required: true
required: true,
})
casEndpoint!: string;
@@ -55,9 +52,9 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "access-selector",
type: "aliyun"
type: "aliyun",
},
required: true
required: true,
})
accessId!: string;
@@ -77,7 +74,7 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
title: "监听",
helper: "请选择要部署证书的监听",
action: AliyunDeployCertToGA.prototype.onGetListenerList.name,
watches: ["accessId", "acceleratorId"]
watches: ["accessId", "acceleratorId"],
})
)
listenerIds!: string[];
@@ -90,8 +87,8 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
name: "a-select",
options: [
{ value: "default", label: "默认证书" },
{ value: "additional", label: "扩展证书" }
]
{ value: "additional", label: "扩展证书" },
],
},
required: true,
})
@@ -109,21 +106,20 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
return form.certType === "additional";
})
}
`
`,
})
)
additionalDomains!: string[];
async onInstance() {
}
async onInstance() {}
async getAliyunCertId(access: AliyunAccess) {
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
endpoint: this.casEndpoint
endpoint: this.casEndpoint,
});
return await sslClient.uploadCertOrGet(this.cert as any)
return await sslClient.uploadCertOrGet(this.cert as any);
}
async execute(): Promise<void> {
@@ -133,7 +129,7 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
const client = await this.getClient(access);
const { certIdentifier } = await this.getAliyunCertId(access);
for (const listenerId of this.listenerIds) {
if (this.certType === "default") {
// 更新默认证书
@@ -146,11 +142,9 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
RegionId: "cn-hangzhou",
AcceleratorId: this.acceleratorId,
ListenerId: listenerId,
Certificates: [
{ Id: certIdentifier},
]
}
}
Certificates: [{ Id: certIdentifier }],
},
},
});
this.logger.info(`部署默认证书到实例[${this.acceleratorId}]监听[${listenerId}]成功:${JSON.stringify(res)}`);
} else if (this.certType === "additional") {
@@ -166,14 +160,12 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
query: {
RegionId: "cn-hangzhou",
AcceleratorId: this.acceleratorId,
ListenerId: listenerId
}
}
ListenerId: listenerId,
},
},
});
const domainExists = existingCerts.Certificates?.some((cert: any) =>
cert.Domain === domain
);
const domainExists = existingCerts.Certificates?.some((cert: any) => cert.Domain === domain);
if (domainExists) {
// 更新扩展证书
@@ -187,9 +179,9 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
AcceleratorId: this.acceleratorId,
ListenerId: listenerId,
Domain: domain,
CertificateId: certIdentifier
}
}
CertificateId: certIdentifier,
},
},
});
this.logger.info(`更新扩展证书到实例[${this.acceleratorId}]监听[${listenerId}]域名[${domain}]成功:${JSON.stringify(res)}`);
} else {
@@ -203,12 +195,14 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
RegionId: "cn-hangzhou",
AcceleratorId: this.acceleratorId,
ListenerId: listenerId,
Certificates: [{
Id: certIdentifier,
Domain: domain
}]
}
}
Certificates: [
{
Id: certIdentifier,
Domain: domain,
},
],
},
},
});
this.logger.info(`新增扩展证书绑定到实例[${this.acceleratorId}]监听[${listenerId}]域名[${domain}]成功:${JSON.stringify(res)}`);
}
@@ -228,8 +222,8 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
throw new Error("请选择Access授权");
}
const pager = new Pager(data)
pager.pageSize = 50
const pager = new Pager(data);
pager.pageSize = 50;
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
@@ -242,9 +236,9 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
RegionId: "cn-hangzhou",
PageNumber: pager.pageNo,
PageSize: pager.pageSize,
State: "active"
}
}
State: "active",
},
},
});
const list = res?.Accelerators;
@@ -253,7 +247,7 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
}
const options = list.map((item: any) => {
const label = `${item.Name} (${item.AcceleratorId})`
const label = `${item.Name} (${item.AcceleratorId})`;
return {
label: label,
value: item.AcceleratorId,
@@ -279,9 +273,9 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
data: {
query: {
RegionId: "cn-hangzhou",
AcceleratorId: this.acceleratorId
}
}
AcceleratorId: this.acceleratorId,
},
},
});
const listeners = res?.Listeners;
@@ -327,4 +321,4 @@ export class AliyunDeployCertToGA extends AbstractTaskPlugin {
}
}
new AliyunDeployCertToGA();
new AliyunDeployCertToGA();
@@ -1,15 +1,15 @@
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertApplyPluginNames } from '@certd/plugin-cert';
import { CertInfo, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js';
import { AliyunSslClient, CasCertId } from '../../../plugin-lib/aliyun/lib/index.js';
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames } from "@certd/plugin-cert";
import { CertInfo, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'DeployCertToAliyunLive',
title: '阿里云-部署至直播(Live',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunLive",
title: "阿里云-部署至直播(Live",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署证书到阿里云视频直播(Live)域名',
desc: "部署证书到阿里云视频直播(Live)域名",
needPlus: false,
default: {
strategy: {
@@ -18,14 +18,12 @@ import { AliyunSslClient, CasCertId } from '../../../plugin-lib/aliyun/lib/index
},
})
export class DeployCertToAliyunLive extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
template: false,
required: true,
@@ -35,28 +33,27 @@ export class DeployCertToAliyunLive extends AbstractTaskPlugin {
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书服务接入点',
helper: '不会选就按默认',
value: 'cas.aliyuncs.com',
title: "证书服务接入点",
helper: "不会选就按默认",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true,
@@ -65,11 +62,11 @@ export class DeployCertToAliyunLive extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: '直播域名',
helper: '请选择要部署证书的直播域名',
typeName: 'DeployCertToAliyunLive',
title: "直播域名",
helper: "请选择要部署证书的直播域名",
typeName: "DeployCertToAliyunLive",
action: DeployCertToAliyunLive.prototype.onGetDomainList.name,
watches: ['certDomains', 'accessId'],
watches: ["certDomains", "accessId"],
pager: true,
search: true,
})
@@ -79,18 +76,18 @@ export class DeployCertToAliyunLive extends AbstractTaskPlugin {
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云直播');
this.logger.info("开始部署证书到阿里云直播");
const access = await this.getAccess<AliyunAccess>(this.accessId);
if (this.cert == null) {
throw new Error('域名证书参数为空,请检查前置任务');
throw new Error("域名证书参数为空,请检查前置任务");
}
const client = await this.getClient(access);
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
endpoint: this.endpoint || 'cas.aliyuncs.com',
endpoint: this.endpoint || "cas.aliyuncs.com",
});
// 确保证书已上传到 CAS,统一使用 cas 方式部署
@@ -98,39 +95,39 @@ export class DeployCertToAliyunLive extends AbstractTaskPlugin {
// const certName = this.appendTimeSuffix(this.certName || casCert.certName);
for (const domain of this.domainList) {
const res = await client.doRequest({
action: 'SetLiveDomainCertificate',
version: '2016-11-01',
protocol: 'HTTPS',
action: "SetLiveDomainCertificate",
version: "2016-11-01",
protocol: "HTTPS",
data: {
query: {
DomainName: domain,
CertName: casCert.certName,
CertType: 'cas',
SSLProtocol: 'on',
CertType: "cas",
SSLProtocol: "on",
CertId: casCert.certId,
},
},
});
this.logger.info('部署直播域名[' + domain + ']证书成功:' + JSON.stringify(res));
this.logger.info("部署直播域名[" + domain + "]证书成功:" + JSON.stringify(res));
}
}
async getClient(access: AliyunAccess) {
const endpoint = 'live.aliyuncs.com';
const endpoint = "live.aliyuncs.com";
return access.getClient(endpoint);
}
async onGetDomainList(data: PageSearch) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
const res = await client.doRequest({
action: 'DescribeLiveUserDomains',
version: '2016-11-01',
protocol: 'HTTPS',
action: "DescribeLiveUserDomains",
version: "2016-11-01",
protocol: "HTTPS",
data: {
query: {
DomainName: data.searchKey || undefined,
@@ -142,7 +139,7 @@ export class DeployCertToAliyunLive extends AbstractTaskPlugin {
const list = res?.Domains?.PageData;
if (!list || list.length === 0) {
throw new Error('没有找到直播域名,请先在阿里云添加直播域名');
throw new Error("没有找到直播域名,请先在阿里云添加直播域名");
}
const options = list.map((item: any) => {
@@ -1,19 +1,16 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { CertApplyPluginNames} from '@certd/plugin-cert';
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { CertApplyPluginNames } from "@certd/plugin-cert";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
import { AliyunClientV2 } from '../../../plugin-lib/aliyun/lib/aliyun-client-v2.js';
import { AliyunClientV2 } from "../../../plugin-lib/aliyun/lib/aliyun-client-v2.js";
@IsTaskPlugin({
name: 'AliyunDeployCertToNLB',
title: '阿里云-部署至NLB(网络负载均衡)',
icon: 'svg:icon-aliyun',
name: "AliyunDeployCertToNLB",
title: "阿里云-部署至NLB(网络负载均衡)",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: 'NLB,网络负载均衡,更新监听器的默认证书',
desc: "NLB,网络负载均衡,更新监听器的默认证书",
needPlus: false,
default: {
strategy: {
@@ -23,11 +20,11 @@ import { AliyunClientV2 } from '../../../plugin-lib/aliyun/lib/aliyun-client-v2.
})
export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -36,17 +33,16 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: '证书接入点',
helper: '不会选就保持默认即可',
value: 'cas.aliyuncs.com',
title: "证书接入点",
helper: "不会选就保持默认即可",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true,
@@ -54,11 +50,11 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
casEndpoint!: string;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
@@ -66,68 +62,64 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'NLB所在地区',
typeName: 'AliyunDeployCertToNLB',
title: "NLB所在地区",
typeName: "AliyunDeployCertToNLB",
single: true,
action: AliyunDeployCertToNLB.prototype.onGetRegionList.name,
watches: ['accessId'],
watches: ["accessId"],
})
)
regionId: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '负载均衡列表',
helper: '要部署证书的负载均衡ID',
typeName: 'AliyunDeployCertToNLB',
title: "负载均衡列表",
helper: "要部署证书的负载均衡ID",
typeName: "AliyunDeployCertToNLB",
action: AliyunDeployCertToNLB.prototype.onGetLoadBalanceList.name,
watches: ['regionId'],
watches: ["regionId"],
})
)
loadBalancers!: string[];
@TaskInput(
createRemoteSelectInputDefine({
title: '监听器列表',
helper: '要部署证书的监听器列表',
typeName: 'AliyunDeployCertToNLB',
title: "监听器列表",
helper: "要部署证书的监听器列表",
typeName: "AliyunDeployCertToNLB",
action: AliyunDeployCertToNLB.prototype.onGetListenerList.name,
watches: ['loadBalancers'],
watches: ["loadBalancers"],
})
)
listeners!: string[];
@TaskInput({
title: "部署证书类型",
value: "default",
component: {
name: "a-select",
vModel: "value",
options: [
{
label: "默认证书",
value: "default"
},
{
label: "扩展证书",
value: "extension"
}
]
},
required: true
}
)
deployType: string = "default";
title: "部署证书类型",
value: "default",
component: {
name: "a-select",
vModel: "value",
options: [
{
label: "默认证书",
value: "default",
},
{
label: "扩展证书",
value: "extension",
},
],
},
required: true,
})
deployType = "default";
async onInstance() {}
async getLBClient(access: AliyunAccess, region: string) {
const client = new AliyunClient({ logger: this.logger });
const version = '2022-04-30';
const version = "2022-04-30";
await client.init({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
@@ -152,16 +144,16 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
}
this.logger.info(`准备开始清理过期证书`);
await this.ctx.utils.sleep(30000)
await this.ctx.utils.sleep(30000);
for (const listener of this.listeners) {
try{
try {
await this.clearInvalidCert(nlbClientV2, listener);
}catch(e){
} catch (e) {
this.logger.error(`清理监听器${listener}的过期证书失败`, e);
}
}
this.logger.info('执行完成');
this.logger.info("执行完成");
}
async deployExtensionCert(client: AliyunClientV2, certId: any) {
@@ -176,32 +168,30 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
body: {
ListenerId: listenerId,
RegionId: this.regionId,
"AdditionalCertificateIds.1": certId
}
}
"AdditionalCertificateIds.1": certId,
},
},
});
this.logger.info(`部署监听器${listenerId}的扩展证书成功`);
}
}
async deployDefaultCert(certId: any, client: AliyunClient) {
for (const listener of this.listeners) {
//查询原来的证书
const params: any = {
RegionId: this.regionId,
ListenerId: listener,
CertificateIds:[certId], //旧sdk
CertificateIds: [certId], //旧sdk
};
const res = await client.request('UpdateListenerAttribute', params);
const res = await client.request("UpdateListenerAttribute", params);
this.checkRet(res);
this.logger.info(`部署${listener}监听器证书成功`, JSON.stringify(res));
}
}
getNLBClientV2(access: AliyunAccess) {
return access.getClient(`nlb.${this.regionId}.aliyuncs.com`);
}
@@ -216,24 +206,23 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
data: {
body: {
ListenerId: listener,
RegionId: this.regionId
}
}
RegionId: this.regionId,
},
},
};
const res = await client.doRequest(req);
const list = res.Certificates;
if (list.length === 0) {
this.logger.info(`监听器${listener}没有绑定证书`);
return
return;
}
const sslClient = new AliyunSslClient({
access: client.access,
logger: this.logger,
endpoint: this.casEndpoint
endpoint: this.casEndpoint,
});
const certIds = [];
for (const item of list) {
this.logger.info(`监听器${listener}绑定的证书${item.CertificateId},status:${item.Status},IsDefault:${item.IsDefault}`);
@@ -243,7 +232,7 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
if (item.IsDefault) {
continue;
}
certIds.push( parseInt(item.CertificateId));
certIds.push(parseInt(item.CertificateId));
}
this.logger.info(`监听器${listener}绑定的证书${certIds}`);
//检查是否过期,过期则删除
@@ -257,14 +246,14 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
}
if (invalidCertIds.length === 0) {
this.logger.info(`监听器${listener}没有过期的证书`);
return
return;
}
this.logger.info(`开始解绑过期的证书:${invalidCertIds},listener:${listener}`);
const ids:any = {}
let i = 0
const ids: any = {};
let i = 0;
for (const certId of invalidCertIds) {
i++
i++;
ids[`AdditionalCertificateIds.${i}`] = certId;
}
await client.doRequest({
@@ -276,17 +265,16 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
body: {
ListenerId: listener,
RegionId: this.regionId,
...ids
}
}
...ids,
},
},
});
this.logger.info(`解绑过期证书成功`);
}
async getAliyunCertId(access: AliyunAccess) {
let certId: any = this.cert;
if (typeof this.cert === 'object') {
if (typeof this.cert === "object") {
const casCert = this.cert as CasCertId;
if (casCert.certId) {
return casCert.certId;
@@ -300,7 +288,7 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
endpoint: this.casEndpoint,
});
const certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt))
const certName = this.buildCertName(CertReader.getMainDomain(certInfo.crt));
const certIdRes = await sslClient.uploadCertificate({
name: certName,
@@ -313,15 +301,15 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
async onGetRegionList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, 'cn-shanghai');
const client = await this.getLBClient(access, "cn-shanghai");
const res = await client.request('DescribeRegions', {});
const res = await client.request("DescribeRegions", {});
this.checkRet(res);
if (!res?.Regions || res?.Regions.length === 0) {
throw new Error('没有找到Regions列表');
throw new Error("没有找到Regions列表");
}
return res.Regions.map((item: any) => {
@@ -335,10 +323,10 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
async onGetLoadBalanceList(data: any) {
if (!this.accessId) {
throw new Error('请先选择Access授权');
throw new Error("请先选择Access授权");
}
if (!this.regionId) {
throw new Error('请先选择地区');
throw new Error("请先选择地区");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, this.regionId);
@@ -346,10 +334,10 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
const params = {
MaxResults: 100,
};
const res = await client.request('ListLoadBalancers', params);
const res = await client.request("ListLoadBalancers", params);
this.checkRet(res);
if (!res?.LoadBalancers || res?.LoadBalancers.length === 0) {
throw new Error('没有找到LoadBalancers');
throw new Error("没有找到LoadBalancers");
}
return res.LoadBalancers.map((item: any) => {
@@ -363,10 +351,10 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
async onGetListenerList(data: any) {
if (!this.accessId) {
throw new Error('请先选择Access授权');
throw new Error("请先选择Access授权");
}
if (!this.regionId) {
throw new Error('请先选择地区');
throw new Error("请先选择地区");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, this.regionId);
@@ -377,10 +365,10 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
if (this.loadBalancers && this.loadBalancers.length > 0) {
params.LoadBalancerIds = this.loadBalancers;
}
const res = await client.request('ListListeners', params);
const res = await client.request("ListListeners", params);
this.checkRet(res);
if (!res?.Listeners || res?.Listeners.length === 0) {
throw new Error('没有找到TCPSSL监听器');
throw new Error("没有找到TCPSSL监听器");
}
return res.Listeners.map((item: any) => {
@@ -1,19 +1,16 @@
import { optionsUtils } from "@certd/basic";
import { AbstractTaskPlugin, IsTaskPlugin, Pager, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertApplyPluginNames, CertInfo } from '@certd/plugin-cert';
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from '@certd/plugin-lib';
import { AbstractTaskPlugin, IsTaskPlugin, Pager, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { isArray } from "lodash-es";
import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js';
import { CasCertId } from '../../../plugin-lib/aliyun/lib/index.js';
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'DeployCertToAliyunOSS',
title: '阿里云-部署证书至OSS',
icon: 'svg:icon-aliyun',
name: "DeployCertToAliyunOSS",
title: "阿里云-部署证书至OSS",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署域名证书至阿里云OSS自定义域名,不是上传到阿里云oss',
desc: "部署域名证书至阿里云OSS自定义域名,不是上传到阿里云oss",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -21,13 +18,12 @@ import { CasCertId } from '../../../plugin-lib/aliyun/lib/index.js';
},
})
export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames,"uploadCertToAliyun"],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -36,42 +32,41 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: '大区',
title: "大区",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: [
{ value: 'oss-cn-hangzhou', label: '华东1(杭州)' },
{ value: 'oss-cn-shanghai', label: '华东2(上海)' },
{ value: 'oss-cn-nanjing', label: '华东5(南京-本地地域)' },
{ value: 'oss-cn-fuzhou', label: '华东6(福州-本地地域)' },
{ value: 'oss-cn-wuhan-lr', label: '华中1(武汉-本地地域)' },
{ value: 'oss-cn-qingdao', label: '华北1(青岛)' },
{ value: 'oss-cn-beijing', label: '华北2(北京)' },
{ value: 'oss-cn-zhangjiakou', label: '华北 3(张家口)' },
{ value: 'oss-cn-huhehaote', label: '华北5(呼和浩特)' },
{ value: 'oss-cn-wulanchabu', label: '华北6(乌兰察布)' },
{ value: 'oss-cn-shenzhen', label: '华南1(深圳)' },
{ value: 'oss-cn-heyuan', label: '华南2(河源)' },
{ value: 'oss-cn-guangzhou', label: '华南3(广州)' },
{ value: 'oss-cn-chengdu', label: '西南1(成都)' },
{ value: 'oss-cn-hongkong', label: '中国香港' },
{ value: 'oss-us-west-1', label: '美国(硅谷)①' },
{ value: 'oss-us-east-1', label: '美国(弗吉尼亚)①' },
{ value: 'oss-ap-northeast-1', label: '日本(东京)①' },
{ value: 'oss-ap-northeast-2', label: '韩国(首尔)' },
{ value: 'oss-ap-southeast-1', label: '新加坡①' },
{ value: 'oss-ap-southeast-2', label: '澳大利亚(悉尼)①' },
{ value: 'oss-ap-southeast-3', label: '马来西亚(吉隆坡)①' },
{ value: 'oss-ap-southeast-5', label: '印度尼西亚(雅加达)①' },
{ value: 'oss-ap-southeast-6', label: '菲律宾(马尼拉)' },
{ value: 'oss-ap-southeast-7', label: '泰国(曼谷)' },
{ value: 'oss-eu-central-1', label: '德国(法兰克福)①' },
{ value: 'oss-eu-west-1', label: '英国(伦敦)' },
{ value: 'oss-me-east-1', label: '阿联酋(迪拜)①' },
{ value: 'oss-rg-china-mainland', label: '无地域属性(中国内地)' },
{ value: "oss-cn-hangzhou", label: "华东1(杭州)" },
{ value: "oss-cn-shanghai", label: "华东2(上海)" },
{ value: "oss-cn-nanjing", label: "华东5(南京-本地地域)" },
{ value: "oss-cn-fuzhou", label: "华东6(福州-本地地域)" },
{ value: "oss-cn-wuhan-lr", label: "华中1(武汉-本地地域)" },
{ value: "oss-cn-qingdao", label: "华北1(青岛)" },
{ value: "oss-cn-beijing", label: "华北2(北京)" },
{ value: "oss-cn-zhangjiakou", label: "华北 3(张家口)" },
{ value: "oss-cn-huhehaote", label: "华北5(呼和浩特)" },
{ value: "oss-cn-wulanchabu", label: "华北6(乌兰察布)" },
{ value: "oss-cn-shenzhen", label: "华南1(深圳)" },
{ value: "oss-cn-heyuan", label: "华南2(河源)" },
{ value: "oss-cn-guangzhou", label: "华南3(广州)" },
{ value: "oss-cn-chengdu", label: "西南1(成都)" },
{ value: "oss-cn-hongkong", label: "中国香港" },
{ value: "oss-us-west-1", label: "美国(硅谷)①" },
{ value: "oss-us-east-1", label: "美国(弗吉尼亚)①" },
{ value: "oss-ap-northeast-1", label: "日本(东京)①" },
{ value: "oss-ap-northeast-2", label: "韩国(首尔)" },
{ value: "oss-ap-southeast-1", label: "新加坡①" },
{ value: "oss-ap-southeast-2", label: "澳大利亚(悉尼)①" },
{ value: "oss-ap-southeast-3", label: "马来西亚(吉隆坡)①" },
{ value: "oss-ap-southeast-5", label: "印度尼西亚(雅加达)①" },
{ value: "oss-ap-southeast-6", label: "菲律宾(马尼拉)" },
{ value: "oss-ap-southeast-7", label: "泰国(曼谷)" },
{ value: "oss-eu-central-1", label: "德国(法兰克福)①" },
{ value: "oss-eu-west-1", label: "英国(伦敦)" },
{ value: "oss-me-east-1", label: "阿联酋(迪拜)①" },
{ value: "oss-rg-china-mainland", label: "无地域属性(中国内地)" },
],
},
required: true,
@@ -79,49 +74,48 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
region!: string;
@TaskInput({
title: 'Bucket',
helper: '存储桶名称',
title: "Bucket",
helper: "存储桶名称",
component: {
name: 'remote-auto-complete',
vModel: 'value',
type: 'plugin',
action: 'onGetBucketList',
name: "remote-auto-complete",
vModel: "value",
type: "plugin",
action: "onGetBucketList",
search: false,
pager: false,
watches: ['accessId', 'region']
watches: ["accessId", "region"],
},
required: true,
})
bucket!: string;
@TaskInput(createRemoteSelectInputDefine({
title: '绑定的域名',
helper: '你在阿里云OSS上绑定的域名,比如:certd.docmirror.cn',
required: true,
action: DeployCertToAliyunOSS.prototype.onGetDomainList.name,
watches: ['certDomains', 'accessId','bucket'],
}))
@TaskInput(
createRemoteSelectInputDefine({
title: "绑定的域名",
helper: "你在阿里云OSS上绑定的域名,比如:certd.docmirror.cn",
required: true,
action: DeployCertToAliyunOSS.prototype.onGetDomainList.name,
watches: ["certDomains", "accessId", "bucket"],
})
)
domainName!: string | string[];
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
title: "证书名称",
helper: "上传后将以此名称作为前缀备注",
})
certName!: string;
@TaskInput({
title: '证书服务接入点',
helper: '不会选就按默认',
value: 'cn-hangzhou',
title: "证书服务接入点",
helper: "不会选就按默认",
value: "cn-hangzhou",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cn-hangzhou', label: '中国大陆' },
{ value: 'ap-southeast-1', label: '新加坡' },
{ value: 'eu-central-1', label: '德国(法兰克福)' },
{ value: "cn-hangzhou", label: "中国大陆" },
{ value: "ap-southeast-1", label: "新加坡" },
{ value: "eu-central-1", label: "德国(法兰克福)" },
],
},
required: true,
@@ -130,11 +124,11 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
casRegion!: string;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
order: -98,
@@ -143,44 +137,43 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云OSS');
this.logger.info("开始部署证书到阿里云OSS");
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
this.logger.info(`bucket: ${this.bucket}, region: ${this.region}, domainName: ${this.domainName}`);
const client = await this.getClient(access);
if (typeof this.domainName === "string"){
if (typeof this.domainName === "string") {
this.domainName = [this.domainName];
}
for (const domainName of this.domainName) {
this.logger.info("开始部署证书到阿里云oss自定义域名:", domainName)
await this.updateCert(domainName,client, {});
this.logger.info("开始部署证书到阿里云oss自定义域名:", domainName);
await this.updateCert(domainName, client, {});
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async updateCert(domainName:string,client: any, params: any) {
params = client._bucketRequestParams('POST', this.bucket, {
cname: '',
comp: 'add',
async updateCert(domainName: string, client: any, params: any) {
params = client._bucketRequestParams("POST", this.bucket, {
cname: "",
comp: "add",
});
let certStr = ""
let certStr = "";
if (typeof this.cert === "object" ){
if (typeof this.cert === "object") {
const certInfo = this.cert as CertInfo;
if (certInfo.crt){
if (certInfo.crt) {
certStr = `
<PrivateKey>${certInfo.key}</PrivateKey>
<Certificate>${certInfo.crt}</Certificate>
`
}else {
`;
} else {
const casCert = this.cert as CasCertId;
certStr = `<CertId>${casCert.certIdentifier}</CertId>`
certStr = `<CertId>${casCert.certIdentifier}</CertId>`;
}
}else {
certStr = `<CertId>${this.cert}-${this.casRegion}</CertId>`
} else {
certStr = `<CertId>${this.cert}-${this.casRegion}</CertId>`;
}
const xml = `
@@ -194,17 +187,16 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
</Cname>
</BucketCnameConfiguration>`;
params.content = xml;
params.mime = 'xml';
params.mime = "xml";
params.successStatuses = [200];
const res = await client.request(params);
this.checkRet(res);
return res;
}
async getClient(access: AliyunAccess) {
// @ts-ignore
const OSS = await import('ali-oss');
const OSS = await import("ali-oss");
return new OSS.default({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
@@ -218,34 +210,30 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
}
async onGetBucketList(data: Pager) {
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
const client = await this.getClient(access);
let res;
const buckets = []
do{
const requestData = {'marker': res?.nextMarker || null, 'max-keys': 1000};
res = await client.listBuckets(requestData)
buckets.push(...(res?.buckets || []))
} while (!!res?.nextMarker)
return buckets
.filter(bucket => bucket?.region === this.region)
.map(bucket => ({label: `${bucket.name}<${bucket.region}>`, value: bucket.name}));
const buckets = [];
do {
const requestData = { marker: res?.nextMarker || null, "max-keys": 1000 };
res = await client.listBuckets(requestData);
buckets.push(...(res?.buckets || []));
} while (!!res?.nextMarker);
return buckets.filter(bucket => bucket?.region === this.region).map(bucket => ({ label: `${bucket.name}<${bucket.region}>`, value: bucket.name }));
}
async onGetDomainList(data: any) {
const access = (await this.getAccess(this.accessId)) as AliyunAccess;
const client = await this.getClient(access);
const res = await this.doListCnameRequest(client,this.bucket)
let domains = res.data?.Cname
if (domains == null || domains.length === 0){
return []
const res = await this.doListCnameRequest(client, this.bucket);
let domains = res.data?.Cname;
if (domains == null || domains.length === 0) {
return [];
}
if (!isArray(domains)){
domains = [domains]
if (!isArray(domains)) {
domains = [domains];
}
const options = domains.map((item: any) => {
@@ -258,13 +246,12 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
return optionsUtils.buildGroupOptions(options, this.certDomains);
}
async doListCnameRequest(client: any,bucket:string) {
const params = client._bucketRequestParams('GET', this.bucket, {
cname: '',
bucket
async doListCnameRequest(client: any, bucket: string) {
const params = client._bucketRequestParams("GET", this.bucket, {
cname: "",
bucket,
});
params.mime = 'xml';
params.mime = "xml";
params.successStatuses = [200];
params.xmlResponse = true;
const res = await client.request(params);
@@ -272,11 +259,9 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
return res;
}
checkRet(ret: any) {
if (ret.Code != null || ret.status!==200) {
throw new Error('执行失败:' + ret.Message || ret.data);
if (ret.Code != null || ret.status !== 200) {
throw new Error("执行失败:" + ret.Message || ret.data);
}
}
}
@@ -1,19 +1,16 @@
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo } from '@certd/plugin-cert';
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from '@certd/plugin-lib';
import { CertApplyPluginNames } from '@certd/plugin-cert';
import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js';
import { AliyunClient, AliyunSslClient, CasCertInfo } from '../../../plugin-lib/aliyun/lib/index.js';
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertInfo } from "@certd/plugin-cert";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { CertApplyPluginNames } from "@certd/plugin-cert";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertInfo } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'AliyunDeployCertToSLB',
title: '阿里云-部署至CLB(传统负载均衡)',
icon: 'svg:icon-aliyun',
name: "AliyunDeployCertToSLB",
title: "阿里云-部署至CLB(传统负载均衡)",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署证书到阿里云CLB(传统负载均衡)',
desc: "部署证书到阿里云CLB(传统负载均衡)",
needPlus: false,
default: {
strategy: {
@@ -23,11 +20,11 @@ import { AliyunClient, AliyunSslClient, CasCertInfo } from '../../../plugin-lib/
})
export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -36,77 +33,71 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: '证书接入点',
helper: '不会选就保持默认即可',
value: 'cas.aliyuncs.com',
title: "证书接入点",
helper: "不会选就保持默认即可",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ 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',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: 'LB所在地区',
title: "LB所在地区",
single: true,
action: AliyunDeployCertToSLB.prototype.onGetRegionList.name,
watches: ['accessId'],
watches: ["accessId"],
})
)
regionId: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '负载均衡列表',
helper: '要部署证书的负载均衡ID',
title: "负载均衡列表",
helper: "要部署证书的负载均衡ID",
action: AliyunDeployCertToSLB.prototype.onGetLoadBalanceList.name,
watches: ['regionId'],
watches: ["regionId"],
})
)
loadBalancers!: string[];
@TaskInput(
createRemoteSelectInputDefine({
title: '监听器列表',
helper: '要部署证书的监听器列表',
title: "监听器列表",
helper: "要部署证书的监听器列表",
action: AliyunDeployCertToSLB.prototype.onGetListenerList.name,
watches: ['loadBalancers'],
watches: ["loadBalancers"],
})
)
listeners!: string[];
@TaskInput({
title: "部署默认证书",
value: true,
component: {
name: "a-switch",
vModel: "checked"
}
}
)
vModel: "checked",
},
})
deployDefault!: boolean;
@TaskInput({
@@ -114,37 +105,33 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
value: false,
component: {
name: "a-switch",
vModel: "checked"
}
}
)
vModel: "checked",
},
})
deployExtension!: boolean;
@TaskInput(
createRemoteSelectInputDefine({
title: '扩展域名列表',
helper: '要部署扩展域名列表',
title: "扩展域名列表",
helper: "要部署扩展域名列表",
action: AliyunDeployCertToSLB.prototype.onGetExtensionDomainList.name,
watches: ['listeners', 'deployExtension'],
watches: ["listeners", "deployExtension"],
mergeScript: `
return {
show: ctx.compute(({form})=>{
return form.deployExtension;
})
}
`
`,
})
)
extensionDomains!: string[];
async onInstance() {
}
async onInstance() {}
async getLBClient(access: AliyunAccess, region: string) {
const client = new AliyunClient({ logger: this.logger });
const version = '2014-05-15';
const version = "2014-05-15";
await client.init({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
@@ -164,9 +151,9 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
const slbServerCertId = await this.uploadServerCert(client, aliyunCert);
if (this.deployDefault !== false) {
this.logger.info("部署监听器默认证书")
this.logger.info("部署监听器默认证书");
for (const listener of this.listeners) {
const { port, loadBalanceId } = this.resolveListenerKey(listener)
const { port, loadBalanceId } = this.resolveListenerKey(listener);
const params = {
RegionId: this.regionId,
LoadBalancerId: loadBalanceId,
@@ -174,18 +161,18 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
ServerCertificateId: slbServerCertId,
};
const res = await client.request('SetLoadBalancerHTTPSListenerAttribute', params);
const res = await client.request("SetLoadBalancerHTTPSListenerAttribute", params);
this.checkRet(res);
this.logger.info(`部署${listener}监听器证书成功`, JSON.stringify(res));
}
}
if (this.deployExtension) {
this.logger.info("部署监听器扩展域名证书")
this.logger.info("部署监听器扩展域名证书");
const clientV2 = this.getCLBClientV2(access);
for (const domainStr of this.extensionDomains) {
const { extensionDomainId } = this.resolveListenerKey(domainStr)
const { extensionDomainId } = this.resolveListenerKey(domainStr);
const res = await clientV2.doRequest({
action: "SetDomainExtensionAttribute",
// 接口版本
@@ -194,22 +181,22 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
query: {
RegionId: this.regionId,
DomainExtensionId: extensionDomainId,
ServerCertificateId: slbServerCertId
}
}
})
this.logger.info(`部署扩展域名${extensionDomainId}证书成功`, JSON.stringify(res))
ServerCertificateId: slbServerCertId,
},
},
});
this.logger.info(`部署扩展域名${extensionDomainId}证书成功`, JSON.stringify(res));
}
}
this.logger.info('执行完成');
this.logger.info("执行完成");
}
getCLBClientV2(access: AliyunAccess) {
return access.getClient(`slb.${this.regionId}.aliyuncs.com`)
return access.getClient(`slb.${this.regionId}.aliyuncs.com`);
}
resolveListenerKey(listener: string) {
const arr = listener.split('_');
const arr = listener.split("_");
const loadBalanceId = arr[0];
const protocol = arr[1];
const port = arr[2];
@@ -222,8 +209,8 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
loadBalanceId,
port: parseInt(port),
extensionDomainId: extensionDomainId,
protocol: protocol
}
protocol: protocol,
};
}
async uploadServerCert(client: any, aliyunCert: CasCertInfo) {
@@ -231,12 +218,12 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
RegionId: this.regionId,
AliCloudCertificateId: aliyunCert.certId,
AliCloudCertificateName: aliyunCert.certName,
AliCloudCertificateRegionId: aliyunCert.casRegion
AliCloudCertificateRegionId: aliyunCert.casRegion,
};
const res = await client.request('UploadServerCertificate', params);
const res = await client.request("UploadServerCertificate", params);
this.checkRet(res);
this.logger.info('SLBServerCertificate创建成功', res.ServerCertificateId);
this.logger.info("SLBServerCertificate创建成功", res.ServerCertificateId);
return res.ServerCertificateId;
}
@@ -249,8 +236,8 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
endpoint: this.casEndpoint,
});
if (typeof this.cert === 'object') {
const name = this.appendTimeSuffix('certd');
if (typeof this.cert === "object") {
const name = this.appendTimeSuffix("certd");
const casCert = this.cert as CasCertInfo;
if (casCert.certIdentifier) {
@@ -263,8 +250,6 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
});
certId = certIdRes.certId as any;
}
}
return await sslClient.getCertInfo(certId);
@@ -272,15 +257,15 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
async onGetRegionList(data: any) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, 'cn-shanghai');
const client = await this.getLBClient(access, "cn-shanghai");
const res = await client.request('DescribeRegions', {});
const res = await client.request("DescribeRegions", {});
this.checkRet(res);
if (!res?.Regions?.Region || res?.Regions?.Region.length === 0) {
throw new Error('没有找到Regions列表');
throw new Error("没有找到Regions列表");
}
return res.Regions.Region.map((item: any) => {
@@ -294,10 +279,10 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
async onGetLoadBalanceList(data: any) {
if (!this.accessId) {
throw new Error('请先选择Access授权');
throw new Error("请先选择Access授权");
}
if (!this.regionId) {
throw new Error('请先选择地区');
throw new Error("请先选择地区");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, this.regionId);
@@ -306,10 +291,10 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
RegionId: this.regionId,
MaxResults: 100,
};
const res = await client.request('DescribeLoadBalancers', params);
const res = await client.request("DescribeLoadBalancers", params);
this.checkRet(res);
if (!res?.LoadBalancers?.LoadBalancer || res?.LoadBalancers.LoadBalancer.length === 0) {
throw new Error('没有找到LoadBalancers');
throw new Error("没有找到LoadBalancers");
}
return res.LoadBalancers.LoadBalancer.map((item: any) => {
@@ -323,10 +308,10 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
async onGetListenerList(data: any) {
if (!this.accessId) {
throw new Error('请先选择Access授权');
throw new Error("请先选择Access授权");
}
if (!this.regionId) {
throw new Error('请先选择地区');
throw new Error("请先选择地区");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getLBClient(access, this.regionId);
@@ -334,15 +319,15 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
const params: any = {
MaxResults: 100,
RegionId: this.regionId,
ListenerProtocol: 'HTTPS',
ListenerProtocol: "HTTPS",
};
if (this.loadBalancers && this.loadBalancers.length > 0) {
params.LoadBalancerId = this.loadBalancers;
}
const res = await client.request('DescribeLoadBalancerListeners', params);
const res = await client.request("DescribeLoadBalancerListeners", params);
this.checkRet(res);
if (!res?.Listeners || res?.Listeners.length === 0) {
throw new Error('没有找到HTTPS监听器');
throw new Error("没有找到HTTPS监听器");
}
return res.Listeners.map((item: any) => {
@@ -357,46 +342,39 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
async onGetExtensionDomainList(data: PageSearch) {
if (!this.accessId) {
throw new Error('请先选择Access授权');
throw new Error("请先选择Access授权");
}
if (!this.regionId) {
throw new Error('请先选择地区');
throw new Error("请先选择地区");
}
if (!this.listeners && this.listeners.length == 0) {
throw new Error('请先选择监听器');
throw new Error("请先选择监听器");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const allDomains: any[] = []
const allDomains: any[] = [];
for (const ls of this.listeners) {
const { port, loadBalanceId, protocol } = this.resolveListenerKey(ls)
const { port, loadBalanceId, protocol } = this.resolveListenerKey(ls);
const domains = await this.doGetExtensionDomainList({
access,
loadBalancerId: loadBalanceId,
listenerPort: port,
listenerProtocol: protocol,
});
allDomains.push(...domains)
allDomains.push(...domains);
}
return this.ctx.utils.options.buildGroupOptions(allDomains, this.certDomains)
return this.ctx.utils.options.buildGroupOptions(allDomains, this.certDomains);
}
async doGetExtensionDomainList(data: {
loadBalancerId: string,
listenerPort: number,
listenerProtocol: string,
access: AliyunAccess
}) {
async doGetExtensionDomainList(data: { loadBalancerId: string; listenerPort: number; listenerProtocol: string; access: AliyunAccess }) {
const { loadBalancerId, listenerPort, listenerProtocol, access } = data;
const client = access.getClient(`slb.${this.regionId}.aliyuncs.com`)
const client = access.getClient(`slb.${this.regionId}.aliyuncs.com`);
let queries = {
const queries = {
RegionId: this.regionId,
LoadBalancerId: loadBalancerId,
ListenerPort: listenerPort
ListenerPort: listenerPort,
};
const res = await client.doRequest({
@@ -406,13 +384,13 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
version: "2014-05-15",
data: {
query: queries,
}
})
},
});
this.checkRet(res);
const list = res?.DomainExtensions.DomainExtension;
if (!list || list.length === 0) {
return []
return [];
}
return list.map((i: any) => {
@@ -421,12 +399,11 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
return {
value: value,
label: label,
domain: i.Domain
domain: i.Domain,
};
});
}
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error(ret.Message);
@@ -12,9 +12,9 @@ import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
needPlus: false,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class AliyunDeployCertToVod extends AbstractTaskPlugin {
@TaskInput({
@@ -22,9 +22,9 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
helper: "请选择证书申请任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames]
from: [...CertApplyPluginNames],
},
required: true
required: true,
})
cert!: CertInfo;
@@ -55,22 +55,21 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
options: [
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" }
]
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true
required: true,
})
casEndpoint!: string;
@TaskInput({
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "access-selector",
type: "aliyun"
type: "aliyun",
},
required: true
required: true,
})
accessId!: string;
@@ -81,15 +80,12 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
action: AliyunDeployCertToVod.prototype.onGetDomainList.name,
watches: ["accessId"],
pager: true,
search: true
search: true,
})
)
domainList!: string[];
async onInstance() {
}
async onInstance() {}
async execute(): Promise<void> {
this.logger.info("开始部署证书到阿里云VOD");
@@ -97,7 +93,6 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
const client = await this.getClient(access);
for (const siteId of this.domainList) {
/**
* let queries : {[key: string ]: any} = { };
@@ -122,9 +117,9 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
CertName: this.appendTimeSuffix("certd"),
SSLProtocol: "on",
SSLPub: this.cert.crt,
SSLPri: this.cert.key
}
}
SSLPri: this.cert.key,
},
},
});
this.logger.info(`部署站点[${siteId}]证书成功:${JSON.stringify(res)}`);
}
@@ -161,9 +156,9 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
query: {
DomainName: data.searchKey,
PageNumber: data.pageNo,
PageSize: data.pageSize
}
}
PageSize: data.pageSize,
},
},
});
const list = res?.Domains.PageData;
@@ -175,12 +170,11 @@ export class AliyunDeployCertToVod extends AbstractTaskPlugin {
return {
label: item.DomainName,
value: item.DomainName,
domain: item.DomainName
domain: item.DomainName,
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
}
}
new AliyunDeployCertToVod();
@@ -1,18 +1,15 @@
import { AbstractTaskPlugin, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertInfo } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'AliyunDeployCertToWafCloud',
title: '阿里云-部署至阿里云WAF(云产品接入)',
icon: 'svg:icon-aliyun',
name: "AliyunDeployCertToWafCloud",
title: "阿里云-部署至阿里云WAF(云产品接入)",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署证书到阿里云WAF(云产品接入),CNAME方式接入的请选择另外一个waf插件',
desc: "部署证书到阿里云WAF(云产品接入),CNAME方式接入的请选择另外一个waf插件",
needPlus: false,
default: {
strategy: {
@@ -22,11 +19,11 @@ import { AliyunClient, AliyunSslClient, CasCertInfo } from "../../../plugin-lib/
})
export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -36,14 +33,14 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'WAF接入点',
helper: '不会选就按默认',
value: 'cn-hangzhou',
title: "WAF接入点",
helper: "不会选就按默认",
value: "cn-hangzhou",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cn-hangzhou', label: '中国内地' },
{ value: 'ap-southeast-1', label: '非中国内地' },
{ value: "cn-hangzhou", label: "中国内地" },
{ value: "ap-southeast-1", label: "非中国内地" },
],
},
required: true,
@@ -51,15 +48,15 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
regionId!: string;
@TaskInput({
title: '证书接入点',
helper: '跟上面保持一致即可',
value: 'cas.aliyuncs.com',
title: "证书接入点",
helper: "跟上面保持一致即可",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true,
@@ -67,11 +64,11 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
casEndpoint!: string;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
@@ -79,33 +76,31 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: '云产品资源',
helper: '请选择要部署证书的云产品资源',
title: "云产品资源",
helper: "请选择要部署证书的云产品资源",
action: AliyunDeployCertToWafCloud.prototype.onGetCloudResourceList.name,
watches: ['accessId', 'regionId'],
watches: ["accessId", "regionId"],
pager: true,
search: true,
})
)
cloudResources!: string[];
@TaskInput({
title: '证书部署类型',
value: 'default',
title: "证书部署类型",
value: "default",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'default', label: '默认证书' },
{ value: 'extension', label: '扩展证书' },
{ value: "default", label: "默认证书" },
{ value: "extension", label: "扩展证书" },
],
},
required: true,
})
certType!: string;
async onInstance() { }
async onInstance() {}
async getWafClient(access: AliyunAccess) {
const client = new AliyunClient({ logger: this.logger });
@@ -113,7 +108,7 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: `https://wafopenapi.${this.regionId}.aliyuncs.com`,
apiVersion: '2021-10-01',
apiVersion: "2021-10-01",
});
return client;
}
@@ -122,17 +117,17 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
const params = {
RegionId: this.regionId,
};
this.logger.info('调用DescribeInstance API', JSON.stringify(params));
const res = await client.request('DescribeInstance', params);
this.logger.info('获取实例ID', res.InstanceId);
this.logger.info("调用DescribeInstance API", JSON.stringify(params));
const res = await client.request("DescribeInstance", params);
this.logger.info("获取实例ID", res.InstanceId);
return res.InstanceId;
}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云WAF(云产品接入)');
this.logger.info("开始部署证书到阿里云WAF(云产品接入)");
const access = await this.getAccess<AliyunAccess>(this.accessId);
let certId: any = this.cert;
if (typeof this.cert === 'object') {
if (typeof this.cert === "object") {
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
@@ -153,16 +148,16 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
} else if (casCert.certId) {
certId = casCert.certId;
} else {
throw new Error('证书格式错误'+JSON.stringify(this.cert));
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
const client = await this.getWafClient(access);
const instanceId = await this.getInstanceId(client);
for (const cloudResourceId of this.cloudResources) {
this.logger.info('开始部署', cloudResourceId);
if (this.certType === 'default') {
this.logger.info("开始部署", cloudResourceId);
if (this.certType === "default") {
// 部署默认证书
const params = {
RegionId: this.regionId,
@@ -170,10 +165,10 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
CloudResourceId: cloudResourceId,
CertId: certId,
};
this.logger.info('调用ModifyCloudResourceDefaultCert API', JSON.stringify(params));
const res = await client.request('ModifyCloudResourceDefaultCert', params);
this.logger.info('部署默认证书成功', JSON.stringify(res));
} else if (this.certType === 'extension') {
this.logger.info("调用ModifyCloudResourceDefaultCert API", JSON.stringify(params));
const res = await client.request("ModifyCloudResourceDefaultCert", params);
this.logger.info("部署默认证书成功", JSON.stringify(res));
} else if (this.certType === "extension") {
// 部署扩展证书
const addCertParams = {
RegionId: this.regionId,
@@ -181,10 +176,10 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
CloudResourceId: cloudResourceId,
CertId: certId,
};
this.logger.info('调用CreateCloudResourceExtensionCert API', JSON.stringify(addCertParams));
const addCertRes = await client.request('CreateCloudResourceExtensionCert', addCertParams);
this.logger.info('部署扩展证书成功', JSON.stringify(addCertRes));
this.logger.info("调用CreateCloudResourceExtensionCert API", JSON.stringify(addCertParams));
const addCertRes = await client.request("CreateCloudResourceExtensionCert", addCertParams);
this.logger.info("部署扩展证书成功", JSON.stringify(addCertRes));
// 清理过期扩展证书
await this.cleanupExpiredExtensionCerts(client, instanceId, cloudResourceId, certId);
}
@@ -193,20 +188,20 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
async cleanupExpiredExtensionCerts(client: AliyunClient, instanceId: string, cloudResourceId: string, currentCertId: string) {
try {
this.logger.info('开始清理过期扩展证书, cloudResourceId: ' + cloudResourceId);
this.logger.info("开始清理过期扩展证书, cloudResourceId: " + cloudResourceId);
// 解析CloudResourceId获取ResourceInstanceId
// CloudResourceId格式:{ResourceInstanceId}-{Port}-{ResourceProduct}
const resourceInfo = cloudResourceId.split('-');
const resourceInfo = cloudResourceId.split("-");
if (resourceInfo.length < 3) {
this.logger.warn('CloudResourceId格式不正确: ' + cloudResourceId);
this.logger.warn("CloudResourceId格式不正确: " + cloudResourceId);
return;
}
// 从后往前解析,因为ResourceInstanceId可能包含"-"
const product = resourceInfo.pop();
const port = resourceInfo.pop();
const resourceInstanceId = resourceInfo.join('-');
this.logger.info('ResourceInstanceId: ' + resourceInstanceId, 'Port: ' + port, 'Product: ' + product);
const resourceInstanceId = resourceInfo.join("-");
this.logger.info("ResourceInstanceId: " + resourceInstanceId, "Port: " + port, "Product: " + product);
// 查询云产品实例的证书列表
const certsParams = {
InstanceId: instanceId,
@@ -214,22 +209,22 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
ResourceInstanceId: resourceInstanceId,
PageSize: 100,
};
this.logger.info('调用DescribeResourceInstanceCerts API: ' + JSON.stringify(certsParams));
const certsRes = await client.request('DescribeResourceInstanceCerts', certsParams);
this.logger.info("调用DescribeResourceInstanceCerts API: " + JSON.stringify(certsParams));
const certsRes = await client.request("DescribeResourceInstanceCerts", certsParams);
if (!certsRes || !certsRes.Certs || certsRes.Certs.length === 0) {
this.logger.info('没有找到证书, cloudResourceId: ' + cloudResourceId);
this.logger.info("没有找到证书, cloudResourceId: " + cloudResourceId);
return;
}
this.logger.info('查询到的证书数量: ' + certsRes.Certs.length);
this.logger.info("查询到的证书数量: " + certsRes.Certs.length);
const now = Date.now();
const expiredCerts = certsRes.Certs.filter((cert: any) => {
// 检查证书是否有必要的属性
if (!cert || !cert.AfterDate || !cert.CertIdentifier) {
this.logger.warn('证书格式不正确: ' + JSON.stringify(cert));
this.logger.warn("证书格式不正确: " + JSON.stringify(cert));
return false;
}
// 检查是否为当前部署的证书
if (cert.CertIdentifier === currentCertId) {
return false;
@@ -239,13 +234,13 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
// 检查是否过期
return afterDate < now;
});
if (expiredCerts.length === 0) {
this.logger.info('没有过期的扩展证书, cloudResourceId: ' + cloudResourceId);
this.logger.info("没有过期的扩展证书, cloudResourceId: " + cloudResourceId);
return;
}
this.logger.info('过期的扩展证书数量: ' + expiredCerts.length);
this.logger.info("过期的扩展证书数量: " + expiredCerts.length);
// 删除过期的扩展证书
for (const expiredCert of expiredCerts) {
const deleteParams = {
@@ -254,26 +249,26 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
CloudResourceId: cloudResourceId,
CertId: expiredCert.CertIdentifier,
};
this.logger.info('调用DeleteCloudResourceExtensionCert API: ' + JSON.stringify(deleteParams));
const deleteRes = await client.request('DeleteCloudResourceExtensionCert', deleteParams);
this.logger.info('删除过期扩展证书成功, certId: ' + expiredCert.CertIdentifier + ', response: ' + JSON.stringify(deleteRes));
this.logger.info("调用DeleteCloudResourceExtensionCert API: " + JSON.stringify(deleteParams));
const deleteRes = await client.request("DeleteCloudResourceExtensionCert", deleteParams);
this.logger.info("删除过期扩展证书成功, certId: " + expiredCert.CertIdentifier + ", response: " + JSON.stringify(deleteRes));
}
this.logger.info('清理过期扩展证书完成, cloudResourceId: ' + cloudResourceId + ', deletedCount: ' + expiredCerts.length);
this.logger.info("清理过期扩展证书完成, cloudResourceId: " + cloudResourceId + ", deletedCount: " + expiredCerts.length);
} catch (error) {
this.logger.error('清理过期扩展证书失败, cloudResourceId: ' + cloudResourceId + ', error: ' + JSON.stringify(error));
this.logger.error("清理过期扩展证书失败, cloudResourceId: " + cloudResourceId + ", error: " + JSON.stringify(error));
// 清理失败不影响主流程
}
}
async onGetCloudResourceList(data: PageSearch) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getWafClient(access);
const pager = new Pager(data)
const pager = new Pager(data);
const instanceId = await this.getInstanceId(client);
const params: any = {
@@ -286,17 +281,17 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
params.ResourceInstanceId = data.searchKey;
}
this.logger.info('调用DescribeCloudResourceList API', JSON.stringify(params));
const res = await client.request('DescribeCloudResourceList', params);
this.logger.info('DescribeCloudResourceList API返回', JSON.stringify(res));
this.logger.info("调用DescribeCloudResourceList API", JSON.stringify(params));
const res = await client.request("DescribeCloudResourceList", params);
this.logger.info("DescribeCloudResourceList API返回", JSON.stringify(res));
if (!res || !res.CloudResourceList || res.CloudResourceList.length === 0) {
this.logger.warn('没有找到云产品接入的资源');
this.logger.warn("没有找到云产品接入的资源");
return {
list: [],
total: 0,
pageNo: pager.pageNo,
pageSize: pager.pageSize
pageSize: pager.pageSize,
};
}
const total = res.TotalCount || 0;
@@ -315,9 +310,9 @@ export class AliyunDeployCertToWafCloud extends AbstractTaskPlugin {
list,
total: total,
pageNo: pager.pageNo,
pageSize: pager.pageSize
pageSize: pager.pageSize,
};
}
}
new AliyunDeployCertToWafCloud();
new AliyunDeployCertToWafCloud();
@@ -1,18 +1,15 @@
import { AbstractTaskPlugin, IsTaskPlugin, Pager, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine
} from "@certd/plugin-lib";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunClient, AliyunSslClient, CasCertInfo } from "../../../plugin-lib/aliyun/lib/index.js";
@IsTaskPlugin({
name: 'AliyunDeployCertToWaf',
title: '阿里云-部署至阿里云WAF(cname接入)',
icon: 'svg:icon-aliyun',
name: "AliyunDeployCertToWaf",
title: "阿里云-部署至阿里云WAF(cname接入)",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '部署证书到阿里云WAF(cname接入),云资源的请选择另外一个waf插件',
desc: "部署证书到阿里云WAF(cname接入),云资源的请选择另外一个waf插件",
needPlus: false,
default: {
strategy: {
@@ -22,11 +19,11 @@ import { AliyunClient, AliyunSslClient, CasCertInfo } from "../../../plugin-lib/
})
export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
name: "output-selector",
from: [...CertApplyPluginNames, "uploadCertToAliyun"],
},
required: true,
})
@@ -36,14 +33,14 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'WAF接入点',
helper: '不会选就按默认',
value: 'cn-hangzhou',
title: "WAF接入点",
helper: "不会选就按默认",
value: "cn-hangzhou",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'cn-hangzhou', label: '中国大陆-华东1(杭州)' },
{ value: 'ap-southeast-1', label: '新加坡' },
{ value: "cn-hangzhou", label: "中国大陆-华东1(杭州)" },
{ value: "ap-southeast-1", label: "新加坡" },
],
},
required: true,
@@ -51,15 +48,15 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
regionId!: string;
@TaskInput({
title: '证书接入点',
helper: '跟上面保持一致即可',
value: 'cas.aliyuncs.com',
title: "证书接入点",
helper: "跟上面保持一致即可",
value: "cas.aliyuncs.com",
component: {
name: 'a-select',
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: '德国(法兰克福)' },
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" },
],
},
required: true,
@@ -67,11 +64,11 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
casEndpoint!: string;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
@@ -79,26 +76,25 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'CNAME站点',
helper: '请选择要部署证书的CNAME站点',
title: "CNAME站点",
helper: "请选择要部署证书的CNAME站点",
action: AliyunDeployCertToWaf.prototype.onGetCnameList.name,
watches: ['accessId', 'regionId'],
watches: ["accessId", "regionId"],
pager: true,
search: true,
})
)
cnameDomains!: string[];
@TaskInput({
title: 'TLS版本',
value: 'tlsv1.2',
title: "TLS版本",
value: "tlsv1.2",
component: {
name: 'a-select',
name: "a-select",
options: [
{ value: 'tlsv1', label: 'TLSv1' },
{ value: 'tlsv1.1', label: 'TLSv1.1' },
{ value: 'tlsv1.2', label: 'TLSv1.2' },
{ value: "tlsv1", label: "TLSv1" },
{ value: "tlsv1.1", label: "TLSv1.1" },
{ value: "tlsv1.2", label: "TLSv1.2" },
],
},
required: true,
@@ -106,19 +102,17 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
tlsVersion!: string;
@TaskInput({
title: '启用TLSv3',
title: "启用TLSv3",
value: true,
component: {
name: 'a-switch',
vModel: 'checked',
name: "a-switch",
vModel: "checked",
},
required: true,
})
enableTLSv3!: boolean;
async onInstance() { }
async onInstance() {}
async getWafClient(access: AliyunAccess) {
const client = new AliyunClient({ logger: this.logger });
@@ -127,25 +121,25 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
accessKeySecret: access.accessKeySecret,
//https://wafopenapi.cn-hangzhou.aliyuncs.com
endpoint: `https://wafopenapi.${this.regionId}.aliyuncs.com`,
apiVersion: '2021-10-01',
apiVersion: "2021-10-01",
});
return client;
}
async getInstanceId(client: AliyunClient) {
const params = {
RegionId: 'cn-hangzhou',
RegionId: "cn-hangzhou",
};
const res = await client.request('DescribeInstance', params);
this.logger.info('获取实例ID', res.InstanceId);
const res = await client.request("DescribeInstance", params);
this.logger.info("获取实例ID", res.InstanceId);
return res.InstanceId;
}
async execute(): Promise<void> {
this.logger.info('开始部署证书到阿里云');
this.logger.info("开始部署证书到阿里云");
const access = await this.getAccess<AliyunAccess>(this.accessId);
let certId: any = this.cert;
if (typeof this.cert === 'object') {
if (typeof this.cert === "object") {
const sslClient = new AliyunSslClient({
access,
logger: this.logger,
@@ -163,21 +157,21 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
} else if (casCert.certId) {
certId = casCert.certId;
} else {
throw new Error('证书格式错误'+JSON.stringify(this.cert));
throw new Error("证书格式错误" + JSON.stringify(this.cert));
}
}
const client = await this.getWafClient(access);
const instanceId = await this.getInstanceId(client);
for (const siteDomain of this.cnameDomains) {
this.logger.info('开始部署', siteDomain);
this.logger.info("开始部署", siteDomain);
const params = {
RegionId: this.regionId,
InstanceId: instanceId,
Domain: siteDomain,
};
const siteDetail = await client.request('DescribeDomainDetail', params);
this.logger.info('站点详情', JSON.stringify(siteDetail));
const siteDetail = await client.request("DescribeDomainDetail", params);
this.logger.info("站点详情", JSON.stringify(siteDetail));
const listen = siteDetail.Listen;
if (!listen) {
throw new Error(`没有找到${siteDomain}的监听器`);
@@ -190,7 +184,7 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
*/
const redirect = siteDetail.Redirect;
redirect.Backends = redirect.AllBackends;
listen.CertId = certId + '-' + this.regionId;
listen.CertId = certId + "-" + this.regionId;
if (!listen.HttpsPorts || listen.HttpsPorts.length === 0) {
listen.HttpsPorts = [443];
}
@@ -200,23 +194,22 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
Redirect: JSON.stringify(redirect),
Listen: JSON.stringify(listen),
Domain: siteDomain,
TLSVersion: this.tlsVersion || 'tlsv1.2',
TLSVersion: this.tlsVersion || "tlsv1.2",
EnableTLSv3: this.enableTLSv3 ?? true,
};
const res = await client.request('ModifyDomain', updateParams);
this.logger.info('部署成功', JSON.stringify(res));
const res = await client.request("ModifyDomain", updateParams);
this.logger.info("部署成功", JSON.stringify(res));
}
}
async onGetCnameList(data: PageSearch) {
if (!this.accessId) {
throw new Error('请选择Access授权');
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getWafClient(access);
const pager = new Pager(data)
const pager = new Pager(data);
const instanceId = await this.getInstanceId(client);
const params: any = {
@@ -226,12 +219,12 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
PageNumber: pager.pageNo,
};
if (data.searchKey) {
params.Domain = data.searchKey
params.Domain = data.searchKey;
}
const res = await client.request('DescribeDomains', params);
const res = await client.request("DescribeDomains", params);
if (!res?.Domains || res?.Domains.length === 0) {
throw new Error('没有找到CNAME接入的域名站点');
throw new Error("没有找到CNAME接入的域名站点");
}
const total = res.TotalCount;
@@ -251,7 +244,7 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
list,
total: total,
pageNo: pager.pageNo,
pageSize: pager.pageSize
pageSize: pager.pageSize,
};
}
}
@@ -1,2 +1,2 @@
export * from './deploy-to-waf-cname.js';
export * from './deploy-to-waf-cloud.js';
export * from "./deploy-to-waf-cname.js";
export * from "./deploy-to-waf-cloud.js";
@@ -1,18 +1,18 @@
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';
export * from './deploy-to-alb/index.js';
export * from './deploy-to-nlb/index.js';
export * from './deploy-to-slb/index.js';
export * from './deploy-to-fc/index.js';
export * from './deploy-to-esa/index.js';
export * from './deploy-to-ga/index.js';
export * from './deploy-to-vod/index.js';
export * from './deploy-to-live/index.js';
export * from './deploy-to-apigateway/index.js';
export * from './deploy-to-apig/index.js';
export * from './deploy-to-ack/index.js';
export * from './deploy-to-all/index.js';
export * from './delete-expiring-cert/index.js';
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";
export * from "./deploy-to-alb/index.js";
export * from "./deploy-to-nlb/index.js";
export * from "./deploy-to-slb/index.js";
export * from "./deploy-to-fc/index.js";
export * from "./deploy-to-esa/index.js";
export * from "./deploy-to-ga/index.js";
export * from "./deploy-to-vod/index.js";
export * from "./deploy-to-live/index.js";
export * from "./deploy-to-apigateway/index.js";
export * from "./deploy-to-apig/index.js";
export * from "./deploy-to-ack/index.js";
export * from "./deploy-to-all/index.js";
export * from "./delete-expiring-cert/index.js";
@@ -1,7 +1,7 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from "@certd/pipeline";
import { CertApplyPluginNames, CertReader } from "@certd/plugin-cert";
import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js';
import { AliyunSslClient, CasCertId } from '../../../plugin-lib/aliyun/lib/index.js';
import { AliyunAccess } from "../../../plugin-lib/aliyun/access/index.js";
import { AliyunSslClient, CasCertId } from "../../../plugin-lib/aliyun/lib/index.js";
/**
* 华东1(杭州) cn-hangzhou cas.aliyuncs.com cas-vpc.cn-hangzhou.aliyuncs.com
* 马来西亚(吉隆坡) ap-southeast-3 cas.ap-southeast-3.aliyuncs.com cas-vpc.ap-southeast-3.aliyuncs.com
@@ -13,21 +13,21 @@ import { AliyunSslClient, CasCertId } from '../../../plugin-lib/aliyun/lib/index
* 德国(法兰克福) eu-central-1 cas.eu-central-1.aliyuncs.com
*/
const regionDict = [
{ value: 'cn-hangzhou', endpoint: 'cas.aliyuncs.com', label: 'cn-hangzhou-中国大陆' },
{ value: 'ap-southeast-1', endpoint: 'cas.ap-southeast-1.aliyuncs.com', label: 'ap-southeast-1-新加坡(国际版选这个)' },
{ value: 'private-', endpoint: '', disabled:true, label: '以下是私有证书区域' },
{ value: 'eu-central-1', endpoint: 'cas.eu-central-1.aliyuncs.com', label: 'eu-central-1-德国(法兰克福)' },
{ value: 'ap-southeast-3', endpoint: 'cas.ap-southeast-3.aliyuncs.com', label: 'ap-southeast-3-马来西亚(吉隆坡)' },
{ value: 'ap-southeast-5', endpoint: 'cas.ap-southeast-5.aliyuncs.com', label: 'ap-southeast-5-印度尼西亚(雅加达)' },
{ value: 'cn-hongkong', endpoint: 'cas.cn-hongkong.aliyuncs.com', label: 'cn-hongkong-中国香港' },
{ value: "cn-hangzhou", endpoint: "cas.aliyuncs.com", label: "cn-hangzhou-中国大陆" },
{ value: "ap-southeast-1", endpoint: "cas.ap-southeast-1.aliyuncs.com", label: "ap-southeast-1-新加坡(国际版选这个)" },
{ value: "private-", endpoint: "", disabled: true, label: "以下是私有证书区域" },
{ value: "eu-central-1", endpoint: "cas.eu-central-1.aliyuncs.com", label: "eu-central-1-德国(法兰克福)" },
{ value: "ap-southeast-3", endpoint: "cas.ap-southeast-3.aliyuncs.com", label: "ap-southeast-3-马来西亚(吉隆坡)" },
{ value: "ap-southeast-5", endpoint: "cas.ap-southeast-5.aliyuncs.com", label: "ap-southeast-5-印度尼西亚(雅加达)" },
{ value: "cn-hongkong", endpoint: "cas.cn-hongkong.aliyuncs.com", label: "cn-hongkong-中国香港" },
];
@IsTaskPlugin({
name: 'uploadCertToAliyun',
title: '阿里云-上传证书到CAS',
icon: 'svg:icon-aliyun',
name: "uploadCertToAliyun",
title: "阿里云-上传证书到CAS",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: '上传证书到阿里云证书管理服务(CAS),如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出',
desc: "上传证书到阿里云证书管理服务(CAS),如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -36,17 +36,17 @@ const regionDict = [
})
export class UploadCertToAliyun extends AbstractTaskPlugin {
@TaskInput({
title: '证书名称',
helper: '证书上传后将以此参数作为名称前缀',
title: "证书名称",
helper: "证书上传后将以此参数作为名称前缀",
})
name!: string;
@TaskInput({
title: '大区',
value: 'cn-hangzhou',
title: "大区",
value: "cn-hangzhou",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: regionDict,
},
required: true,
@@ -54,10 +54,10 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
regionId!: string;
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
@@ -65,28 +65,28 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
cert!: any;
@TaskInput({
title: 'Access授权',
helper: '阿里云授权AccessKeyId、AccessKeySecret',
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: 'access-selector',
type: 'aliyun',
name: "access-selector",
type: "aliyun",
},
required: true,
})
accessId!: string;
@TaskOutput({
title: '上传成功后的阿里云CertId',
title: "上传成功后的阿里云CertId",
})
aliyunCertId!: CasCertId;
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始上传证书到阿里云证书管理CAS');
this.logger.info("开始上传证书到阿里云证书管理CAS");
const access: AliyunAccess = await this.getAccess(this.accessId);
let endpoint = '';
let endpoint = "";
for (const region of regionDict) {
if (region.value === this.regionId) {
endpoint = region.endpoint;
@@ -98,12 +98,12 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
logger: this.logger,
endpoint,
});
let certName = ""
let certName = "";
const certReader = new CertReader(this.cert);
if (this.name){
certName = this.appendTimeSuffix(this.name)
}else {
certName = this.buildCertName(certReader.getMainDomain())
if (this.name) {
certName = this.appendTimeSuffix(this.name);
} else {
certName = this.buildCertName(certReader.getMainDomain());
}
const certIdRes = await client.uploadCertificate({