mirror of
https://github.com/certd/certd.git
synced 2026-06-30 16:39:43 +08:00
chore: format
This commit is contained in:
@@ -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";
|
||||
|
||||
+32
-32
@@ -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";
|
||||
|
||||
+26
-27
@@ -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();
|
||||
|
||||
+110
-124
@@ -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";
|
||||
|
||||
+45
-46
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
+28
-32
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -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`,
|
||||
|
||||
+39
-53
@@ -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
|
||||
|
||||
+54
-54
@@ -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,
|
||||
|
||||
+14
-16
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user