feat: 升级midway,支持esm

This commit is contained in:
xiaojunnuo
2024-07-15 00:30:33 +08:00
parent 970c7fd8a0
commit 485e603b51
246 changed files with 3821 additions and 1532 deletions
@@ -1,6 +1,6 @@
export * from '@certd/plugin-cert';
export * from './plugin-aliyun';
export * from './plugin-tencent';
export * from './plugin-host';
export * from './plugin-huawei';
export * from './plugin-demo';
export * from './plugin-aliyun/index.js';
export * from './plugin-tencent/index.js';
export * from './plugin-host/index.js';
export * from './plugin-huawei/index.js';
export * from './plugin-demo/index.js';
@@ -1 +1 @@
export * from './aliyun-access';
export * from './aliyun-access.js';
@@ -1,7 +1,12 @@
import Core from "@alicloud/pop-core";
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { Autowire, ILogger } from "@certd/pipeline";
import { AliyunAccess } from "../access";
import Core from '@alicloud/pop-core';
import {
AbstractDnsProvider,
CreateRecordOptions,
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import { Autowire, ILogger } from '@certd/pipeline';
import { AliyunAccess } from '../access/index.js';
@IsDnsProvider({
name: 'aliyun',
@@ -9,7 +14,7 @@ import { AliyunAccess } from "../access";
desc: '阿里云DNS解析提供商',
accessType: 'aliyun',
})
export class AliyunDnsProvider extends AbstractDnsProvider{
export class AliyunDnsProvider extends AbstractDnsProvider {
client: any;
@Autowire()
access!: AliyunAccess;
@@ -86,8 +91,8 @@ export class AliyunDnsProvider extends AbstractDnsProvider{
// }
async createRecord(options: CreateRecordOptions): Promise<any> {
const { fullRecord, value, type,domain } = options;
this.logger.info('添加域名解析:', fullRecord, value,domain);
const { fullRecord, value, type, domain } = options;
this.logger.info('添加域名解析:', fullRecord, value, domain);
// const domain = await this.matchDomain(fullRecord);
const rr = fullRecord.replace('.' + domain, '');
@@ -1 +1 @@
import './aliyun-dns-provider';
import './aliyun-dns-provider.js';
@@ -1,3 +1,3 @@
export * from './access/index';
export * from './dns-provider/index';
export * from './plugin/index';
export * from './access/index.js';
export * from './dns-provider/index.js';
export * from './plugin/index.js';
@@ -9,9 +9,9 @@ import {
} from '@certd/pipeline';
// @ts-ignore
import { ROAClient } from '@alicloud/pop-core';
import { AliyunAccess } from '../../access';
import { K8sClient } from '@certd/plugin-util';
import { appendTimeSuffix } from '../../utils';
import { AliyunAccess } from '../../access/index.js';
import { K8sClient } from '@certd/lib-k8s';
import { appendTimeSuffix } from '../../utils/index.js';
import { CertInfo } from '@certd/plugin-cert';
@IsTaskPlugin({
@@ -9,7 +9,7 @@ import {
import dayjs from 'dayjs';
import Core from '@alicloud/pop-core';
import RPCClient from '@alicloud/pop-core';
import { AliyunAccess } from '../../access';
import { AliyunAccess } from '../../access/index.js';
@IsTaskPlugin({
name: 'DeployCertToAliyunCDN',
@@ -1,3 +1,3 @@
export * from './deploy-to-cdn/index';
export * from './deploy-to-ack-ingress/index';
export * from './upload-to-aliyun/index';
export * from './deploy-to-cdn/index.js';
export * from './deploy-to-ack-ingress/index.js';
export * from './upload-to-aliyun/index.js';
@@ -7,8 +7,8 @@ import {
TaskOutput,
} from '@certd/pipeline';
import Core from '@alicloud/pop-core';
import { AliyunAccess } from '../../access';
import { appendTimeSuffix, checkRet, ZoneOptions } from '../../utils';
import { AliyunAccess } from '../../access/index.js';
import { appendTimeSuffix, checkRet, ZoneOptions } from '../../utils/index.js';
import { Logger } from 'log4js';
@IsTaskPlugin({
@@ -1,6 +1,11 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { Autowire, HttpClient, ILogger } from "@certd/pipeline";
import { CloudflareAccess } from "./access";
import {
AbstractDnsProvider,
CreateRecordOptions,
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import { Autowire, HttpClient, ILogger } from '@certd/pipeline';
import { CloudflareAccess } from './access.js';
export type CloudflareRecord = {
id: string;
@@ -15,7 +20,6 @@ export type CloudflareRecord = {
modified_on: string;
};
// 这里通过IsDnsProvider注册一个dnsProvider
@IsDnsProvider({
name: 'cloudflare',
@@ -24,94 +28,96 @@ export type CloudflareRecord = {
// 这里是对应的 cloudflare的access类型名称
accessType: 'cloudflare',
})
export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord>{
export class CloudflareDnsProvider extends AbstractDnsProvider<CloudflareRecord> {
// 通过Autowire传递context
@Autowire()
logger! : ILogger;
logger!: ILogger;
access!: CloudflareAccess;
http!: HttpClient;
async onInstance() {
//一些初始化的操作
// 也可以通过ctx成员变量传递context 与Autowire效果一样
this.access = this.ctx.access as CloudflareAccess;
this.http = this.ctx.http
this.http = this.ctx.http;
}
async getZoneId(domain:string){
async getZoneId(domain: string) {
const url = `https://api.cloudflare.com/client/v4/zones?name=${domain}`;
const res = await this.doRequestApi(url,null,"get");
return res.result[0].id
const res = await this.doRequestApi(url, null, 'get');
return res.result[0].id;
}
private async doRequestApi(url: string,data:any = null,method:string="post") {
const res = await this.http.request<any,any>({
url,
method,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.access.apiToken}`,
},
data
});
if (!res.success) {
throw new Error(`${JSON.stringify(res.errors)}`);
}
return res
private async doRequestApi(url: string, data: any = null, method = 'post') {
const res = await this.http.request<any, any>({
url,
method,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.access.apiToken}`,
},
data,
});
if (!res.success) {
throw new Error(`${JSON.stringify(res.errors)}`);
}
return res;
}
/**
* 创建dns解析记录,用于验证域名所有权
* 创建dns解析记录,用于验证域名所有权
*/
async createRecord(options: CreateRecordOptions): Promise<CloudflareRecord> {
/**
* fullRecord: '_acme-challenge.test.example.com',
* value: 一串uuid
* type: 'TXT',
* domain: 'example.com'
*/
const { fullRecord, value, type,domain } = options;
this.logger.info('添加域名解析:', fullRecord, value, type,domain);
const { fullRecord, value, type, domain } = options;
this.logger.info('添加域名解析:', fullRecord, value, type, domain);
const zoneId = await this.getZoneId(domain);
this.logger.info('获取zoneId成功:',zoneId)
this.logger.info('获取zoneId成功:', zoneId);
// 给domain下创建txt类型的dns解析记录,fullRecord
let url = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`;
const url = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`;
const res = await this.doRequestApi(url, {
content: value,
name: fullRecord,
type: type,
ttl: 60,
})
content: value,
name: fullRecord,
type: type,
ttl: 60,
});
const record = res.result as CloudflareRecord;
this.logger.info(`添加域名解析成功:fullRecord=${fullRecord},value=${value}`);
this.logger.info(`dns解析记录:${JSON.stringify(record)}`,)
this.logger.info(
`添加域名解析成功:fullRecord=${fullRecord},value=${value}`
);
this.logger.info(`dns解析记录:${JSON.stringify(record)}`);
//本接口需要返回本次创建的dns解析记录,这个记录会在删除的时候用到
return record
return record;
}
/**
* 删除dns解析记录,清理申请痕迹
* @param options
*/
async removeRecord(options: RemoveRecordOptions<CloudflareRecord>): Promise<void> {
async removeRecord(
options: RemoveRecordOptions<CloudflareRecord>
): Promise<void> {
const { fullRecord, value, record } = options;
this.logger.info('删除域名解析:', fullRecord, value);
if(!record){
if (!record) {
this.logger.info('record不存在');
return
return;
}
//这里调用删除txt dns解析记录接口
const zoneId = record.zone_id;
const recordId = record.id;
let url = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recordId}`;
await this.doRequestApi(url,null,"delete")
this.logger.info(`删除域名解析成功:fullRecord=${fullRecord},value=${value}`);
const url = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recordId}`;
await this.doRequestApi(url, null, 'delete');
this.logger.info(
`删除域名解析成功:fullRecord=${fullRecord},value=${value}`
);
}
}
@@ -1,3 +1,3 @@
export * from './dns-provider';
export * from './plugins';
export * from './access';
export * from './dns-provider.js';
export * from './plugins/index.js';
export * from './access.js';
@@ -1 +1 @@
export * from './plugin-deploy-to-cdn';
export * from './plugin-deploy-to-cdn.js';
@@ -1,4 +1,4 @@
import { IsAccess, AccessInput, IAccess } from "@certd/pipeline";
import { IsAccess, AccessInput, IAccess } from '@certd/pipeline';
/**
* 这个注解将注册一个授权配置
@@ -9,7 +9,7 @@ import { IsAccess, AccessInput, IAccess } from "@certd/pipeline";
title: '授权插件示例',
desc: '',
})
export class DemoAccess implements IAccess{
export class DemoAccess implements IAccess {
/**
* 授权属性配置
*/
@@ -1,20 +1,24 @@
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { Autowire, HttpClient, ILogger } from "@certd/pipeline";
import { DemoAccess } from "./access";
import {
AbstractDnsProvider,
CreateRecordOptions,
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import { Autowire, HttpClient, ILogger } from '@certd/pipeline';
import { DemoAccess } from './access.js';
type DemoRecord = {
// 这里定义Record记录的数据结构,跟对应云平台接口返回值一样即可,一般是拿到id就行,用于删除txt解析记录,清理申请痕迹
// id:string
}
};
// 这里通过IsDnsProvider注册一个dnsProvider
@IsDnsProvider({
name: "demo",
title: "Dns提供商Demo",
desc: "dns provider示例",
name: 'demo',
title: 'Dns提供商Demo',
desc: 'dns provider示例',
// 这里是对应的云平台的access类型名称
accessType: "demo"
accessType: 'demo',
})
export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
// 通过Autowire注入工具对象
@@ -27,12 +31,11 @@ export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
async onInstance() {
// 也可以通过ctx成员变量传递context 与Autowire效果一样
this.http = this.ctx.http;
this.logger.debug("access", this.access);
this.logger.debug('access', this.access);
//初始化的操作
//...
}
/**
* 创建dns解析记录,用于验证域名所有权
*/
@@ -45,7 +48,7 @@ export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
* domain: 'example.com'
*/
const { fullRecord, value, type, domain } = options;
this.logger.info("添加域名解析:", fullRecord, value, type, domain);
this.logger.info('添加域名解析:', fullRecord, value, type, domain);
// 调用创建dns解析记录的对应的云端接口,创建txt类型的dns解析记录
// 请根据实际接口情况调用,例如:
@@ -64,7 +67,7 @@ export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
*/
async removeRecord(options: RemoveRecordOptions<DemoRecord>): Promise<void> {
const { fullRecord, value, record } = options;
this.logger.info("删除域名解析:", fullRecord, value, record);
this.logger.info('删除域名解析:', fullRecord, value, record);
//这里调用删除txt dns解析记录接口
//请根据实际接口情况调用,例如:
@@ -75,7 +78,7 @@ export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
// })
//
this.logger.info("删除域名解析成功:", fullRecord, value);
this.logger.info('删除域名解析成功:', fullRecord, value);
}
}
@@ -1,3 +1,3 @@
export * from './dns-provider';
export * from './plugins';
export * from './access';
export * from './dns-provider.js';
export * from './plugins/index.js';
export * from './access.js';
@@ -1 +1 @@
export * from './plugin-test';
export * from './plugin-test.js';
@@ -1 +1 @@
export * from './ssh-access';
export * from './ssh-access.js';
@@ -1,3 +1,3 @@
export * from './access';
export * from './lib/ssh';
export * from './plugin';
export * from './access/index.js';
export * from './lib/ssh.js';
export * from './plugin/index.js';
@@ -1,16 +1,16 @@
// @ts-ignore
import ssh2, { ConnectConfig } from 'ssh2';
import path from 'path';
import _ from 'lodash';
import * as _ from 'lodash-es';
import { ILogger } from '@certd/pipeline';
import iconv from 'iconv-lite';
import {SshAccess} from "../access";
import { SshAccess } from '../access/index.js';
export class AsyncSsh2Client {
conn: ssh2.Client;
logger: ILogger;
connConf: ssh2.ConnectConfig;
windows:boolean = false;
encoding:string;
windows = false;
encoding: string;
constructor(connConf: SshAccess, logger: ILogger) {
this.connConf = connConf;
this.logger = logger;
@@ -19,7 +19,7 @@ export class AsyncSsh2Client {
}
convert(buffer: Buffer) {
if(this.encoding){
if (this.encoding) {
return iconv.decode(buffer, this.encoding);
}
return buffer.toString();
@@ -31,6 +31,7 @@ export class AsyncSsh2Client {
const conn = new ssh2.Client();
conn
.on('error', (err: any) => {
this.logger.error('连接失败', err);
reject(err);
})
.on('ready', () => {
@@ -77,7 +78,7 @@ export class AsyncSsh2Client {
reject(err);
return;
}
let data: string = '';
let data = '';
stream
.on('close', (code: any, signal: any) => {
this.logger.info(`[${this.connConf.host}][close]:code:${code}`);
@@ -88,13 +89,13 @@ export class AsyncSsh2Client {
}
})
.on('data', (ret: Buffer) => {
const out = this.convert(ret)
data += out
const out = this.convert(ret);
data += out;
this.logger.info(`[${this.connConf.host}][info]: ` + out.trimEnd());
})
.stderr.on('data', (ret:Buffer) => {
const err = this.convert(ret)
data += err
.stderr.on('data', (ret: Buffer) => {
const err = this.convert(ret);
data += err;
this.logger.info(`[${this.connConf.host}][error]: ` + err.trimEnd());
});
});
@@ -103,9 +104,7 @@ export class AsyncSsh2Client {
async shell(script: string | string[]): Promise<string[]> {
return new Promise<any>((resolve, reject) => {
this.logger.info(
`执行shell脚本:[${this.connConf.host}][shell]: ` + script
);
this.logger.info(`执行shell脚本:[${this.connConf.host}][shell]: ` + script);
this.conn.shell((err: Error, stream: any) => {
if (err) {
reject(err);
@@ -118,15 +117,15 @@ export class AsyncSsh2Client {
resolve(output);
})
.on('data', (ret: Buffer) => {
const data = this.convert(ret)
const data = this.convert(ret);
this.logger.info('' + data);
output.push(data);
})
.stderr.on('data', (ret:Buffer) => {
const data = this.convert(ret)
.stderr.on('data', (ret: Buffer) => {
const data = this.convert(ret);
output.push(data);
this.logger.info(`[${this.connConf.host}][error]: ` + data);
});
});
stream.end(script + '\nexit\n');
});
});
@@ -161,15 +160,15 @@ export class SshClient {
const sftp = await conn.getSftp();
this.logger.info('开始上传');
for (const transport of transports) {
let filePath = path.dirname(transport.remotePath);
const filePath = path.dirname(transport.remotePath);
let mkdirCmd = `mkdir -p ${filePath} `;
if(conn.windows){
if(filePath.indexOf("/") > -1){
this.logger.info("--------------------------")
this.logger.info("请注意:windows下,文件目录分隔应该写成\\而不是/")
this.logger.info("--------------------------")
if (conn.windows) {
if (filePath.indexOf('/') > -1) {
this.logger.info('--------------------------');
this.logger.info('请注意:windows下,文件目录分隔应该写成\\而不是/');
this.logger.info('--------------------------');
}
const spec = await conn.exec(`echo %COMSPEC%`);
const spec = await conn.exec('echo %COMSPEC%');
if (spec.toString().trim() === '%COMSPEC%') {
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
} else {
@@ -184,10 +183,7 @@ export class SshClient {
});
}
async exec(options: {
connectConf: SshAccess;
script: string | Array<string>;
}) {
async exec(options: { connectConf: SshAccess; script: string | Array<string> }) {
let { script } = options;
const { connectConf } = options;
if (_.isArray(script)) {
@@ -203,10 +199,7 @@ export class SshClient {
});
}
async shell(options: {
connectConf: SshAccess;
script: string;
}): Promise<string[]> {
async shell(options: { connectConf: SshAccess; script: string }): Promise<string[]> {
const { connectConf, script } = options;
return await this._call({
connectConf,
@@ -216,10 +209,7 @@ export class SshClient {
});
}
async _call(options: {
connectConf: SshAccess;
callable: any;
}): Promise<string[]> {
async _call(options: { connectConf: SshAccess; callable: any }): Promise<string[]> {
const { connectConf, callable } = options;
const conn = new AsyncSsh2Client(connectConf, this.logger);
await conn.connect();
@@ -6,7 +6,7 @@ import {
RunStrategy,
TaskInput,
} from '@certd/pipeline';
import { SshClient } from '../../lib/ssh';
import { SshClient } from '../../lib/ssh.js';
@IsTaskPlugin({
name: 'hostShellExecute',
@@ -1,2 +1,2 @@
export * from './host-shell-execute';
export * from './upload-to-host';
export * from './host-shell-execute/index.js';
export * from './upload-to-host/index.js';
@@ -7,10 +7,10 @@ import {
TaskInput,
TaskOutput,
} from '@certd/pipeline';
import { SshClient } from '../../lib/ssh';
import { SshClient } from '../../lib/ssh.js';
import { CertInfo, CertReader } from '@certd/plugin-cert';
import * as fs from 'fs';
import {SshAccess} from "../../access";
import { SshAccess } from '../../access/index.js';
@IsTaskPlugin({
name: 'uploadCertToHost',
@@ -113,7 +113,7 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin {
throw new Error('主机登录授权配置不能为空');
}
this.logger.info('准备上传到服务器');
const connectConf:SshAccess = await this.accessService.getById(accessId);
const connectConf: SshAccess = await this.accessService.getById(accessId);
const sshClient = new SshClient(this.logger);
await sshClient.uploadFiles({
connectConf,
@@ -1 +1 @@
export * from './huawei-access';
export * from './huawei-access.js';
@@ -1,8 +1,8 @@
import _ from "lodash";
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
import { Autowire, ILogger } from "@certd/pipeline";
import { HuaweiAccess } from "../access";
import { ApiRequestOptions, HuaweiYunClient } from "../lib/client";
import * as _ from 'lodash-es';
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
import { Autowire, ILogger } from '@certd/pipeline';
import { HuaweiAccess } from '../access/index.js';
import { ApiRequestOptions, HuaweiYunClient } from '@certd/lib-huawei';
export type SearchRecordOptions = {
zoneId: string;
@@ -14,7 +14,7 @@ export type SearchRecordOptions = {
desc: '华为云DNS解析提供商',
accessType: 'huawei',
})
export class HuaweiDnsProvider extends AbstractDnsProvider{
export class HuaweiDnsProvider extends AbstractDnsProvider {
client!: HuaweiYunClient;
@Autowire()
access!: HuaweiAccess;
@@ -1 +1 @@
import './huawei-dns-provider';
import './huawei-dns-provider.js';
@@ -1,2 +1,2 @@
export * from './access';
export * from './dns-provider';
export * from './access/index.js';
export * from './dns-provider/index.js';
@@ -1,24 +0,0 @@
# License
[The MIT License (MIT)](http://opensource.org/licenses/MIT)
Copyright (c) 2009-2013 Jeff Mott
Copyright (c) 2013-2016 Evan Vosberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -1,20 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,35 +0,0 @@
var signer = require("./signer");
var https = require("https");
var sig = new signer.Signer();
//Set the AK/SK to sign and authenticate the request.
sig.Key = "QTWAOYTTINDUT2QVKYUC";
sig.Secret = "MFyfvK41ba2giqM7**********KGpownRZlmVmHc";
//The following example shows how to set the request URL and parameters to query a VPC list.
//Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
//Set request host.
//Set request URI.
//Set parameters for the request URL.
var r = new signer.HttpRequest("GET", "endpoint.example.com/v1/77b6a44cba5143ab91d13ab9a8ff44fd/vpcs?limie=1");
//Add header parameters, for example, x-domain-id for invoking a global service and x-project-id for invoking a project-level service.
r.headers = { "Content-Type": "application/json" };
//Add a body if you have specified the PUT or POST method. Special characters, such as the double quotation mark ("), contained in the body must be escaped.
r.body = "";
var opt = sig.Sign(r);
console.log(opt.headers["X-Sdk-Date"]);
console.log(opt.headers["Authorization"]);
var req = https.request(opt, function (res) {
console.log(res.statusCode);
console.log("headers:", JSON.stringify(res.headers));
res.on("data", function (chunk) {
console.log(chunk.toString());
});
});
req.on("error", function (err) {
console.log(err.message);
});
req.write(r.body);
req.end();
@@ -1,501 +0,0 @@
// HWS API Gateway Signature
(function (root, factory) {
"use strict";
/*global define*/
if (typeof define === "function" && define.amd) {
// AMD
define(["CryptoJS"], function (CryptoJS) {
var crypto_wrapper = {
hmacsha256: function (keyByte, message) {
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
},
HexEncodeSHA256Hash: function (body) {
return CryptoJS.SHA256(body);
},
};
return factory(crypto_wrapper);
});
} else if (typeof wx === "object") {
// wechat
var CryptoJS = require("./js/hmac-sha256.js");
var crypto_wrapper = {
hmacsha256: function (keyByte, message) {
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
},
HexEncodeSHA256Hash: function (body) {
return CryptoJS.SHA256(body);
},
};
module.exports = factory(crypto_wrapper);
} else if (typeof module === "object" && module.exports) {
// Node
var crypto = require("crypto");
var crypto_wrapper = {
hmacsha256: function (keyByte, message) {
return crypto.createHmac("SHA256", keyByte).update(message).digest().toString("hex");
},
HexEncodeSHA256Hash: function (body) {
return crypto.createHash("SHA256").update(body).digest().toString("hex");
},
};
module.exports = factory(crypto_wrapper);
} else {
// Browser
var CryptoJS = root.CryptoJS;
var crypto_wrapper = {
hmacsha256: function (keyByte, message) {
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
},
HexEncodeSHA256Hash: function (body) {
return CryptoJS.SHA256(body);
},
};
root.signer = factory(crypto_wrapper);
}
})(this, function (crypto_wrapper) {
"use strict";
var Algorithm = "SDK-HMAC-SHA256";
var HeaderXDate = "X-Sdk-Date";
var HeaderAuthorization = "Authorization";
var HeaderContentSha256 = "x-sdk-content-sha256";
const hexTable = new Array(256);
for (var i = 0; i < 256; ++i) hexTable[i] = "%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase();
const noEscape = [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 0 - 15
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 16 - 31
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
0, // 32 - 47
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
0, // 48 - 63
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1, // 64 - 79
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
1, // 80 - 95
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1, // 96 - 111
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
1,
0, // 112 - 127
];
// function urlEncode is based on https://github.com/nodejs/node/blob/master/lib/querystring.js
// Copyright Joyent, Inc. and other Node contributors.
function urlEncode(str) {
if (typeof str !== "string") {
if (typeof str === "object") str = String(str);
else str += "";
}
var out = "";
var lastPos = 0;
for (var i = 0; i < str.length; ++i) {
var c = str.charCodeAt(i);
// ASCII
if (c < 0x80) {
if (noEscape[c] === 1) continue;
if (lastPos < i) out += str.slice(lastPos, i);
lastPos = i + 1;
out += hexTable[c];
continue;
}
if (lastPos < i) out += str.slice(lastPos, i);
// Multi-byte characters ...
if (c < 0x800) {
lastPos = i + 1;
out += hexTable[0xc0 | (c >> 6)] + hexTable[0x80 | (c & 0x3f)];
continue;
}
if (c < 0xd800 || c >= 0xe000) {
lastPos = i + 1;
out += hexTable[0xe0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
continue;
}
// Surrogate pair
++i;
if (i >= str.length) throw new errors.URIError("ERR_INVALID_URI");
var c2 = str.charCodeAt(i) & 0x3ff;
lastPos = i + 1;
c = 0x10000 + (((c & 0x3ff) << 10) | c2);
out += hexTable[0xf0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3f)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
}
if (lastPos === 0) return str;
if (lastPos < str.length) return out + str.slice(lastPos);
return out;
}
function HttpRequest(method, url, headers, body) {
if (method === undefined) {
this.method = "";
} else {
this.method = method;
}
if (url === undefined) {
this.host = "";
this.uri = "";
this.query = {};
} else {
this.query = {};
var host, path;
var i = url.indexOf("://");
if (i !== -1) {
url = url.substr(i + 3);
}
var i = url.indexOf("?");
if (i !== -1) {
var query_str = url.substr(i + 1);
url = url.substr(0, i);
var spl = query_str.split("&");
for (var i in spl) {
var kv = spl[i];
var index = kv.indexOf("=");
var key, value;
if (index >= 0) {
key = kv.substr(0, index);
value = kv.substr(index + 1);
} else {
key = kv;
value = "";
}
if (key !== "") {
key = decodeURI(key);
value = decodeURI(value);
if (this.query[key] === undefined) {
this.query[key] = [value];
} else {
this.query[key].push(value);
}
}
}
}
var i = url.indexOf("/");
if (i === -1) {
host = url;
path = "/";
} else {
host = url.substr(0, i);
path = url.substr(i);
}
this.host = host;
this.uri = decodeURI(path);
}
if (headers === undefined) {
this.headers = {};
} else {
this.headers = headers;
}
if (body === undefined) {
this.body = "";
} else {
this.body = body;
}
}
function findHeader(r, header) {
for (var k in r.headers) {
if (k.toLowerCase() === header.toLowerCase()) {
return r.headers[k];
}
}
return null;
}
// Build a CanonicalRequest from a regular request string
//
// CanonicalRequest =
// HTTPRequestMethod + '\n' +
// CanonicalURI + '\n' +
// CanonicalQueryString + '\n' +
// CanonicalHeaders + '\n' +
// SignedHeaders + '\n' +
// HexEncode(Hash(RequestPayload))
function CanonicalRequest(r, signedHeaders) {
var hexencode = findHeader(r, HeaderContentSha256);
if (hexencode === null) {
var data = RequestPayload(r);
hexencode = crypto_wrapper.HexEncodeSHA256Hash(data);
}
return (
r.method +
"\n" +
CanonicalURI(r) +
"\n" +
CanonicalQueryString(r) +
"\n" +
CanonicalHeaders(r, signedHeaders) +
"\n" +
signedHeaders.join(";") +
"\n" +
hexencode
);
}
function CanonicalURI(r) {
var pattens = r.uri.split("/");
var uri = [];
for (var k in pattens) {
var v = pattens[k];
uri.push(urlEncode(v));
}
var urlpath = uri.join("/");
if (urlpath[urlpath.length - 1] !== "/") {
urlpath = urlpath + "/";
}
//r.uri = urlpath
return urlpath;
}
function CanonicalQueryString(r) {
var keys = [];
for (var key in r.query) {
keys.push(key);
}
keys.sort();
var a = [];
for (var i in keys) {
var key = urlEncode(keys[i]);
var value = r.query[keys[i]];
if (Array.isArray(value)) {
value.sort();
for (var iv in value) {
a.push(key + "=" + urlEncode(value[iv]));
}
} else {
a.push(key + "=" + urlEncode(value));
}
}
return a.join("&");
}
function CanonicalHeaders(r, signedHeaders) {
var headers = {};
for (var key in r.headers) {
headers[key.toLowerCase()] = r.headers[key];
}
var a = [];
for (var i in signedHeaders) {
var value = headers[signedHeaders[i]];
a.push(signedHeaders[i] + ":" + value.trim());
}
return a.join("\n") + "\n";
}
function SignedHeaders(r) {
var a = [];
for (var key in r.headers) {
a.push(key.toLowerCase());
}
a.sort();
return a;
}
function RequestPayload(r) {
return r.body;
}
// Create a "String to Sign".
function StringToSign(canonicalRequest, t) {
var bytes = crypto_wrapper.HexEncodeSHA256Hash(canonicalRequest);
return Algorithm + "\n" + t + "\n" + bytes;
}
// Create the HWS Signature.
function SignStringToSign(stringToSign, signingKey) {
return crypto_wrapper.hmacsha256(signingKey, stringToSign);
}
// Get the finalized value for the "Authorization" header. The signature
// parameter is the output from SignStringToSign
function AuthHeaderValue(signature, Key, signedHeaders) {
return Algorithm + " Access=" + Key + ", SignedHeaders=" + signedHeaders.join(";") + ", Signature=" + signature;
}
function twoChar(s) {
if (s >= 10) {
return "" + s;
} else {
return "0" + s;
}
}
function getTime() {
var date = new Date();
return (
"" +
date.getUTCFullYear() +
twoChar(date.getUTCMonth() + 1) +
twoChar(date.getUTCDate()) +
"T" +
twoChar(date.getUTCHours()) +
twoChar(date.getUTCMinutes()) +
twoChar(date.getUTCSeconds()) +
"Z"
);
}
function Signer() {
this.Key = "";
this.Secret = "";
}
Signer.prototype.Sign = function (r) {
var headerTime = findHeader(r, HeaderXDate);
if (headerTime === null) {
headerTime = getTime();
r.headers[HeaderXDate] = headerTime;
}
if (r.method !== "PUT" && r.method !== "PATCH" && r.method !== "POST") {
r.body = "";
}
var queryString = CanonicalQueryString(r);
if (queryString !== "") {
queryString = "?" + queryString;
}
var options = {
hostname: r.host,
path: encodeURI(r.uri) + queryString,
method: r.method,
headers: r.headers,
};
if (findHeader(r, "host") === null) {
r.headers.host = r.host;
}
var signedHeaders = SignedHeaders(r);
var canonicalRequest = CanonicalRequest(r, signedHeaders);
var stringToSign = StringToSign(canonicalRequest, headerTime);
var signature = SignStringToSign(stringToSign, this.Secret);
options.headers[HeaderAuthorization] = AuthHeaderValue(signature, this.Key, signedHeaders);
return options;
};
return {
HttpRequest: HttpRequest,
Signer: Signer,
urlEncode: urlEncode,
findHeader: findHeader,
SignedHeaders: SignedHeaders,
CanonicalRequest: CanonicalRequest,
StringToSign: StringToSign,
};
});
@@ -1,10 +0,0 @@
var assert = require("assert");
var signer = require('./signer')
var s = ""
for (i = 0; i < 0x80; i++) {
s = s + signer.urlEncode(String.fromCharCode(i))
}
console.log(s)
assert.equal(s, "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F")
@@ -1,58 +0,0 @@
import { Signer, SigHttpRequest } from './signer';
import { HuaweiAccess } from '../access';
import axios from 'axios';
import { logger } from '@certd/pipeline';
export type ApiRequestOptions = {
method: string;
url: string;
headers?: any;
data?: any;
};
export class HuaweiYunClient {
access: HuaweiAccess;
constructor(access: HuaweiAccess) {
this.access = access;
}
async request(options: ApiRequestOptions) {
const sig = new Signer(
this.access.accessKeyId,
this.access.accessKeySecret
);
//The following example shows how to set the request URL and parameters to query a VPC list.
//Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
//Set request host.
//Set request URI.
//Set parameters for the request URL.
let body = undefined;
if (options.data) {
body = JSON.stringify(options.data);
}
const r = new SigHttpRequest(
options.method,
options.url,
options.headers,
body
);
//Add header parameters, for example, x-domain-id for invoking a global service and x-project-id for invoking a project-level service.
r.headers = { 'Content-Type': 'application/json' };
//Add a body if you have specified the PUT or POST method. Special characters, such as the double quotation mark ("), contained in the body must be escaped.
// r.body = option;
const opt = sig.Sign(r);
try {
const res = await axios.request({
url: options.url,
method: options.method,
headers: opt.headers,
data: body,
});
return res.data;
} catch (e: any) {
logger.error('华为云接口请求出错:', e?.response?.data);
const error: any = new Error(e?.response?.data.message);
error.code = e?.response?.code;
throw error;
}
}
}
@@ -1,476 +0,0 @@
import crypto from 'crypto';
function hmacsha256(keyByte: any, message: any) {
return crypto
.createHmac('SHA256', keyByte)
.update(message)
.digest()
.toString('hex');
}
function HexEncodeSHA256Hash(body: any) {
return crypto.createHash('SHA256').update(body).digest().toString('hex');
}
const Algorithm = 'SDK-HMAC-SHA256';
const HeaderXDate = 'X-Sdk-Date';
const HeaderAuthorization = 'Authorization';
const HeaderContentSha256 = 'x-sdk-content-sha256';
const hexTable = new Array(256);
for (let i = 0; i < 256; ++i)
hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
const noEscape = [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 0 - 15
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 16 - 31
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
0, // 32 - 47
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
0, // 48 - 63
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1, // 64 - 79
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
1, // 80 - 95
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1, // 96 - 111
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
1,
0, // 112 - 127
];
// function urlEncode is based on https://github.com/nodejs/node/blob/master/lib/querystring.js
// Copyright Joyent, Inc. and other Node contributors.
function urlEncode(str: any) {
if (typeof str !== 'string') {
if (typeof str === 'object') str = String(str);
else str += '';
}
let out = '';
let lastPos = 0;
for (let i = 0; i < str.length; ++i) {
let c = str.charCodeAt(i);
// ASCII
if (c < 0x80) {
if (noEscape[c] === 1) continue;
if (lastPos < i) out += str.slice(lastPos, i);
lastPos = i + 1;
out += hexTable[c];
continue;
}
if (lastPos < i) out += str.slice(lastPos, i);
// Multi-byte characters ...
if (c < 0x800) {
lastPos = i + 1;
out += hexTable[0xc0 | (c >> 6)] + hexTable[0x80 | (c & 0x3f)];
continue;
}
if (c < 0xd800 || c >= 0xe000) {
lastPos = i + 1;
out +=
hexTable[0xe0 | (c >> 12)] +
hexTable[0x80 | ((c >> 6) & 0x3f)] +
hexTable[0x80 | (c & 0x3f)];
continue;
}
// Surrogate pair
++i;
if (i >= str.length) throw new Error('ERR_INVALID_URI');
const c2 = str.charCodeAt(i) & 0x3ff;
lastPos = i + 1;
c = 0x10000 + (((c & 0x3ff) << 10) | c2);
out +=
hexTable[0xf0 | (c >> 18)] +
hexTable[0x80 | ((c >> 12) & 0x3f)] +
hexTable[0x80 | ((c >> 6) & 0x3f)] +
hexTable[0x80 | (c & 0x3f)];
}
if (lastPos === 0) return str;
if (lastPos < str.length) return out + str.slice(lastPos);
return out;
}
function findHeader(r: any, header: any) {
for (const k in r.headers) {
if (k.toLowerCase() === header.toLowerCase()) {
return r.headers[k];
}
}
return null;
}
// Build a CanonicalRequest from a regular request string
//
// CanonicalRequest =
// HTTPRequestMethod + '\n' +
// CanonicalURI + '\n' +
// CanonicalQueryString + '\n' +
// CanonicalHeaders + '\n' +
// SignedHeaders + '\n' +
// HexEncode(Hash(RequestPayload))
function CanonicalRequest(r: any, signedHeaders: any) {
let hexencode = findHeader(r, HeaderContentSha256);
if (hexencode === null) {
const data = RequestPayload(r);
hexencode = HexEncodeSHA256Hash(data);
}
return (
r.method +
'\n' +
CanonicalURI(r) +
'\n' +
CanonicalQueryString(r) +
'\n' +
CanonicalHeaders(r, signedHeaders) +
'\n' +
signedHeaders.join(';') +
'\n' +
hexencode
);
}
function CanonicalURI(r: any) {
const pattens = r.uri.split('/');
const uri = [];
for (const k in pattens) {
const v = pattens[k];
uri.push(urlEncode(v));
}
let urlpath = uri.join('/');
if (urlpath[urlpath.length - 1] !== '/') {
urlpath = urlpath + '/';
}
//r.uri = urlpath
return urlpath;
}
function CanonicalQueryString(r: any) {
const keys = [];
for (const key in r.query) {
keys.push(key);
}
keys.sort();
const a = [];
for (const i in keys) {
const key = urlEncode(keys[i]);
const value = r.query[keys[i]];
if (Array.isArray(value)) {
value.sort();
for (const iv in value) {
a.push(key + '=' + urlEncode(value[iv]));
}
} else {
a.push(key + '=' + urlEncode(value));
}
}
return a.join('&');
}
function CanonicalHeaders(r: any, signedHeaders: any) {
const headers: any = {};
for (const key in r.headers) {
headers[key.toLowerCase()] = r.headers[key];
}
const a = [];
for (const i in signedHeaders) {
const value = headers[signedHeaders[i]];
a.push(signedHeaders[i] + ':' + value.trim());
}
return a.join('\n') + '\n';
}
function SignedHeaders(r: any) {
const a = [];
for (const key in r.headers) {
a.push(key.toLowerCase());
}
a.sort();
return a;
}
function RequestPayload(r: any) {
return r.body;
}
// Create a "String to Sign".
function StringToSign(canonicalRequest: any, t: any) {
const bytes = HexEncodeSHA256Hash(canonicalRequest);
return Algorithm + '\n' + t + '\n' + bytes;
}
// Create the HWS Signature.
function SignStringToSign(stringToSign: any, signingKey: any) {
return hmacsha256(signingKey, stringToSign);
}
// Get the finalized value for the "Authorization" header. The signature
// parameter is the output from SignStringToSign
function AuthHeaderValue(signature: any, Key: any, signedHeaders: any) {
return (
Algorithm +
' Access=' +
Key +
', SignedHeaders=' +
signedHeaders.join(';') +
', Signature=' +
signature
);
}
function twoChar(s: any) {
if (s >= 10) {
return '' + s;
} else {
return '0' + s;
}
}
function getTime() {
const date = new Date();
return (
'' +
date.getUTCFullYear() +
twoChar(date.getUTCMonth() + 1) +
twoChar(date.getUTCDate()) +
'T' +
twoChar(date.getUTCHours()) +
twoChar(date.getUTCMinutes()) +
twoChar(date.getUTCSeconds()) +
'Z'
);
}
export class SigHttpRequest {
method = '';
host = '';
uri = '';
query: any = {};
headers: any = {};
body = '';
constructor(method: any, url: any, headers: any, body: any) {
if (method === undefined) {
this.method = '';
} else {
this.method = method;
}
if (url === undefined) {
this.host = '';
this.uri = '';
this.query = {};
} else {
this.query = {};
let host, path;
let i = url.indexOf('://');
if (i !== -1) {
url = url.substr(i + 3);
}
i = url.indexOf('?');
if (i !== -1) {
const query_str = url.substr(i + 1);
url = url.substr(0, i);
const spl = query_str.split('&');
for (const i in spl) {
const kv = spl[i];
const index = kv.indexOf('=');
let key, value;
if (index >= 0) {
key = kv.substr(0, index);
value = kv.substr(index + 1);
} else {
key = kv;
value = '';
}
if (key !== '') {
key = decodeURI(key);
value = decodeURI(value);
if (this.query[key] === undefined) {
this.query[key] = [value];
} else {
this.query[key].push(value);
}
}
}
}
i = url.indexOf('/');
if (i === -1) {
host = url;
path = '/';
} else {
host = url.substr(0, i);
path = url.substr(i);
}
this.host = host;
this.uri = decodeURI(path);
}
if (headers === undefined) {
this.headers = {};
} else {
this.headers = headers;
}
if (body === undefined) {
this.body = '';
} else {
this.body = body;
}
}
}
export class Signer {
Key = '';
Secret = '';
constructor(Key: any, Secret: any) {
this.Key = Key;
this.Secret = Secret;
}
Sign(r: any) {
let headerTime = findHeader(r, HeaderXDate);
if (headerTime === null) {
headerTime = getTime();
r.headers[HeaderXDate] = headerTime;
}
if (r.method !== 'PUT' && r.method !== 'PATCH' && r.method !== 'POST') {
r.body = '';
}
let queryString = CanonicalQueryString(r);
if (queryString !== '') {
queryString = '?' + queryString;
}
const options = {
hostname: r.host,
path: encodeURI(r.uri) + queryString,
method: r.method,
headers: r.headers,
};
if (findHeader(r, 'host') === null) {
r.headers.host = r.host;
}
const signedHeaders = SignedHeaders(r);
const canonicalRequest = CanonicalRequest(r, signedHeaders);
const stringToSign = StringToSign(canonicalRequest, headerTime);
const signature = SignStringToSign(stringToSign, this.Secret);
options.headers[HeaderAuthorization] = AuthHeaderValue(
signature,
this.Key,
signedHeaders
);
return options;
}
}
@@ -1,2 +1,2 @@
export * from './dnspod-access';
export * from './tencent-access';
export * from './dnspod-access.js';
export * from './tencent-access.js';
@@ -5,8 +5,8 @@ import {
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import _ from 'lodash';
import { DnspodAccess } from '../access';
import * as _ from 'lodash-es';
import { DnspodAccess } from '../access/index.js';
@IsDnsProvider({
name: 'dnspod',
@@ -1 +1 @@
import './dnspod-dns-provider';
import './dnspod-dns-provider.js';
@@ -5,9 +5,8 @@ import {
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import { TencentAccess } from '../access';
import tencentcloud from 'tencentcloud-sdk-nodejs/index';
import TencentCloudSDKHttpException from 'tencentcloud-sdk-nodejs/tencentcloud/common/exception/tencent_cloud_sdk_exception';
import { TencentAccess } from '../access/index.js';
import * as tencentcloud from 'tencentcloud-sdk-nodejs';
const DnspodClient = tencentcloud.dnspod.v20210323.Client;
@IsDnsProvider({
@@ -73,11 +72,9 @@ export class TencentDnsProvider extends AbstractDnsProvider {
*/
return ret;
} catch (e: any) {
if (e instanceof TencentCloudSDKHttpException) {
if (e.code === 'InvalidParameter.DomainRecordExist') {
this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value);
return {};
}
if (e?.code === 'InvalidParameter.DomainRecordExist') {
this.logger.info('域名解析已存在,无需重复添加:', fullRecord, value);
return {};
}
throw e;
}
@@ -1,3 +1,3 @@
export * from './access';
export * from './plugin';
export * from './dns-provider';
export * from './access/index.js';
export * from './plugin/index.js';
export * from './dns-provider/index.js';
@@ -6,8 +6,8 @@ import {
RunStrategy,
TaskInput,
} from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs/index';
import { TencentAccess } from '../../access';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { TencentAccess } from '../../access/index.js';
import { CertInfo } from '@certd/plugin-cert';
@IsTaskPlugin({
@@ -7,8 +7,8 @@ import {
TaskInput,
utils,
} from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs/index';
import { TencentAccess } from '../../access';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { TencentAccess } from '../../access/index.js';
import dayjs from 'dayjs';
@IsTaskPlugin({
@@ -6,8 +6,8 @@ import {
TaskInput,
utils,
} from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs/index';
import { K8sClient } from '@certd/plugin-util';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { K8sClient } from '@certd/lib-k8s';
import dayjs from 'dayjs';
import { Logger } from 'log4js';
@@ -1,4 +1,4 @@
export * from './deploy-to-clb';
export * from './deploy-to-tke-ingress';
export * from './deploy-to-cdn';
export * from './upload-to-tencent';
export * from './deploy-to-clb/index.js';
export * from './deploy-to-tke-ingress/index.js';
export * from './deploy-to-cdn/index.js';
export * from './upload-to-tencent/index.js';
@@ -7,7 +7,7 @@ import {
TaskInput,
TaskOutput,
} from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs/index';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import dayjs from 'dayjs';
@IsTaskPlugin({