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,46 +1,46 @@
import { IsAccess, AccessInput, BaseAccess } from '@certd/pipeline';
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
@IsAccess({
name: 'dnspod',
title: 'dnspod(已废弃)',
desc: '腾讯云的域名解析接口已迁移到dnspod',
deprecated: 'dnspod已废弃,请换成腾讯云',
icon: 'svg:icon-tencentcloud',
name: "dnspod",
title: "dnspod(已废弃)",
desc: "腾讯云的域名解析接口已迁移到dnspod",
deprecated: "dnspod已废弃,请换成腾讯云",
icon: "svg:icon-tencentcloud",
})
export class DnspodAccess extends BaseAccess {
@AccessInput({
title: '端点',
title: "端点",
component: {
placeholder: 'endpoint',
name: 'a-auto-complete',
vModel: 'value',
placeholder: "endpoint",
name: "a-auto-complete",
vModel: "value",
options: [
{ value: 'https://dnsapi.cn', label: '中国站' },
{ value: 'https://api.dnspod.com', label: '国际站' },
{ value: "https://dnsapi.cn", label: "中国站" },
{ value: "https://api.dnspod.com", label: "国际站" },
],
},
rules: [{ required: true, message: '该项必填' }],
rules: [{ required: true, message: "该项必填" }],
})
endpoint = '';
endpoint = "";
@AccessInput({
title: 'ID',
title: "ID",
component: {
placeholder: 'dnspod token 的 id',
placeholder: "dnspod token 的 id",
},
rules: [{ required: true, message: '该项必填' }],
rules: [{ required: true, message: "该项必填" }],
})
id = '';
id = "";
@AccessInput({
title: 'token',
title: "token",
component: {
placeholder: '开放接口token',
placeholder: "开放接口token",
},
encrypt: true,
rules: [{ required: true, message: '该项必填' }],
rules: [{ required: true, message: "该项必填" }],
})
token = '';
token = "";
}
new DnspodAccess();
@@ -1 +1 @@
export * from './dnspod-access.js';
export * from "./dnspod-access.js";
@@ -1,37 +1,37 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import * as _ from 'lodash-es';
import { DnspodAccess } from '../access/index.js';
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import * as _ from "lodash-es";
import { DnspodAccess } from "../access/index.js";
@IsDnsProvider({
name: 'dnspod',
title: 'dnspod(已过时,请尽快换成腾讯云)',
desc: '已废弃,请尽快换成腾讯云类型',
accessType: 'dnspod',
deprecated: 'dnspod已废弃,请换成腾讯云',
icon: 'svg:icon-tencentcloud',
name: "dnspod",
title: "dnspod(已过时,请尽快换成腾讯云)",
desc: "已废弃,请尽快换成腾讯云类型",
accessType: "dnspod",
deprecated: "dnspod已废弃,请换成腾讯云",
icon: "svg:icon-tencentcloud",
})
export class DnspodDnsProvider extends AbstractDnsProvider {
access!: DnspodAccess;
loginToken: any;
endpoint = '';
endpoint = "";
async onInstance() {
this.access = this.ctx.access as DnspodAccess
this.access = this.ctx.access as DnspodAccess;
const access: DnspodAccess = this.access as DnspodAccess;
this.loginToken = access.id + ',' + access.token;
this.endpoint = access.endpoint || 'https://dnsapi.cn';
this.loginToken = access.id + "," + access.token;
this.endpoint = access.endpoint || "https://dnsapi.cn";
}
async doRequest(options: any, successCodes: string[] = []) {
const config: any = {
// @ts-ignore
method: 'post',
method: "post",
formData: {
login_token: this.loginToken,
format: 'json',
lang: 'cn',
error_on_empty: 'no',
format: "json",
lang: "cn",
error_on_empty: "no",
},
timeout: 10000,
};
@@ -40,8 +40,8 @@ export class DnspodDnsProvider extends AbstractDnsProvider {
const ret: any = await this.http.request(config);
if (!ret || !ret.status) {
const code = ret.status.code;
if (code !== '1' || !successCodes.includes(code)) {
throw new Error('请求失败:' + ret.status.message + ',api=' + config.url);
if (code !== "1" || !successCodes.includes(code)) {
throw new Error("请求失败:" + ret.status.message + ",api=" + config.url);
}
}
return ret;
@@ -49,34 +49,34 @@ export class DnspodDnsProvider extends AbstractDnsProvider {
async getDomainList() {
const ret = await this.doRequest({
url: this.access.endpoint + '/Domain.List',
url: this.access.endpoint + "/Domain.List",
});
this.logger.info('dnspod 域名列表:', ret.domains);
this.logger.info("dnspod 域名列表:", ret.domains);
return ret.domains;
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type } = options;
this.logger.info('添加域名解析:', fullRecord, value);
this.logger.info("添加域名解析:", fullRecord, value);
const domainItem = await this.matchDomain(fullRecord);
const domain = domainItem.name;
const rr = fullRecord.replace('.' + domain, '');
const rr = fullRecord.replace("." + domain, "");
const ret = await this.doRequest(
{
url: this.access.endpoint + '/Record.Create',
url: this.access.endpoint + "/Record.Create",
formData: {
domain,
sub_domain: rr,
record_type: type,
record_line: '默认',
record_line: "默认",
value: value,
mx: 1,
},
},
['104']
["104"]
); // 104错误码为记录已存在,无需再次添加
this.logger.info('添加域名解析成功:', fullRecord, value, JSON.stringify(ret.record));
this.logger.info("添加域名解析成功:", fullRecord, value, JSON.stringify(ret.record));
return ret.record;
}
@@ -86,30 +86,30 @@ export class DnspodDnsProvider extends AbstractDnsProvider {
const domain = await this.matchDomain(fullRecord);
const ret = await this.doRequest({
url: this.access.endpoint + '/Record.Remove',
url: this.access.endpoint + "/Record.Remove",
formData: {
domain,
record_id: record.id,
},
});
this.logger.info('删除域名解析成功:', fullRecord, value);
this.logger.info("删除域名解析成功:", fullRecord, value);
return ret.RecordId;
}
async matchDomain(dnsRecord: any) {
const list = await this.getDomainList();
if (list == null) {
throw new Error('域名列表不能为空');
throw new Error("域名列表不能为空");
}
let domain = null;
for (const item of list) {
if (_.endsWith(dnsRecord, '.' + item.name)) {
if (_.endsWith(dnsRecord, "." + item.name)) {
domain = item;
break;
}
}
if (!domain) {
throw new Error('找不到域名,请检查域名是否正确:' + dnsRecord);
throw new Error("找不到域名,请检查域名是否正确:" + dnsRecord);
}
return domain;
}
@@ -1,3 +1,3 @@
import './dnspod-dns-provider.js';
import './tencent-dns-provider.js';
import './teo-dns-provider.js';
import "./dnspod-dns-provider.js";
import "./tencent-dns-provider.js";
import "./teo-dns-provider.js";
@@ -1,33 +1,33 @@
import { AbstractDnsProvider, CreateRecordOptions, DomainRecord, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import { TencentAccess } from '../../plugin-lib/tencent/index.js';
import { Pager, PageRes, PageSearch } from '@certd/pipeline';
import { AbstractDnsProvider, CreateRecordOptions, DomainRecord, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { TencentAccess } from "../../plugin-lib/tencent/index.js";
import { Pager, PageRes, PageSearch } from "@certd/pipeline";
@IsDnsProvider({
name: 'tencent',
title: '腾讯云',
desc: '腾讯云域名DNS解析提供者',
accessType: 'tencent',
icon: 'svg:icon-tencentcloud',
name: "tencent",
title: "腾讯云",
desc: "腾讯云域名DNS解析提供者",
accessType: "tencent",
icon: "svg:icon-tencentcloud",
})
export class TencentDnsProvider extends AbstractDnsProvider {
access!: TencentAccess;
client!: any;
endpoint = 'dnspod.tencentcloudapi.com';
endpoint = "dnspod.tencentcloudapi.com";
async onInstance() {
this.access = this.ctx.access as TencentAccess
this.access = this.ctx.access as TencentAccess;
const clientConfig = {
credential: this.access,
region: '',
region: "",
profile: {
httpProfile: {
endpoint: this.endpoint,
},
},
};
const dnspodSdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/dnspod/v20210323/index.js');
const dnspodSdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/dnspod/v20210323/index.js");
const DnspodClient = dnspodSdk.v20210323.Client;
// 实例化要请求产品的client对象,clientProfile是可选的
this.client = new DnspodClient(clientConfig);
@@ -35,20 +35,20 @@ export class TencentDnsProvider extends AbstractDnsProvider {
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type, domain } = options;
this.logger.info('添加域名解析:', fullRecord, value);
const rr = fullRecord.replace('.' + domain, '');
this.logger.info("添加域名解析:", fullRecord, value);
const rr = fullRecord.replace("." + domain, "");
const params = {
Domain: domain,
RecordType: type,
RecordLine: '默认',
RecordLine: "默认",
Value: value,
SubDomain: rr,
};
try {
const ret = await this.client.CreateRecord(params);
this.logger.info('添加域名解析成功:', fullRecord, value, JSON.stringify(ret));
this.logger.info("添加域名解析成功:", fullRecord, value, JSON.stringify(ret));
/*
{
"RecordId": 162,
@@ -57,8 +57,8 @@ export class TencentDnsProvider extends AbstractDnsProvider {
*/
return ret;
} catch (e: any) {
if (e?.code === 'InvalidParameter.DomainRecordExist') {
this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value);
if (e?.code === "InvalidParameter.DomainRecordExist") {
this.logger.info("域名解析已存在,无需重复添加:", fullRecord, value);
return await this.findRecord(options);
}
throw e;
@@ -74,7 +74,7 @@ export class TencentDnsProvider extends AbstractDnsProvider {
};
const ret = await this.client.DescribeRecordFilterList(params);
if (ret.RecordList && ret.RecordList.length > 0) {
this.logger.info('已存在解析记录:', ret.RecordList);
this.logger.info("已存在解析记录:", ret.RecordList);
return ret.RecordList[0];
}
return {};
@@ -84,22 +84,21 @@ export class TencentDnsProvider extends AbstractDnsProvider {
const { fullRecord, value, domain } = options.recordReq;
const record = options.recordRes;
if (!record) {
this.logger.info('解析记录recordId为空,不执行删除', fullRecord, value);
this.logger.info("解析记录recordId为空,不执行删除", fullRecord, value);
}
const params = {
Domain: domain,
RecordId: record.RecordId,
};
const ret = await this.client.DeleteRecord(params);
this.logger.info('删除域名解析成功:', fullRecord, value);
this.logger.info("删除域名解析成功:", fullRecord, value);
return ret;
}
async getDomainListPage(req: PageSearch): Promise<PageRes<DomainRecord>> {
const pager = new Pager(req);
const params:any = {
const params: any = {
Offset: pager.getOffset(),
Limit: pager.pageSize,
};
@@ -108,12 +107,12 @@ export class TencentDnsProvider extends AbstractDnsProvider {
}
const ret = await this.client.DescribeDomainList(params);
let list = ret.DomainList || [];
list = list.map((item) => ({
list = list.map(item => ({
id: item.DomainId,
domain: item.Name,
}));
const total = ret.DomainCountInfo?.AllTotal || list.length
return {total,list,};
const total = ret.DomainCountInfo?.AllTotal || list.length;
return { total, list };
}
}
new TencentDnsProvider();
@@ -1,145 +1,131 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import { TencentAccess } from '../../plugin-lib/tencent/access.js';
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { TencentAccess } from "../../plugin-lib/tencent/access.js";
@IsDnsProvider({
name: 'tencent-eo',
title: '腾讯云EO DNS',
desc: '腾讯云EO DNS解析提供者',
accessType: 'tencent',
icon: 'svg:icon-tencentcloud',
name: "tencent-eo",
title: "腾讯云EO DNS",
desc: "腾讯云EO DNS解析提供者",
accessType: "tencent",
icon: "svg:icon-tencentcloud",
})
export class TencentEoDnsProvider extends AbstractDnsProvider {
access!: TencentAccess;
access!: TencentAccess;
client!: any;
client!: any;
async onInstance() {
this.access = this.ctx.access as TencentAccess;
const clientConfig = {
credential: this.access,
region: "",
profile: {
httpProfile: {
endpoint: this.access.buildEndpoint("teo.tencentcloudapi.com"),
},
},
};
const teosdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js");
const TeoClient = teosdk.v20220901.Client;
// 实例化要请求产品的client对象,clientProfile是可选的
this.client = new TeoClient(clientConfig);
}
async onInstance() {
this.access = this.ctx.access as TencentAccess
const clientConfig = {
credential: this.access,
region: '',
profile: {
httpProfile: {
endpoint: this.access.buildEndpoint("teo.tencentcloudapi.com"),
},
},
};
const teosdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js');
const TeoClient = teosdk.v20220901.Client;
// 实例化要请求产品的client对象,clientProfile是可选的
this.client = new TeoClient(clientConfig);
async getZoneId(domain: string) {
const params = {
Filters: [
{
Name: "zone-name",
Values: [domain],
},
],
};
const res = await this.client.DescribeZones(params);
if (res.Zones && res.Zones.length > 0) {
return res.Zones[0].ZoneId;
}
throw new Error("未找到对应的ZoneId");
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type, domain } = options;
this.logger.info("添加域名解析:", fullRecord, value);
async getZoneId(domain: string) {
const zoneId = await this.getZoneId(domain);
const params = {
ZoneId: zoneId,
Name: fullRecord,
Type: type,
Content: value,
TTL: 60,
};
const params = {
"Filters": [
{
"Name": "zone-name",
"Values": [
domain
]
}
]
};
const res = await this.client.DescribeZones(params);
if (res.Zones && res.Zones.length > 0) {
return res.Zones[0].ZoneId;
}
throw new Error('未找到对应的ZoneId');
}
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type, domain } = options;
this.logger.info('添加域名解析:', fullRecord, value);
const zoneId = await this.getZoneId(domain);
const params = {
"ZoneId": zoneId,
"Name": fullRecord,
"Type": type,
"Content": value,
"TTL": 60,
};
try {
const ret = await this.client.CreateDnsRecord(params);
this.logger.info('添加域名解析成功:', fullRecord, value, JSON.stringify(ret));
/*
try {
const ret = await this.client.CreateDnsRecord(params);
this.logger.info("添加域名解析成功:", fullRecord, value, JSON.stringify(ret));
/*
{
"RecordId": 162,
"RequestId": "ab4f1426-ea15-42ea-8183-dc1b44151166"
}
*/
return {
RecordId: ret.RecordId,
ZoneId: zoneId,
};
} catch (e: any) {
if (e?.code === 'ResourceInUse.DuplicateName') {
this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value);
return await this.findRecord({
...options,
zoneId,
});
}
throw e;
}
return {
RecordId: ret.RecordId,
ZoneId: zoneId,
};
} catch (e: any) {
if (e?.code === "ResourceInUse.DuplicateName") {
this.logger.info("域名解析已存在,无需重复添加:", fullRecord, value);
return await this.findRecord({
...options,
zoneId,
});
}
throw e;
}
}
async findRecord(options: CreateRecordOptions & { zoneId: string }): Promise<any> {
const { zoneId } = options;
const params = {
ZoneId: zoneId,
Filters: [
{
Name: "name",
Values: [options.fullRecord],
},
{
Name: "content",
Values: [options.value],
},
{
Name: "type",
Values: [options.type],
},
],
};
const ret = await this.client.DescribeRecordFilterList(params);
if (ret.DnsRecords && ret.DnsRecords.length > 0) {
this.logger.info("已存在解析记录:", ret.DnsRecords);
return ret.DnsRecords[0];
}
return {};
}
async removeRecord(options: RemoveRecordOptions<any>) {
const { fullRecord, value } = options.recordReq;
const record = options.recordRes;
if (!record) {
this.logger.info("解析记录recordId为空,不执行删除", fullRecord, value);
}
async findRecord(options: CreateRecordOptions & { zoneId: string }): Promise<any> {
const params = {
ZoneId: record.ZoneId,
RecordIds: [record.RecordId],
};
const { zoneId } = options;
const params = {
"ZoneId": zoneId,
"Filters": [
{
"Name": "name",
"Values": [
options.fullRecord
]
},
{
"Name": "content",
"Values": [
options.value
]
},
{
"Name": "type",
"Values": [
options.type
]
}
]
};
const ret = await this.client.DescribeRecordFilterList(params);
if (ret.DnsRecords && ret.DnsRecords.length > 0) {
this.logger.info('已存在解析记录:', ret.DnsRecords);
return ret.DnsRecords[0];
}
return {};
}
async removeRecord(options: RemoveRecordOptions<any>) {
const { fullRecord, value } = options.recordReq;
const record = options.recordRes;
if (!record) {
this.logger.info('解析记录recordId为空,不执行删除', fullRecord, value);
}
const params = {
"ZoneId": record.ZoneId,
"RecordIds": [
record.RecordId
]
};
const ret = await this.client.DeleteDnsRecords(params);
this.logger.info('删除域名解析成功:', fullRecord, value);
return ret;
}
const ret = await this.client.DeleteDnsRecords(params);
this.logger.info("删除域名解析成功:", fullRecord, value);
return ret;
}
}
new TencentEoDnsProvider();
@@ -1,3 +1,3 @@
export * from './access/index.js';
export * from './plugin/index.js';
export * from './dns-provider/index.js';
export * from "./access/index.js";
export * from "./plugin/index.js";
export * from "./dns-provider/index.js";
@@ -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 { remove } from 'lodash-es';
import { TencentAccess, TencentSslClient } from '../../../plugin-lib/tencent/index.js';
import dayjs from "dayjs";
import { remove } from "lodash-es";
import { TencentAccess, TencentSslClient } from "../../../plugin-lib/tencent/index.js";
@IsTaskPlugin({
name: 'TencentDeleteExpiringCert',
title: '腾讯云-删除即将过期证书',
icon: 'svg:icon-tencentcloud',
name: "TencentDeleteExpiringCert",
title: "腾讯云-删除即将过期证书",
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '仅删除未使用的证书',
desc: "仅删除未使用的证书",
default: {
strategy: {
runStrategy: RunStrategy.AlwaysRun,
@@ -19,58 +19,57 @@ import { TencentAccess, TencentSslClient } from '../../../plugin-lib/tencent/ind
})
export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '关键字筛选',
helper: '仅匹配ID、备注名称、域名包含关键字的证书,可以不填',
title: "关键字筛选",
helper: "仅匹配ID、备注名称、域名包含关键字的证书,可以不填",
required: false,
component: {
name: 'a-input',
name: "a-input",
},
})
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:
'仅删除有效期小于此天数的证书',
title: "即将过期天数",
helper: "仅删除有效期小于此天数的证书",
value: 18,
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,
})
@@ -88,18 +87,18 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
const params = {
Limit: this.maxCount ?? 100,
SearchKey: this.searchKey,
ExpirationSort: 'ASC',
FilterSource: 'upload',
ExpirationSort: "ASC",
FilterSource: "upload",
// FilterExpiring: 1,
};
const res = await sslClient.DescribeCertificates(params);
let certificates = res?.Certificates;
if (!certificates && certificates.length === 0) {
this.logger.info('没有找到证书');
this.logger.info("没有找到证书");
return;
}
const lastDay = dayjs().add(this.expiringDays, 'day');
const lastDay = dayjs().add(this.expiringDays, "day");
certificates = certificates.filter((item: any) => {
const endTime = item.CertEndTime;
return dayjs(endTime).isBefore(lastDay);
@@ -109,19 +108,19 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
}
this.logger.info(`即将过期的证书数量:${certificates.length}`);
if (certificates.length === 0) {
this.logger.info('没有即将过期的证书, 无需删除');
this.logger.info("没有即将过期的证书, 无需删除");
return;
}
const certIds = certificates.map((cert: any) => cert.CertificateId);
const deleteRes = await sslClient.doRequest('DeleteCertificates', {
const deleteRes = await sslClient.doRequest("DeleteCertificates", {
CertificateIds: certIds,
IsSync: true,
});
this.logger.info('删除任务已提交: ', JSON.stringify(deleteRes));
this.logger.info("删除任务已提交: ", JSON.stringify(deleteRes));
const ids = deleteRes?.CertTaskIds;
if (!ids && !ids.length) {
this.logger.error('没有找到任务ID');
this.logger.error("没有找到任务ID");
return;
}
const taskIds = ids.map((id: any) => id.TaskId);
@@ -139,12 +138,12 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
while (Date.now() < startTime + this.checkTimeout * 60 * 1000) {
this.checkSignal();
const taskResultRes = await sslClient.doRequest('DescribeDeleteCertificatesTaskResult', {
const taskResultRes = await sslClient.doRequest("DescribeDeleteCertificatesTaskResult", {
TaskIds: taskIds,
});
const result = taskResultRes.DeleteTaskResult;
if (!result || result.length === 0) {
this.logger.info('暂未获取到有效的任务结果');
this.logger.info("暂未获取到有效的任务结果");
continue;
}
for (const item of result) {
@@ -158,23 +157,23 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 进行中`);
} else if (status === 1) {
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 成功`);
results[item.TaskId] = '成功';
results[item.TaskId] = "成功";
statusCount.success++;
} else if (status === 2) {
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 失败`);
results[item.TaskId] = '失败';
results[item.TaskId] = "失败";
statusCount.failed++;
} else if (status === 3) {
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 未授权服务角色导致任务失败`);
results[item.TaskId] = '未授权服务角色导致任务失败';
results[item.TaskId] = "未授权服务角色导致任务失败";
statusCount.unauthorized++;
} else if (status === 4) {
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 有未解绑的云资源导致任务失败`);
results[item.TaskId] = '有未解绑的云资源导致任务失败';
results[item.TaskId] = "有未解绑的云资源导致任务失败";
statusCount.unbind++;
} else if (status === 5) {
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 查询关联云资源超时导致任务失败`);
results[item.TaskId] = '查询关联云资源超时导致任务失败';
results[item.TaskId] = "查询关联云资源超时导致任务失败";
statusCount.timeout++;
} else {
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 未知状态:${status}`);
@@ -186,17 +185,17 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
`任务总数:${total}, 进行中:${taskIds.length} 成功:${statusCount.success}, 未授权服务角色导致失败:${statusCount.unauthorized}, 未解绑关联资源失败:${statusCount.unbind}, 查询关联资源超时:${statusCount.timeout},未知原因失败:${statusCount.failed}`
);
if (taskIds.length === 0) {
this.logger.info('任务已全部完成');
this.logger.info("任务已全部完成");
if (statusCount.unauthorized > 0) {
throw new Error('有未授权服务角色导致任务失败,需给Access授权服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate');
throw new Error("有未授权服务角色导致任务失败,需给Access授权服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate");
}
return;
}
await this.ctx.utils.sleep(10000);
}
this.logger.error('检查任务结果超时', JSON.stringify(results));
this.logger.error("检查任务结果超时", JSON.stringify(results));
}
}
@@ -1,14 +1,14 @@
import {AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { TencentSslClient } from '../../../plugin-lib/tencent/index.js';
import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
@IsTaskPlugin({
name: 'DeployCertToTencentAll',
title: '腾讯云-部署证书到任意云资源',
name: "DeployCertToTencentAll",
title: "腾讯云-部署证书到任意云资源",
needPlus: false,
icon: 'svg:icon-tencentcloud',
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '支持负载均衡、CDN、DDoS、直播、点播、Web应用防火墙、API网关、TEO、容器服务、对象存储、轻应用服务器、云原生微服务、云开发',
desc: "支持负载均衡、CDN、DDoS、直播、点播、Web应用防火墙、API网关、TEO、容器服务、对象存储、轻应用服务器、云原生微服务、云开发",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -20,35 +20,32 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
* AccessProvider的key,或者一个包含access的具体的对象
*/
@TaskInput({
title: 'Access授权',
helper: 'access授权',
title: "Access授权",
helper: "access授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书',
title: "证书",
helper: '请选择"证书申请任务"或“上传证书到腾讯云”前置任务的输出',
component: {
name: 'output-selector',
from: [...CertApplyPluginNames,'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
tencentCertId!: string | CertInfo;
@TaskInput({
title: '资源类型',
title: "资源类型",
component: {
name: 'a-select',
vModel: 'value',
name: "a-select",
vModel: "value",
allowClear: true,
//- clb
// - cdn
@@ -64,47 +61,46 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
// - tse
// - tcb
options: [
{ value: 'clb',label: '负载均衡'},
{ value: 'cdn',label: 'CDN'},
{ value: 'ddos',label: 'DDoS'},
{ value: 'live',label: '直播'},
{ value: 'vod',label: '点播'},
{ value: 'waf',label: 'Web应用防火墙'},
{ value: 'apigateway',label: 'API网关'},
{ value: 'teo',label: 'TEO'},
{ value: 'tke',label: '容器服务'},
{ value: 'cos',label: '对象存储'},
{ value: 'lighthouse',label: '轻应用服务器'},
{ value: 'tse',label: '云原生微服务'},
{ value: 'tcb',label: '云开发'},
]
{ value: "clb", label: "负载均衡" },
{ value: "cdn", label: "CDN" },
{ value: "ddos", label: "DDoS" },
{ value: "live", label: "直播" },
{ value: "vod", label: "点播" },
{ value: "waf", label: "Web应用防火墙" },
{ value: "apigateway", label: "API网关" },
{ value: "teo", label: "TEO" },
{ value: "tke", label: "容器服务" },
{ value: "cos", label: "对象存储" },
{ value: "lighthouse", label: "轻应用服务器" },
{ value: "tse", label: "云原生微服务" },
{ value: "tcb", label: "云开发" },
],
},
helper: '',
helper: "",
required: true,
})
resourceType!: string;
@TaskInput({
title: 'Region',
title: "Region",
component: {
name: 'a-input',
vModel: 'value',
name: "a-input",
vModel: "value",
allowClear: true,
},
helper: '当云资源类型传入clb、waf、apigateway、cos、lighthouse、tke、tse、tcb 时,公共参数Region必传。[参考文档](https://cloud.tencent.com/document/product/400/91667)',
helper: "当云资源类型传入clb、waf、apigateway、cos、lighthouse、tke、tse、tcb 时,公共参数Region必传。[参考文档](https://cloud.tencent.com/document/product/400/91667)",
})
region!: string;
@TaskInput({
title: '云资源实例Id列表',
title: "云资源实例Id列表",
component: {
name: 'a-select',
vModel: 'value',
name: "a-select",
vModel: "value",
open: false,
mode: 'tags',
mode: "tags",
},
helper: '[参考文档](https://cloud.tencent.com/document/product/400/91667)',
helper: "[参考文档](https://cloud.tencent.com/document/product/400/91667)",
})
instanceIdList!: string[];
@@ -112,7 +108,7 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
async execute(): Promise<void> {
const access = await this.getAccess(this.accessId);
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js");
const Client = sdk.v20191205.Client;
const client = new Client({
credential: {
@@ -127,31 +123,31 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
},
});
let certId:string = null
if (typeof this.tencentCertId === 'string') {
let certId: string = null;
if (typeof this.tencentCertId === "string") {
certId = this.tencentCertId as string;
} else if (this.tencentCertId && typeof this.tencentCertId === 'object') {
} else if (this.tencentCertId && typeof this.tencentCertId === "object") {
certId = await this.uploadToTencent(access, this.tencentCertId as CertInfo);
} else {
throw new Error('无效的证书输入类型');
throw new Error("无效的证书输入类型");
}
const params = {
CertificateId: certId,
ResourceType: this.resourceType,
InstanceIdList: this.instanceIdList,
IsCache:0,
IsCache: 0,
};
const res = await client.DeployCertificateInstance(params);
this.checkRet(res);
this.logger.info('部署成功,等待5s:',JSON.stringify(res));
this.logger.info("部署成功,等待5s:", JSON.stringify(res));
await this.ctx.utils.sleep(5000);
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
@@ -161,8 +157,8 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
logger: this.logger,
});
return await sslClient.uploadToTencent({
certName: this.appendTimeSuffix('certd'),
return await sslClient.uploadToTencent({
certName: this.appendTimeSuffix("certd"),
cert: cert,
});
}
@@ -1,14 +1,14 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo ,CertReader} from '@certd/plugin-cert';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertInfo, CertReader } from "@certd/plugin-cert";
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { TencentAccess, TencentSslClient } from '../../../plugin-lib/tencent/index.js';
import { CertApplyPluginNames} from '@certd/plugin-cert';
import { TencentAccess, TencentSslClient } from "../../../plugin-lib/tencent/index.js";
import { CertApplyPluginNames } from "@certd/plugin-cert";
@IsTaskPlugin({
name: 'TencentDeployCertToCDNv2',
title: '腾讯云-部署到CDN-v2',
icon: 'svg:icon-tencentcloud',
name: "TencentDeployCertToCDNv2",
title: "腾讯云-部署到CDN-v2",
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '推荐使用,支持CDN域名以及COS加速域名',
desc: "推荐使用,支持CDN域名以及COS加速域名",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -16,13 +16,12 @@ import { CertApplyPluginNames} from '@certd/plugin-cert';
},
})
export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
title: "域名证书",
helper: "请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
@@ -32,31 +31,28 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
certDomains!: string[];
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: 'CDN域名',
helper: '请选择域名或输入域名',
typeName: 'TencentDeployCertToCDNv2',
title: "CDN域名",
helper: "请选择域名或输入域名",
typeName: "TencentDeployCertToCDNv2",
action: TencentDeployCertToCDNv2.prototype.onGetDomainList.name,
})
)
domains!: string | string[];
async onInstance() {}
async execute(): Promise<void> {
const access = await this.getAccess<TencentAccess>(this.accessId);
const sslClient = new TencentSslClient({
@@ -65,7 +61,7 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
});
let tencentCertId = this.cert as string;
if (typeof this.cert !== 'string') {
if (typeof this.cert !== "string") {
const certReader = new CertReader(this.cert);
tencentCertId = await sslClient.uploadToTencent({
certName: certReader.buildCertName(),
@@ -75,25 +71,25 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
const res = await sslClient.deployCertificateInstance({
CertificateId: tencentCertId,
ResourceType: 'cdn',
ResourceType: "cdn",
Status: 1,
InstanceIdList: this.domains,
});
await this.ctx.utils.sleep(3000)
await this.ctx.utils.sleep(3000);
this.logger.info('部署成功', res);
this.logger.info("部署成功", res);
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
async getCdnClient() {
const accessProvider = await this.getAccess<TencentAccess>(this.accessId);
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/index.js");
const CdnClient = sdk.v20180606.Client;
const clientConfig = {
@@ -101,7 +97,7 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: '',
region: "",
profile: {
httpProfile: {
endpoint: `cdn.${accessProvider.intlDomain()}tencentcloudapi.com`,
@@ -122,9 +118,9 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
return {
label: item.Domain,
value: item.Domain,
domain: item.Domain
domain: item.Domain,
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
}
}
@@ -1,13 +1,13 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo } from '@certd/plugin-cert';
import { TencentAccess } from '../../../plugin-lib/tencent/index.js';
import { CertApplyPluginNames} from '@certd/plugin-cert';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertInfo } from "@certd/plugin-cert";
import { TencentAccess } from "../../../plugin-lib/tencent/index.js";
import { CertApplyPluginNames } from "@certd/plugin-cert";
@IsTaskPlugin({
name: 'DeployCertToTencentCDN',
title: '腾讯云-部署到CDN(废弃)',
icon: 'svg:icon-tencentcloud',
name: "DeployCertToTencentCDN",
title: "腾讯云-部署到CDN(废弃)",
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '已废弃,请使用v2版',
desc: "已废弃,请使用v2版",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -16,10 +16,10 @@ import { CertApplyPluginNames} from '@certd/plugin-cert';
})
export class DeployToCdnPlugin extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
@@ -27,25 +27,25 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
cert!: CertInfo;
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '证书名称',
helper: '证书上传后将以此参数作为名称前缀',
title: "证书名称",
helper: "证书上传后将以此参数作为名称前缀",
})
certName!: string;
@TaskInput({
title: 'cdn加速域名',
rules: [{ required: true, message: '该项必填' }],
title: "cdn加速域名",
rules: [{ required: true, message: "该项必填" }],
})
domainName!: string;
@@ -63,7 +63,7 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
Client: any;
async onInstance() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/index.js");
this.Client = sdk.v20180606.Client;
}
@@ -77,7 +77,7 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: '',
region: "",
profile: {
httpProfile: {
endpoint: `cdn.${accessProvider.intlDomain()}tencentcloudapi.com`,
@@ -96,7 +96,7 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
buildParams() {
return {
Domain: this.domainName,
Route: 'Https.CertInfo',
Route: "Https.CertInfo",
Value: JSON.stringify({
update: {
Certificate: this.cert.crt,
@@ -110,13 +110,13 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
const client = await this.getClient();
const ret = await client.ModifyDomainConfig(params);
this.checkRet(ret);
this.logger.info('设置腾讯云CDN证书成功:', ret.RequestId);
this.logger.info("设置腾讯云CDN证书成功:", ret.RequestId);
return ret.RequestId;
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
}
@@ -1,13 +1,13 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import dayjs from 'dayjs';
import { TencentAccess } from '../../../plugin-lib/tencent/index.js';
import { CertApplyPluginNames, CertInfo } from '@certd/plugin-cert';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import dayjs from "dayjs";
import { TencentAccess } from "../../../plugin-lib/tencent/index.js";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
@IsTaskPlugin({
name: 'DeployCertToTencentCLB',
title: '腾讯云-部署到CLB',
icon: 'svg:icon-tencentcloud',
name: "DeployCertToTencentCLB",
title: "腾讯云-部署到CLB",
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '暂时只支持单向认证证书,暂时只支持通用负载均衡',
desc: "暂时只支持单向认证证书,暂时只支持通用负载均衡",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -15,104 +15,98 @@ import { CertApplyPluginNames, CertInfo } from '@certd/plugin-cert';
},
})
export class DeployCertToTencentCLB extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
cert!: string | CertInfo;
@TaskInput({
title: 'Access提供者',
helper: 'access授权',
title: "Access提供者",
helper: "access授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '大区',
title: "大区",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: [
{ value: 'ap-guangzhou' },
{ value: 'ap-beijing' },
{ value: 'ap-chengdu' },
{ value: 'ap-chongqing' },
{ value: 'ap-hongkong' },
{ value: 'ap-jakarta' },
{ value: 'ap-mumbai' },
{ value: 'ap-nanjing' },
{ value: 'ap-seoul' },
{ value: 'ap-shanghai' },
{ value: 'ap-shanghai-fsi' },
{ value: 'ap-shenzhen-fsi' },
{ value: 'ap-singapore' },
{ value: 'ap-tokyo' },
{ value: 'eu-frankfurt' },
{ value: 'na-ashburn' },
{ value: 'na-siliconvalley' },
{ value: 'na-toronto' },
{ value: 'sa-saopaulo' },
{ value: 'ap-taipei' },
{ value: "ap-guangzhou" },
{ value: "ap-beijing" },
{ value: "ap-chengdu" },
{ value: "ap-chongqing" },
{ value: "ap-hongkong" },
{ value: "ap-jakarta" },
{ value: "ap-mumbai" },
{ value: "ap-nanjing" },
{ value: "ap-seoul" },
{ value: "ap-shanghai" },
{ value: "ap-shanghai-fsi" },
{ value: "ap-shenzhen-fsi" },
{ value: "ap-singapore" },
{ value: "ap-tokyo" },
{ value: "eu-frankfurt" },
{ value: "na-ashburn" },
{ value: "na-siliconvalley" },
{ value: "na-toronto" },
{ value: "sa-saopaulo" },
{ value: "ap-taipei" },
],
helper: '如果列表中没有,您可以手动输入',
helper: "如果列表中没有,您可以手动输入",
},
required: true,
})
region!: string;
@TaskInput({
title: '负载均衡ID',
title: "负载均衡ID",
required: true,
})
loadBalancerId!: string;
@TaskInput({
title: '监听器ID',
title: "监听器ID",
required: true,
})
listenerId!: string;
@TaskInput({
title: '域名',
title: "域名",
required: false,
component: {
name: 'a-select',
vModel: 'value',
name: "a-select",
vModel: "value",
open: false,
mode: 'tags',
mode: "tags",
},
helper: '如果开启了sni,则此项必须填写,未开启,则不要填写',
helper: "如果开启了sni,则此项必须填写,未开启,则不要填写",
})
domain!: string | string[];
@TaskInput({
title: '证书名称前缀',
title: "证书名称前缀",
})
certName!: string;
client: any;
async onInstance() {
this.client = await this.getClient();
}
async getClient() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/clb/v20180317/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/clb/v20180317/index.js");
const ClbClient = sdk.v20180317.Client;
const accessProvider = (await this.getAccess(this.accessId)) as TencentAccess;
@@ -204,7 +198,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
const params = this.buildProps();
const ret = await client.ModifyListener(params);
this.checkRet(ret);
this.logger.info('设置腾讯云CLB证书成功:', ret.RequestId, '->loadBalancerId:', this.loadBalancerId, 'listenerId', this.listenerId);
this.logger.info("设置腾讯云CLB证书成功:", ret.RequestId, "->loadBalancerId:", this.loadBalancerId, "listenerId", this.listenerId);
return ret;
}
@@ -214,9 +208,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
params.Domain = domain;
const ret = await client.ModifyDomainAttributes(params);
this.checkRet(ret);
this.logger.info(
`[${domain}] 设置腾讯云CLB证书(sni)任务已提交:taskId${ret.RequestId}loadBalancerId:${this.loadBalancerId}listenerId:${this.listenerId}`
);
this.logger.info(`[${domain}] 设置腾讯云CLB证书(sni)任务已提交:taskId${ret.RequestId}loadBalancerId:${this.loadBalancerId}listenerId:${this.listenerId}`);
const requestId = ret.RequestId;
while (true) {
@@ -236,17 +228,17 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
}
appendTimeSuffix(name: string) {
if (name == null) {
name = 'certd';
name = "certd";
}
return name + '-' + dayjs().format('YYYYMMDD-HHmmss');
return name + "-" + dayjs().format("YYYYMMDD-HHmmss");
}
buildProps() {
const certId = this.cert as string;
const certInfo = this.cert as CertInfo;
if (typeof this.cert === 'string') {
if (typeof this.cert === "string") {
return {
Certificate: {
SSLMode: 'UNIDIRECTIONAL', // 单向认证
SSLMode: "UNIDIRECTIONAL", // 单向认证
CertId: certId,
},
LoadBalancerId: this.loadBalancerId,
@@ -255,7 +247,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
}
return {
Certificate: {
SSLMode: 'UNIDIRECTIONAL', // 单向认证
SSLMode: "UNIDIRECTIONAL", // 单向认证
CertName: this.appendTimeSuffix(this.certName || "certd"),
CertKey: certInfo.key,
CertContent: certInfo.crt,
@@ -268,7 +260,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
async getCLBList(client: any) {
const params = {
Limit: 100, // 最大暂时只支持100个,暂时没做翻页
OrderBy: 'CreateTime',
OrderBy: "CreateTime",
OrderType: 0,
// ...this.DescribeLoadBalancers,
};
@@ -281,7 +273,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
// HTTPS
const params = {
LoadBalancerId: balancerId,
Protocol: 'HTTPS',
Protocol: "HTTPS",
ListenerIds: listenerIds,
};
const ret = await client.DescribeListeners(params);
@@ -291,7 +283,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
}
@@ -1,15 +1,15 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo } from '@certd/plugin-cert';
import { createRemoteSelectInputDefine } from '@certd/plugin-lib';
import { TencentSslClient } from '../../../plugin-lib/tencent/index.js';
import { CertApplyPluginNames} from '@certd/plugin-cert';
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertInfo } from "@certd/plugin-cert";
import { createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
import { CertApplyPluginNames } from "@certd/plugin-cert";
@IsTaskPlugin({
name: 'DeployCertToTencentCosPlugin',
title: '腾讯云-部署证书到COS',
name: "DeployCertToTencentCosPlugin",
title: "腾讯云-部署证书到COS",
needPlus: false,
icon: 'svg:icon-tencentcloud',
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '部署到腾讯云COS源站域名证书,注意是源站域名,加速域名请使用腾讯云CDN v2插件【注意:很不稳定,需要重试很多次偶尔才能成功一次】',
desc: "部署到腾讯云COS源站域名证书,注意是源站域名,加速域名请使用腾讯云CDN v2插件【注意:很不稳定,需要重试很多次偶尔才能成功一次】",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -21,52 +21,52 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
* AccessProvider的id
*/
@TaskInput({
title: 'Access授权',
helper: 'access授权',
title: "Access授权",
helper: "access授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '存储桶名称',
helper: '请输入存储桶名称',
title: "存储桶名称",
helper: "请输入存储桶名称",
})
bucket!: string;
@TaskInput({
title: '所在地域',
helper: '存储桶所在地域',
title: "所在地域",
helper: "存储桶所在地域",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: [
{ value: '', label: '--------中国大陆地区-------', disabled: true },
{ value: 'ap-beijing-1', label: '北京1区' },
{ value: 'ap-beijing', label: '北京' },
{ value: 'ap-nanjing', label: '南京' },
{ value: 'ap-shanghai', label: '上海' },
{ value: 'ap-guangzhou', label: '广州' },
{ value: 'ap-chengdu', label: '成都' },
{ value: 'ap-chongqing', label: '重庆' },
{ value: 'ap-shenzhen-fsi', label: '深圳金融' },
{ value: 'ap-shanghai-fsi', label: '上海金融' },
{ value: 'ap-beijing-fsi', label: '北京金融' },
{ value: '', label: '--------中国香港及境外-------', disabled: true },
{ value: 'ap-hongkong', label: '中国香港' },
{ value: 'ap-singapore', label: '新加坡' },
{ value: 'ap-mumbai', label: '孟买' },
{ value: 'ap-jakarta', label: '雅加达' },
{ value: 'ap-seoul', label: '首尔' },
{ value: 'ap-bangkok', label: '曼谷' },
{ value: 'ap-tokyo', label: '东京' },
{ value: 'na-siliconvalley', label: '硅谷' },
{ value: 'na-ashburn', label: '弗吉尼亚' },
{ value: 'sa-saopaulo', label: '圣保罗' },
{ value: 'eu-frankfurt', label: '法兰克福' },
{ value: "", label: "--------中国大陆地区-------", disabled: true },
{ value: "ap-beijing-1", label: "北京1区" },
{ value: "ap-beijing", label: "北京" },
{ value: "ap-nanjing", label: "南京" },
{ value: "ap-shanghai", label: "上海" },
{ value: "ap-guangzhou", label: "广州" },
{ value: "ap-chengdu", label: "成都" },
{ value: "ap-chongqing", label: "重庆" },
{ value: "ap-shenzhen-fsi", label: "深圳金融" },
{ value: "ap-shanghai-fsi", label: "上海金融" },
{ value: "ap-beijing-fsi", label: "北京金融" },
{ value: "", label: "--------中国香港及境外-------", disabled: true },
{ value: "ap-hongkong", label: "中国香港" },
{ value: "ap-singapore", label: "新加坡" },
{ value: "ap-mumbai", label: "孟买" },
{ value: "ap-jakarta", label: "雅加达" },
{ value: "ap-seoul", label: "首尔" },
{ value: "ap-bangkok", label: "曼谷" },
{ value: "ap-tokyo", label: "东京" },
{ value: "na-siliconvalley", label: "硅谷" },
{ value: "na-ashburn", label: "弗吉尼亚" },
{ value: "sa-saopaulo", label: "圣保罗" },
{ value: "eu-frankfurt", label: "法兰克福" },
],
},
})
@@ -77,21 +77,21 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: 'COS域名',
helper: '请选择域名',
typeName: 'DeployCertToTencentCosPlugin',
title: "COS域名",
helper: "请选择域名",
typeName: "DeployCertToTencentCosPlugin",
action: DeployCertToTencentCosPlugin.prototype.onGetDomainList.name,
watches: ['bucket', 'region'],
watches: ["bucket", "region"],
})
)
domains!: string | string[];
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
title: "域名证书",
helper: "请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
@@ -109,9 +109,9 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
});
let tencentCertId: string = this.cert as string;
if (typeof this.cert !== 'string') {
if (typeof this.cert !== "string") {
tencentCertId = await client.uploadToTencent({
certName: this.appendTimeSuffix('certd'),
certName: this.appendTimeSuffix("certd"),
cert: this.cert,
});
}
@@ -119,7 +119,7 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
for (const domain of this.domains) {
const params = {
CertificateId: tencentCertId,
ResourceType: 'cos',
ResourceType: "cos",
Status: 1,
InstanceIdList: [`${this.region}#${this.bucket}#${domain}`],
};
@@ -127,22 +127,22 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
const res = await client.deployCertificateInstance(params);
this.logger.info(`域名${domain}部署成功:`, res);
}
this.logger.info('部署完成');
this.logger.info("部署完成");
}
async onGetDomainList(data: any) {
const access = await this.getAccess(this.accessId);
const cosv5 = await import('cos-nodejs-sdk-v5');
const cosv5 = await import("cos-nodejs-sdk-v5");
const cos = new cosv5.default({
SecretId: access.secretId,
SecretKey: access.secretKey,
});
if (!this.bucket) {
throw new Error('存储桶名称不能为空');
throw new Error("存储桶名称不能为空");
}
if (!this.region) {
throw new Error('所在地域不能为空');
throw new Error("所在地域不能为空");
}
const res = await cos.getBucketDomain({
@@ -151,7 +151,7 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
Region: this.region,
});
this.ctx.logger.info('获取域名列表:', res);
this.ctx.logger.info("获取域名列表:", res);
return res.DomainRule.map((item: any) => {
return {
@@ -1,18 +1,15 @@
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 {CertApplyPluginNames, CertInfo, CertReader} from "@certd/plugin-cert";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import { TencentAccess } from "../../../plugin-lib/tencent/access.js";
import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
@IsTaskPlugin({
name: 'DeployCertToTencentEO',
title: '腾讯云-部署到腾讯云EO',
icon: 'svg:icon-tencentcloud',
desc: '腾讯云边缘安全加速平台EdgeOne(EO)',
name: "DeployCertToTencentEO",
title: "腾讯云-部署到腾讯云EO",
icon: "svg:icon-tencentcloud",
desc: "腾讯云边缘安全加速平台EdgeOne(EO)",
group: pluginGroups.tencent.key,
default: {
strategy: {
@@ -21,63 +18,60 @@ import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
},
})
export class DeployCertToTencentEO extends AbstractTaskPlugin {
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
title: "域名证书",
helper: "请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
cert!: CertInfo | string;
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput(createRemoteSelectInputDefine({
title: '站点ID',
helper: '类似于zone-xxxx的字符串,在站点概览页面左上角,或者,站点列表页面站点名称下方',
action: DeployCertToTencentEO.prototype.onGetZoneList.name,
watches: ['certDomains', 'accessId'],
required: true,
component:{
name:"remote-auto-complete"
}
}))
@TaskInput(
createRemoteSelectInputDefine({
title: "站点ID",
helper: "类似于zone-xxxx的字符串,在站点概览页面左上角,或者,站点列表页面站点名称下方",
action: DeployCertToTencentEO.prototype.onGetZoneList.name,
watches: ["certDomains", "accessId"],
required: true,
component: {
name: "remote-auto-complete",
},
})
)
zoneId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: '加速域名',
helper: '请选择域名或输入域名',
title: "加速域名",
helper: "请选择域名或输入域名",
action: DeployCertToTencentEO.prototype.onGetDomainList.name,
})
)
domainNames!: string[];
@TaskInput({
title: '证书名称',
helper: '证书上传后将以此参数作为名称前缀',
title: "证书名称",
helper: "证书上传后将以此参数作为名称前缀",
})
certName!: string;
// @TaskInput({
// title: "CDN接口",
// helper: "CDN接口端点",
@@ -91,25 +85,25 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
Client: any;
async onInstance() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js");
this.Client = sdk.v20220901.Client;
}
async execute(): Promise<void> {
const accessProvider = await this.getAccess<TencentAccess>(this.accessId)
const accessProvider = await this.getAccess<TencentAccess>(this.accessId);
const client = this.getClient(accessProvider);
const sslClient = new TencentSslClient({
access:accessProvider,
access: accessProvider,
logger: this.logger,
});
if (this.cert == null){
throw new Error('请选择域名证书');
if (this.cert == null) {
throw new Error("请选择域名证书");
}
let tencentCertId = this.cert as string;
if (typeof this.cert !== 'string') {
if (typeof this.cert !== "string") {
const certReader = new CertReader(this.cert);
tencentCertId = await sslClient.uploadToTencent({
certName: certReader.buildCertName(),
@@ -117,17 +111,17 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
});
}
const params:any = {
const params: any = {
ZoneId: this.zoneId,
Hosts: this.domainNames,
Mode: 'sslcert',
Mode: "sslcert",
ServerCertInfo: [
{
CertId: tencentCertId,
},
],
};
this.logger.info('设置腾讯云EO证书参数:', JSON.stringify(params));
this.logger.info("设置腾讯云EO证书参数:", JSON.stringify(params));
await this.doRequest(client, params);
}
@@ -141,7 +135,7 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: '',
region: "",
profile: {
httpProfile: {
endpoint,
@@ -152,27 +146,22 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
return new TeoClient(clientConfig);
}
async doRequest(client: any, params: any) {
const ret = await client.ModifyHostsCertificate(params);
this.checkRet(ret);
this.logger.info('设置腾讯云EO证书成功:', ret.RequestId);
this.logger.info("设置腾讯云EO证书成功:", ret.RequestId);
return ret.RequestId;
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
async onGetZoneList(data: any) {
if (!this.accessId){
throw new Error('请选择授权');
if (!this.accessId) {
throw new Error("请选择授权");
}
const access: TencentAccess = await this.getAccess<TencentAccess>(this.accessId);
const client = await this.getClient(access);
@@ -193,8 +182,8 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
}
async onGetDomainList(data: any) {
if (!this.accessId){
throw new Error('请选择授权');
if (!this.accessId) {
throw new Error("请选择授权");
}
const access: TencentAccess = await this.getAccess<TencentAccess>(this.accessId);
const client = await this.getClient(access);
@@ -203,7 +192,7 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
ZoneId: this.zoneId,
});
this.checkRet(res);
const list = res.AccelerationDomains
const list = res.AccelerationDomains;
if (!list || list.length === 0) {
return [];
}
@@ -211,10 +200,10 @@ export class DeployCertToTencentEO extends AbstractTaskPlugin {
return {
label: item.DomainName,
value: item.DomainName,
domain: item.DomainName
domain: item.DomainName,
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
}
}
@@ -5,10 +5,10 @@ import { TencentAccess } from "../../../plugin-lib/tencent/access.js";
import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
@IsTaskPlugin({
name: 'TencentDeployCertToLive',
title: '腾讯云-部署到腾讯云直播',
icon: 'svg:icon-tencentcloud',
desc: 'https://console.cloud.tencent.com/live/',
name: "TencentDeployCertToLive",
title: "腾讯云-部署到腾讯云直播",
icon: "svg:icon-tencentcloud",
desc: "https://console.cloud.tencent.com/live/",
group: pluginGroups.tencent.key,
needPlus: false,
default: {
@@ -19,11 +19,11 @@ import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
})
export class TencentDeployCertToLive extends AbstractTaskPlugin {
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
@@ -31,20 +31,20 @@ export class TencentDeployCertToLive extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: '直播域名',
helper: '请选择域名或输入域名',
typeName: 'TencentDeployCertToLive',
title: "直播域名",
helper: "请选择域名或输入域名",
typeName: "TencentDeployCertToLive",
action: TencentDeployCertToLive.prototype.onGetDomainList.name,
})
)
domains!: string[];
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
title: "域名证书",
helper: "请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID",
component: {
name: 'output-selector',
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
name: "output-selector",
from: [...CertApplyPluginNames, "UploadCertToTencent"],
},
required: true,
})
@@ -56,13 +56,13 @@ export class TencentDeployCertToLive extends AbstractTaskPlugin {
const access = await this.getAccess<TencentAccess>(this.accessId);
let tencentCertId = this.cert as string;
if (typeof this.cert !== 'string') {
if (typeof this.cert !== "string") {
const sslClient = new TencentSslClient({
access,
logger: this.logger,
});
tencentCertId = await sslClient.uploadToTencent({
certName: this.appendTimeSuffix('certd'),
certName: this.appendTimeSuffix("certd"),
cert: this.cert,
});
}
@@ -81,18 +81,18 @@ export class TencentDeployCertToLive extends AbstractTaskPlugin {
const res = await client.ModifyLiveDomainCertBindings(params);
this.checkRet(res);
this.logger.info('部署完成', JSON.stringify(res));
this.logger.info("部署完成", JSON.stringify(res));
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
async getLiveClient() {
const accessProvider = await this.getAccess<TencentAccess>(this.accessId);
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/live/v20180801/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/live/v20180801/index.js");
const CssClient = sdk.v20180801.Client;
const clientConfig = {
@@ -100,7 +100,7 @@ export class TencentDeployCertToLive extends AbstractTaskPlugin {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: '',
region: "",
profile: {
httpProfile: {
endpoint: `live.${accessProvider.intlDomain()}tencentcloudapi.com`,
@@ -13,12 +13,11 @@ import yaml from "js-yaml";
desc: "修改TKE集群密钥配置,支持Opaque和TLS证书类型。注意:\n1. serverless集群请使用K8S部署插件;\n2. Opaque类型需要【上传到腾讯云】作为前置任务;\n3. ApiServer需要开通公网访问(或者certd可访问),实际上底层仍然是通过KubeClient进行部署",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
@TaskInput({
title: "ingress证书类型",
component: {
@@ -26,11 +25,11 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
vModel: "value",
options: [
{ value: "nginx", label: "TLS证书格式(Nginx可用)" },
{ value: "qcloud",label: "Opaque格式(CLB可用,原qcloud"}
]
{ value: "qcloud", label: "Opaque格式(CLB可用,原qcloud" },
],
},
helper: "clb将部署Opaque类型的证书,nginx类型将部署TLS证书格式",
required: true
required: true,
})
ingressClass!: string;
@@ -39,7 +38,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
helper: "请选择“上传证书到腾讯云”前置任务的输出",
component: {
name: "output-selector",
from: "UploadCertToTencent"
from: "UploadCertToTencent",
},
mergeScript: `
return {
@@ -48,17 +47,16 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
})
}
`,
required: true
required: true,
})
tencentCertId!: string;
@TaskInput({
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames]
from: [...CertApplyPluginNames],
},
mergeScript: `
return {
@@ -67,13 +65,10 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
})
}
`,
required: true
required: true,
})
cert!: any;
/**
* AccessProvider的key,或者一个包含access的具体的对象
*/
@@ -82,14 +77,12 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
helper: "access授权",
component: {
name: "access-selector",
type: "tencent"
type: "tencent",
},
required: true
required: true,
})
accessId!: string;
@TaskInput({ title: "大区", value: "ap-guangzhou", required: true })
region!: string;
@@ -97,7 +90,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
title: "集群ID",
required: true,
desc: "例如:cls-6lbj1vee",
request: true
request: true,
})
clusterId!: string;
@@ -112,8 +105,8 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
name: "a-select",
vModel: "value",
mode: "tags",
open: false
}
open: false,
},
})
secretName!: string | string[];
@@ -121,12 +114,11 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
title: "集群域名",
helper: "ApiServer需要开通公网访问,填写`ApiServer公网IP:443`\n默认为:[clusterId].ccs.tencent-cloud.com,可能访问不通",
component: {
placeholder: "xx.xxx.xx.xx:443"
}
placeholder: "xx.xxx.xx.xx:443",
},
})
clusterDomain!: string;
@TaskInput({
title: "ingress名称",
required: false,
@@ -135,12 +127,11 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
name: "a-select",
vModel: "value",
mode: "tags",
open: false
}
open: false,
},
})
ingressName!: string | string[];
@TaskInput({
title: "忽略证书校验",
required: false,
@@ -148,9 +139,9 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
component: {
name: "a-switch",
vModel: "checked",
}
},
})
skipTLSVerify!:boolean
skipTLSVerify!: boolean;
@TaskInput({
title: "Secret自动创建",
@@ -163,11 +154,9 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
})
createOnNotFound: boolean;
// @TaskInput({ title: "集群内网ip", helper: "如果开启了外网的话,无需设置" })
// clusterIp!: string;
K8sClient: any;
async onInstance() {
@@ -181,7 +170,6 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const tkeClient = await this.getTkeClient(accessProvider, this.region);
let kubeConfigStr = await this.getTkeKubeConfig(tkeClient, this.clusterId);
if (this.clusterDomain) {
const kubeConfig = yaml.load(kubeConfigStr);
kubeConfig.clusters[0].cluster.server = `https://${this.clusterDomain}`;
@@ -212,7 +200,6 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
this.logger.info("正在重启ingress:", this.ingressName);
await this.restartIngress({ k8sClient });
}
}
async getTkeClient(accessProvider: any, region = "ap-guangzhou") {
@@ -221,14 +208,14 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const clientConfig = {
credential: {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey
secretKey: accessProvider.secretKey,
},
region,
profile: {
httpProfile: {
endpoint: `tke.${accessProvider.intlDomain()}tencentcloudapi.com`
}
}
endpoint: `tke.${accessProvider.intlDomain()}tencentcloudapi.com`,
},
},
};
return new TkeClient(clientConfig);
@@ -237,7 +224,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
async getTkeKubeConfig(client: any, clusterId: string) {
// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
const params = {
ClusterId: clusterId
ClusterId: clusterId,
};
const ret = await client.DescribeClusterKubeconfig(params);
this.checkRet(ret);
@@ -256,13 +243,13 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const body = {
data: {
qcloud_cert_id: certIdBase64
qcloud_cert_id: certIdBase64,
},
metadata: {
labels: {
certd: this.appendTimeSuffix("certd")
}
}
certd: this.appendTimeSuffix("certd"),
},
},
};
let secretNames: any = secretName;
if (typeof secretName === "string") {
@@ -272,7 +259,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
await options.k8sClient.patchSecret({
namespace,
secretName: secret,
body
body,
});
this.logger.info(`CertSecret已更新:${secret}`);
}
@@ -291,20 +278,20 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const body = {
data: {
"tls.crt": crtBase64,
"tls.key": keyBase64
"tls.key": keyBase64,
},
metadata: {
labels: {
certd: this.appendTimeSuffix("certd")
}
}
certd: this.appendTimeSuffix("certd"),
},
},
};
let secretNames = secretName;
if (typeof secretName === "string") {
secretNames = [secretName];
}
for (const secret of secretNames) {
await k8sClient.patchSecret({ namespace, secretName: secret, body , createOnNotFound: this.createOnNotFound});
await k8sClient.patchSecret({ namespace, secretName: secret, body, createOnNotFound: this.createOnNotFound });
this.logger.info(`CertSecret已更新:${secret}`);
}
}
@@ -316,9 +303,9 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const body = {
metadata: {
labels: {
certd: this.appendTimeSuffix("certd")
}
}
certd: this.appendTimeSuffix("certd"),
},
},
};
let ingressNames = this.ingressName || [];
if (typeof ingressName === "string") {
@@ -335,5 +322,4 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
}
@@ -1,12 +1,12 @@
export * from './deploy-to-all/index.js';
export * from './deploy-to-clb/index.js';
export * from './deploy-to-cdn/index.js';
export * from './deploy-to-cdn-v2/index.js';
export * from './upload-to-tencent/index.js';
export * from './deploy-to-cos/index.js';
export * from './deploy-to-eo/index.js';
export * from './delete-expiring-cert/index.js';
export * from './deploy-to-tke-ingress/index.js';
export * from './deploy-to-live/index.js';
export * from './start-instances/index.js';
export * from './refresh-cert/index.js';
export * from "./deploy-to-all/index.js";
export * from "./deploy-to-clb/index.js";
export * from "./deploy-to-cdn/index.js";
export * from "./deploy-to-cdn-v2/index.js";
export * from "./upload-to-tencent/index.js";
export * from "./deploy-to-cos/index.js";
export * from "./deploy-to-eo/index.js";
export * from "./delete-expiring-cert/index.js";
export * from "./deploy-to-tke-ingress/index.js";
export * from "./deploy-to-live/index.js";
export * from "./start-instances/index.js";
export * from "./refresh-cert/index.js";
@@ -1,12 +1,4 @@
import {
AbstractTaskPlugin,
IsTaskPlugin,
Pager,
PageSearch,
pluginGroups,
RunStrategy,
TaskInput
} from "@certd/pipeline";
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 { TencentAccess } from "../../../plugin-lib/tencent/access.js";
@@ -25,9 +17,9 @@ import { omit } from "lodash-es";
default: {
//默认值配置照抄即可
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
//类名规范,跟上面插件名称(name)一致
export class TencentRefreshCert extends AbstractTaskPlugin {
@@ -37,8 +29,8 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
helper: "请选择前置任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames]
}
from: [...CertApplyPluginNames],
},
// required: true, // 必填
})
cert!: CertInfo;
@@ -51,9 +43,9 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
title: "腾讯云授权",
component: {
name: "access-selector",
type: "tencent" //固定授权类型
type: "tencent", //固定授权类型
},
required: true //必填
required: true, //必填
})
accessId!: string;
//
@@ -64,7 +56,7 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
helper: "要更新的证书id,如果这里没有,请先给手动绑定一次证书",
action: TencentRefreshCert.prototype.onGetCertList.name,
pager: false,
search: false
search: false,
})
)
certList!: string[];
@@ -98,110 +90,109 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
// resourceTypes!: string[];
@TaskInput({
title: '资源区域',
helper:"如果云资源类型区分区域,请选择区域,如果区域在选项中不存在,请手动输入(注意:当前仅支持CLB)",
title: "资源区域",
helper: "如果云资源类型区分区域,请选择区域,如果区域在选项中不存在,请手动输入(注意:当前仅支持CLB)",
component: {
name: 'remote-tree-select',
vModel: 'value',
name: "remote-tree-select",
vModel: "value",
action: TencentRefreshCert.prototype.onGetRegionsTree.name,
pager: false,
search: false,
watches: ['certList'],
watches: ["certList"],
},
required: false,
})
resourceTypesRegions!: string[];
//插件实例化时执行的方法
async onInstance() {
}
async onInstance() {}
//插件执行方法
async execute(): Promise<void> {
const access = await this.getAccess<TencentAccess>(this.accessId);
const sslClient = new TencentSslClient({
access:access,
access: access,
logger: this.logger,
});
// await access.createCert({cert:this.cert})
let resourceTypes = []
const resourceTypesRegions = []
if(!this.resourceTypesRegions){
this.resourceTypesRegions = []
const resourceTypes = [];
const resourceTypesRegions = [];
if (!this.resourceTypesRegions) {
this.resourceTypesRegions = [];
}
for (const item of this.resourceTypesRegions) {
const [type,region] = item.split("_")
if (!resourceTypes.includes( type)){
resourceTypes.push(type)
const [type, region] = item.split("_");
if (!resourceTypes.includes(type)) {
resourceTypes.push(type);
}
if (!region){
if (!region) {
continue;
}
const resourceType = resourceTypesRegions.find(item => item.ResourceType == type)
if (!resourceType){
const resourceType = resourceTypesRegions.find(item => item.ResourceType == type);
if (!resourceType) {
resourceTypesRegions.push({
ResourceType: type,
Regions: [region]
})
}else{
resourceType.Regions.push(region)
Regions: [region],
});
} else {
resourceType.Regions.push(region);
}
}
// resourceTypes = ["clb"] //固定clb
const maxRetry = 10
const maxRetry = 10;
for (const certId of this.certList) {
this.logger.info(`----------- 开始更新证书:${certId}`);
let deployRes = null
let deployRes = null;
let retryCount = 0
while(true){
if (retryCount>maxRetry){
let retryCount = 0;
while (true) {
if (retryCount > maxRetry) {
this.logger.error(`任务创建失败`);
break;
}
retryCount++
retryCount++;
const params = {
"OldCertificateId": certId,
"ResourceTypes": resourceTypes,
"CertificatePublicKey": "xxx",
"CertificatePrivateKey": "xxx",
"ResourceTypesRegions":resourceTypesRegions
}
OldCertificateId: certId,
ResourceTypes: resourceTypes,
CertificatePublicKey: "xxx",
CertificatePrivateKey: "xxx",
ResourceTypesRegions: resourceTypesRegions,
};
this.logger.info(`请求参数:${JSON.stringify(params)}`);
params.CertificatePublicKey = this.cert.crt
params.CertificatePrivateKey = this.cert.key
params.CertificatePublicKey = this.cert.crt;
params.CertificatePrivateKey = this.cert.key;
deployRes = await sslClient.UploadUpdateCertificateInstance(params);
if (deployRes && deployRes.DeployRecordId>0){
if (deployRes && deployRes.DeployRecordId > 0) {
this.logger.info(`任务创建成功,开始检查结果:${JSON.stringify(deployRes)}`);
break;
}else{
} else {
this.logger.info(`任务创建中,稍后查询:${JSON.stringify(deployRes)}`);
}
await this.ctx.utils.sleep(3000);
}
this.logger.info(`开始查询部署结果`);
retryCount=0
while(true){
if (retryCount>maxRetry){
retryCount = 0;
while (true) {
if (retryCount > maxRetry) {
this.logger.error(`任务结果检查失败`);
break;
}
retryCount++
retryCount++;
//查询部署状态
const deployStatus = await sslClient.DescribeHostUploadUpdateRecordDetail({
"DeployRecordId":deployRes.DeployRecordId
})
const details = deployStatus.DeployRecordDetail
let allSuccess = true
DeployRecordId: deployRes.DeployRecordId,
});
const details = deployStatus.DeployRecordDetail;
let allSuccess = true;
for (const item of details) {
this.logger.info(`查询结果:${JSON.stringify(omit(item,"RecordDetailList"))}`);
this.logger.info(`查询结果:${JSON.stringify(omit(item, "RecordDetailList"))}`);
if (item.Status === 2) {
throw new Error(`任务失败:${JSON.stringify(item.RecordDetailList)}`)
}else if (item.Status !== 1) {
throw new Error(`任务失败:${JSON.stringify(item.RecordDetailList)}`);
} else if (item.Status !== 1) {
//如果不是成功状态
allSuccess = false
allSuccess = false;
}
}
if (allSuccess) {
@@ -211,11 +202,9 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
}
this.logger.info(`----------- 更新证书${certId}成功`);
}
}
async onGetRegionsTree(data: PageSearch = {}){
async onGetRegionsTree(data: PageSearch = {}) {
const commonRegions = [
/**
* 华南地区(广州) waf.ap-guangzhou.tencentcloudapi.com
@@ -235,42 +224,42 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
* 南美地区(圣保罗) waf.sa-saopaulo.tencentcloudapi.com
* 欧洲地区(法兰克福) waf.eu-frankfurt.tencentcloudapi.com
*/
{value:"ap-guangzhou", label:"广州"},
{value:"ap-shanghai", label:"上海"},
{value:"ap-nanjing", label:"南京"},
{value:"ap-beijing", label:"北京"},
{value:"ap-chengdu", label:"成都"},
{value:"ap-chongqing", label:"重庆"},
{value:"ap-hongkong", label:"香港"},
{value:"ap-singapore", label:"新加坡"},
{value:"ap-jakarta", label:"雅加达"},
{value:"ap-bangkok", label:"曼谷"},
{value:"ap-tokyo", label:"东京"},
{value:"ap-seoul", label:"首尔"},
{value:"na-ashburn", label:"弗吉尼亚"},
{value:"na-siliconvalley", label:"硅谷"},
{value:"sa-saopaulo", label:"圣保罗"},
{value:"eu-frankfurt", label:"法兰克福"},
]
{ value: "ap-guangzhou", label: "广州" },
{ value: "ap-shanghai", label: "上海" },
{ value: "ap-nanjing", label: "南京" },
{ value: "ap-beijing", label: "北京" },
{ value: "ap-chengdu", label: "成都" },
{ value: "ap-chongqing", label: "重庆" },
{ value: "ap-hongkong", label: "香港" },
{ value: "ap-singapore", label: "新加坡" },
{ value: "ap-jakarta", label: "雅加达" },
{ value: "ap-bangkok", label: "曼谷" },
{ value: "ap-tokyo", label: "东京" },
{ value: "ap-seoul", label: "首尔" },
{ value: "na-ashburn", label: "弗吉尼亚" },
{ value: "na-siliconvalley", label: "硅谷" },
{ value: "sa-saopaulo", label: "圣保罗" },
{ value: "eu-frankfurt", label: "法兰克福" },
];
function buildTypeRegions(type: string) {
const options :any[]= []
const options: any[] = [];
for (const region of commonRegions) {
options.push({
label: type + "_" + region.label,
label: type + "_" + region.label,
value: type + "_" + region.value,
});
}
return options
return options;
}
return [
{ value: 'cdn',label: 'CDN'},
{ value: 'ddos',label: 'DDoS'},
{ value: 'live',label: '直播'},
{ value: 'vod',label: '点播'},
{ value: 'teo',label: 'TEO'},
{ value: 'lighthouse',label: '轻应用服务器'},
{ value: "cdn", label: "CDN" },
{ value: "ddos", label: "DDoS" },
{ value: "live", label: "直播" },
{ value: "vod", label: "点播" },
{ value: "teo", label: "TEO" },
{ value: "lighthouse", label: "轻应用服务器" },
{
label: "负载均衡(clb)",
value: "clb",
@@ -306,27 +295,25 @@ export class TencentRefreshCert extends AbstractTaskPlugin {
value: "tcb",
children: buildTypeRegions("tcb"),
},
]
];
}
async onGetCertList(data: PageSearch = {}) {
const access = await this.getAccess<TencentAccess>(this.accessId)
const access = await this.getAccess<TencentAccess>(this.accessId);
const sslClient = new TencentSslClient({
access:access,
access: access,
logger: this.logger,
});
const pager = new Pager(data);
const offset = pager.getOffset();
const limit = pager.pageSize
const res = await sslClient.DescribeCertificates({Limit:limit,Offset:offset,SearchKey:data.searchKey})
const list = res.Certificates
const limit = pager.pageSize;
const res = await sslClient.DescribeCertificates({ Limit: limit, Offset: offset, SearchKey: data.searchKey });
const list = res.Certificates;
if (!list || list.length === 0) {
throw new Error("没有找到证书,你可以直接手动输入id");
}
/**
* certificate-id
* name
@@ -3,11 +3,11 @@ import { createRemoteSelectInputDefine } from "@certd/plugin-lib";
import { TencentAccess } from "../../../plugin-lib/tencent/access.js";
@IsTaskPlugin({
name: 'TencentActionInstancesPlugin',
title: '腾讯云-实例开关机',
icon: 'svg:icon-tencentcloud',
name: "TencentActionInstancesPlugin",
title: "腾讯云-实例开关机",
icon: "svg:icon-tencentcloud",
group: pluginGroups.tencent.key,
desc: '腾讯云实例开关机',
desc: "腾讯云实例开关机",
default: {
strategy: {
runStrategy: RunStrategy.AlwaysRun,
@@ -17,46 +17,46 @@ import { TencentAccess } from "../../../plugin-lib/tencent/access.js";
})
export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
@TaskInput({
title: 'Access提供者',
helper: 'access 授权',
title: "Access提供者",
helper: "access 授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '所在地域',
helper: '实例所在地域',
title: "所在地域",
helper: "实例所在地域",
component: {
name: 'a-auto-complete',
vModel: 'value',
name: "a-auto-complete",
vModel: "value",
options: [
{ value: '', label: '--------中国大陆地区-------', disabled: true },
{ value: 'ap-beijing-1', label: '北京1区' },
{ value: 'ap-beijing', label: '北京' },
{ value: 'ap-nanjing', label: '南京' },
{ value: 'ap-shanghai', label: '上海' },
{ value: 'ap-guangzhou', label: '广州' },
{ value: 'ap-chengdu', label: '成都' },
{ value: 'ap-chongqing', label: '重庆' },
{ value: 'ap-shenzhen-fsi', label: '深圳金融' },
{ value: 'ap-shanghai-fsi', label: '上海金融' },
{ value: 'ap-beijing-fsi', label: '北京金融' },
{ value: '', label: '--------中国香港及境外-------', disabled: true },
{ value: 'ap-hongkong', label: '中国香港' },
{ value: 'ap-singapore', label: '新加坡' },
{ value: 'ap-mumbai', label: '孟买' },
{ value: 'ap-jakarta', label: '雅加达' },
{ value: 'ap-seoul', label: '首尔' },
{ value: 'ap-bangkok', label: '曼谷' },
{ value: 'ap-tokyo', label: '东京' },
{ value: 'na-siliconvalley', label: '硅谷' },
{ value: 'na-ashburn', label: '弗吉尼亚' },
{ value: 'sa-saopaulo', label: '圣保罗' },
{ value: 'eu-frankfurt', label: '法兰克福' },
{ value: "", label: "--------中国大陆地区-------", disabled: true },
{ value: "ap-beijing-1", label: "北京1区" },
{ value: "ap-beijing", label: "北京" },
{ value: "ap-nanjing", label: "南京" },
{ value: "ap-shanghai", label: "上海" },
{ value: "ap-guangzhou", label: "广州" },
{ value: "ap-chengdu", label: "成都" },
{ value: "ap-chongqing", label: "重庆" },
{ value: "ap-shenzhen-fsi", label: "深圳金融" },
{ value: "ap-shanghai-fsi", label: "上海金融" },
{ value: "ap-beijing-fsi", label: "北京金融" },
{ value: "", label: "--------中国香港及境外-------", disabled: true },
{ value: "ap-hongkong", label: "中国香港" },
{ value: "ap-singapore", label: "新加坡" },
{ value: "ap-mumbai", label: "孟买" },
{ value: "ap-jakarta", label: "雅加达" },
{ value: "ap-seoul", label: "首尔" },
{ value: "ap-bangkok", label: "曼谷" },
{ value: "ap-tokyo", label: "东京" },
{ value: "na-siliconvalley", label: "硅谷" },
{ value: "na-ashburn", label: "弗吉尼亚" },
{ value: "sa-saopaulo", label: "圣保罗" },
{ value: "eu-frankfurt", label: "法兰克福" },
],
},
required: true,
@@ -65,23 +65,23 @@ export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: '实列ID',
helper: '请选择实列',
typeName: 'TencentStartInstancesPlugin',
title: "实列ID",
helper: "请选择实列",
typeName: "TencentStartInstancesPlugin",
action: TencentActionInstancesPlugin.prototype.onGetInstanceList.name,
watches: ['region'],
watches: ["region"],
})
)
instanceId!: string[];
@TaskInput({
title: '操作',
title: "操作",
component: {
name: 'a-radio-group',
vModel: 'value',
name: "a-radio-group",
vModel: "value",
options: [
{ value: 'start', label: '开机' },
{ value: 'stop', label: '关机' },
{ value: "start", label: "开机" },
{ value: "stop", label: "关机" },
],
},
required: true,
@@ -89,11 +89,11 @@ export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
action!: string;
@TaskInput({
title: '实例关机不收费',
title: "实例关机不收费",
value: true,
component: {
name: 'a-switch',
vModel: 'checked',
name: "a-switch",
vModel: "checked",
placeholder: `按量计费实例关机不收费`,
},
required: false,
@@ -115,13 +115,13 @@ export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
InstanceIds: this.instanceId,
};
let res: any;
if (this.action === 'start') {
if (this.action === "start") {
res = await cvmClient.StartInstances(params);
} else {
res = await cvmClient.StopInstances(
Object.assign(params, {
StopType: 'SOFT_FIRST',
StoppedMode: this.charging ? 'STOP_CHARGING' : 'KEEP_CHARGING',
StopType: "SOFT_FIRST",
StoppedMode: this.charging ? "STOP_CHARGING" : "KEEP_CHARGING",
})
);
}
@@ -131,17 +131,17 @@ export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
async getCvmClient() {
const accessProvider = await this.getAccess<TencentAccess>(this.accessId);
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/cvm/v20170312/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/cvm/v20170312/index.js");
const CvmClient = sdk.v20170312.Client;
if (!this.region) {
throw new Error('所在地域不能为空');
throw new Error("所在地域不能为空");
}
const clientConfig = {
@@ -167,7 +167,7 @@ export class TencentActionInstancesPlugin extends AbstractTaskPlugin {
});
this.checkRet(res);
this.ctx.logger.info('获取实列列表:', res);
this.ctx.logger.info("获取实列列表:", res);
return res.InstanceSet.map((item: any) => {
return {
label: item.InstanceName,
@@ -4,10 +4,10 @@ import { TencentAccess } from "../../../plugin-lib/tencent/access.js";
import { TencentSslClient } from "../../../plugin-lib/tencent/index.js";
@IsTaskPlugin({
name: 'UploadCertToTencent',
title: '腾讯云-上传证书到腾讯云',
icon: 'svg:icon-tencentcloud',
desc: '上传成功后输出:tencentCertId',
name: "UploadCertToTencent",
title: "腾讯云-上传证书到腾讯云",
icon: "svg:icon-tencentcloud",
desc: "上传成功后输出:tencentCertId",
group: pluginGroups.tencent.key,
default: {
strategy: {
@@ -20,21 +20,21 @@ export class UploadCertToTencent extends AbstractTaskPlugin {
// name!: string;
@TaskInput({
title: 'Access授权',
helper: 'access授权',
title: "Access授权",
helper: "access授权",
component: {
name: 'access-selector',
type: 'tencent',
name: "access-selector",
type: "tencent",
},
required: true,
})
accessId!: string;
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: 'output-selector',
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
@@ -42,13 +42,13 @@ export class UploadCertToTencent extends AbstractTaskPlugin {
cert!: any;
@TaskOutput({
title: '上传成功后的腾讯云CertId',
title: "上传成功后的腾讯云CertId",
})
tencentCertId?: string;
Client: any;
async onInstance() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js');
const sdk = await import("tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js");
this.Client = sdk.v20191205.Client;
}
@@ -68,11 +68,9 @@ export class UploadCertToTencent extends AbstractTaskPlugin {
this.tencentCertId = tencentCertId;
}
checkRet(ret: any) {
if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
}
}
}