feat: 【破坏性更新】插件改为metadata加载模式,plugin-cert、plugin-lib包部分代码转移到certd-server中,影响自定义插件,需要修改相关import引用

ssh、aliyun、tencent、qiniu、oss等 access和client需要转移import
This commit is contained in:
xiaojunnuo
2025-12-31 17:01:37 +08:00
parent 9c26598831
commit a3fb24993d
312 changed files with 14321 additions and 597 deletions
@@ -0,0 +1,78 @@
import { getGlobalAgents, ILogger } from "@certd/basic";
export class AliyunClient {
client: any;
logger: ILogger;
agent: any;
useROAClient: boolean;
constructor(opts: { logger: ILogger; useROAClient?: boolean }) {
this.logger = opts.logger;
this.useROAClient = opts.useROAClient || false;
const agents = getGlobalAgents();
this.agent = agents.httpsAgent;
}
async getSdk() {
if (this.useROAClient) {
return await this.getROAClient();
}
const Core = await import("@alicloud/pop-core");
return Core.default;
}
async getROAClient() {
const Core = await import("@alicloud/pop-core");
console.log("aliyun sdk", Core);
// @ts-ignore
return Core.ROAClient;
}
async init(opts: any) {
const Core = await this.getSdk();
this.client = new Core(opts);
return this.client;
}
checkRet(ret: any) {
if (ret.Code != null && ret.Code !== "OK" && ret.Message !== "OK") {
throw new Error("执行失败:" + ret.Message);
}
}
async request(
name: string,
params: any,
requestOption: any = {
method: "POST",
formatParams: false,
}
) {
if (!this.useROAClient) {
requestOption.agent = this.agent;
}
const getNumberFromEnv = (key: string, defValue: number) => {
const value = process.env[key];
if (value) {
try {
return parseInt(value);
} catch (e: any) {
this.logger.error(`环境变量${key}设置错误,应该是一个数字,当前值为${value},将使用默认值:${defValue}`);
return defValue;
}
} else {
return defValue;
}
};
// 连接超时设置,仅对当前请求有效。
requestOption.connectTimeout = getNumberFromEnv("ALIYUN_CLIENT_CONNECT_TIMEOUT", 8000);
// 读超时设置,仅对当前请求有效。
requestOption.readTimeout = getNumberFromEnv("ALIYUN_CLIENT_READ_TIMEOUT", 8000);
const res = await this.client.request(name, params, requestOption);
this.checkRet(res);
return res;
}
}
@@ -0,0 +1,3 @@
export * from "./base-client.js";
export * from "./ssl-client.js";
export * from "./oss-client.js";
@@ -0,0 +1,87 @@
import { AliyunAccess } from "../access/index.js";
export class AliossClient {
access: AliyunAccess;
region: string;
bucket: string;
client: any;
constructor(opts: { access: AliyunAccess; bucket: string; region: string }) {
this.access = opts.access;
this.bucket = opts.bucket;
this.region = opts.region;
}
async init() {
if (this.client) {
return;
}
// @ts-ignore
const OSS = await import("ali-oss");
const ossClient = new OSS.default({
accessKeyId: this.access.accessKeyId,
accessKeySecret: this.access.accessKeySecret,
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: this.region,
//@ts-ignore
authorizationV4: true,
// yourBucketName填写Bucket名称。
bucket: this.bucket,
});
// oss
this.client = ossClient;
}
async doRequest(bucket: string, xml: string, params: any) {
await this.init();
params = this.client._bucketRequestParams("POST", bucket, {
...params,
});
params.content = xml;
params.mime = "xml";
params.successStatuses = [200];
const res = await this.client.request(params);
this.checkRet(res);
return res;
}
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error("执行失败:" + ret.Message);
}
}
async uploadFile(filePath: string, content: Buffer | string, timeout = 1000 * 60 * 60) {
await this.init();
return await this.client.put(filePath, content, {
timeout,
});
}
async removeFile(filePath: string) {
await this.init();
return await this.client.delete(filePath);
}
async downloadFile(key: string, savePath: string, timeout = 1000 * 60 * 60) {
await this.init();
return await this.client.get(key, savePath, {
timeout,
});
}
async listDir(dirKey: string) {
await this.init();
const res = await this.client.listV2({
prefix: dirKey,
// max-keys: 100,
// continuation-token: "token",
// delimiter: "/",
// marker: "marker",
// encoding-type: "url",
});
return res.objects;
}
}
@@ -0,0 +1,185 @@
import { ILogger } from "@certd/basic";
import { AliyunAccess } from "../access/index.js";
import { AliyunClient } from "./index.js";
export type AliyunCertInfo = {
crt: string; //fullchain证书
key: string; //私钥
};
export type AliyunSslClientOpts = {
access: AliyunAccess;
logger: ILogger;
endpoint?: string;
region?: string;
};
export type AliyunSslGetResourceListReq = {
cloudProduct: string;
};
export type AliyunSslCreateDeploymentJobReq = {
name: string;
jobType: string;
contactIds: string[];
resourceIds: string[];
certIds: string[];
};
export type AliyunSslUploadCertReq = {
name: string;
cert: AliyunCertInfo;
};
export type CasCertInfo = { certId: number; certName: string; certIdentifier: string; notAfter: number; casRegion: string };
export class AliyunSslClient {
opts: AliyunSslClientOpts;
logger: ILogger;
constructor(opts: AliyunSslClientOpts) {
this.opts = opts;
this.logger = opts.logger;
}
checkRet(ret: any) {
if (ret.Code != null) {
throw new Error("执行失败:" + ret.Message);
}
}
async getClient() {
const access = this.opts.access;
const client = new AliyunClient({ logger: this.opts.logger });
let endpoint = this.opts.endpoint || "cas.aliyuncs.com";
if (this.opts.endpoint == null && this.opts.region) {
if (this.opts.region === "cn-hangzhou") {
endpoint = "cas.aliyuncs.com";
} else {
endpoint = `cas.${this.opts.region}.aliyuncs.com`;
}
}
await client.init({
accessKeyId: access.accessKeyId,
accessKeySecret: access.accessKeySecret,
endpoint: `https://${endpoint}`,
apiVersion: "2020-04-07",
});
return client;
}
async getCertInfo(certId: number): Promise<CasCertInfo> {
const client = await this.getClient();
const params = {
CertId: certId,
};
const res = await client.request("GetUserCertificateDetail", params);
this.checkRet(res);
return {
certId: certId,
certName: res.Name,
certIdentifier: res.CertIdentifier,
notAfter: res.NotAfter,
casRegion: this.getCasRegionFromEndpoint(this.opts.endpoint),
};
}
async uploadCert(req: AliyunSslUploadCertReq) {
const client = await this.getClient();
const params = {
Name: req.name,
Cert: req.cert.crt,
Key: req.cert.key,
};
const requestOption = {
method: "POST",
};
this.opts.logger.info(`开始上传证书:${req.name}`);
const ret: any = await client.request("UploadUserCertificate", params, requestOption);
this.checkRet(ret);
this.opts.logger.info("证书上传成功:aliyunCertId=", ret.CertId);
//output
return ret.CertId;
}
async getResourceList(req: AliyunSslGetResourceListReq) {
const client = await this.getClient();
const params = {
CloudName: "aliyun",
CloudProduct: req.cloudProduct,
};
const requestOption = {
method: "POST",
formatParams: false,
};
const res = await client.request("ListCloudResources", params, requestOption);
this.checkRet(res);
return res;
}
async createDeploymentJob(req: AliyunSslCreateDeploymentJobReq) {
const client = await this.getClient();
const params = {
Name: req.name,
JobType: req.jobType,
ContactIds: req.contactIds.join(","),
ResourceIds: req.resourceIds.join(","),
CertIds: req.certIds.join(","),
};
const requestOption = {
method: "POST",
formatParams: false,
};
const res = await client.request("CreateDeploymentJob", params, requestOption);
this.checkRet(res);
return res;
}
async getContactList() {
const params = {};
const requestOption = {
method: "POST",
formatParams: false,
};
const client = await this.getClient();
const res = await client.request("ListContact", params, requestOption);
this.checkRet(res);
return res;
}
async doRequest(action: string, params: any, requestOption: any) {
const client = await this.getClient();
const res = await client.request(action, params, requestOption);
this.checkRet(res);
return res;
}
async deleteCert(certId: any) {
await this.doRequest("DeleteUserCertificate", { CertId: certId }, { method: "POST" });
}
getCasRegionFromEndpoint(endpoint: string) {
if (!endpoint) {
return "cn-hangzhou";
}
/**
* {value: 'cas.aliyuncs.com', label: '中国大陆'},
* {value: 'cas.ap-southeast-1.aliyuncs.com', label: '新加坡'},
* {value: 'cas.eu-central-1.aliyuncs.com', label: '德国(法兰克福)'},
*/
const region = endpoint.replace(".aliyuncs.com", "").replace("cas.", "");
if (region === "cas") {
return "cn-hangzhou";
}
return region;
}
}