mirror of https://github.com/certd/certd
perf: 支持上传证书到华为云CCM
parent
75c4f9dea8
commit
cfd3b66be9
|
@ -0,0 +1,53 @@
|
|||
// 扫描目录,列出文件,然后加载为模块
|
||||
|
||||
import { join } from 'path';
|
||||
import fs from 'fs'
|
||||
import { pathToFileURL } from "node:url";
|
||||
import path from 'path'
|
||||
function scanDir(dir) {
|
||||
const files = fs.readdirSync(dir);
|
||||
const result = [];
|
||||
// 扫描目录及子目录
|
||||
for (const file of files) {
|
||||
if (file.includes("index.js")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const filePath = join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
result.push(...scanDir(filePath));
|
||||
} else {
|
||||
if (!file.endsWith(".js")) {
|
||||
continue;
|
||||
}
|
||||
result.push(filePath);
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default async function loadModules(dir) {
|
||||
const files = scanDir(dir);
|
||||
const modules = {}
|
||||
for (const file of files) {
|
||||
|
||||
try {
|
||||
// 转换为 file:// URL(Windows 必需)
|
||||
const moduleUrl = pathToFileURL(file).href
|
||||
const module = await import(moduleUrl)
|
||||
|
||||
// 如果模块有默认导出,优先使用
|
||||
modules[file] = module.default || module
|
||||
} catch (err) {
|
||||
console.error(`加载模块 ${file} 失败:`, err)
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
const modules = await loadModules('./dist/plugins');
|
||||
|
||||
for (const key in modules) {
|
||||
console.log(key)
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//@ts-ignore
|
||||
import { HcClient } from "@huaweicloud/huaweicloud-sdk-core/HcClient";
|
||||
|
||||
export class HuaweiCcmClient {
|
||||
//@ts-ignore
|
||||
hcClient: HcClient;
|
||||
|
||||
//@ts-ignore
|
||||
constructor(client: HcClient) {
|
||||
this.hcClient = client;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
importCertificate(req: {
|
||||
name: string,
|
||||
certificate: string,
|
||||
private_key: string,
|
||||
duplicate_check: boolean,
|
||||
}) {
|
||||
const options: any = {
|
||||
method: "POST",
|
||||
url: "/v3/scm/certificates/import",
|
||||
pathParams: {},
|
||||
queryParams: {},
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
/**
|
||||
* name
|
||||
* string 是
|
||||
* 证书名称。字符长度为3~63位, 请输入英文字符,数字,下划线,中划线,英文句点。
|
||||
*
|
||||
* certificate
|
||||
* string 是
|
||||
* 证书内容,可包含中间证书及根证书。若certificate_chain字段传入证书链,则该字段只取证书本身。回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* certificate_chain
|
||||
* string 否
|
||||
* 证书链,非必填,可通过certificate字段传入。回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* private_key
|
||||
* string 是
|
||||
* 证书私钥。
|
||||
* 不能上传带有口令保护的私钥,回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* duplicate_check
|
||||
*/
|
||||
data: {
|
||||
...req
|
||||
}
|
||||
|
||||
};
|
||||
// @ts-ignore
|
||||
options["responseHeaders"] = ["X-Request-Id"];
|
||||
return this.hcClient.sendRequest(options);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
name: HuaweiUploadToCCM
|
||||
title: 华为-上传证书至CCM
|
||||
desc: 上传证书至华为云CCM
|
||||
type: plugin
|
||||
pluginType: deploy
|
||||
author: certd
|
||||
version: 1.0.0
|
||||
icon: 'svg:icon-huawei'
|
||||
group: huawei
|
||||
default:
|
||||
strategy:
|
||||
runStrategy: 1,
|
||||
input: # 插件的输入参数
|
||||
cert:
|
||||
title: 前置任务证书
|
||||
helper: 请选择前置任务产生的证书 # 帮助说明
|
||||
component:
|
||||
name: output-selector # 输入组件名称
|
||||
vModel: modelValue # 组件参数
|
||||
from:
|
||||
- ApplyCert
|
||||
- ApplyCertLego
|
||||
- ApplyCertUpload
|
||||
required: true
|
||||
certDomains:
|
||||
title: 当前证书域名
|
||||
component:
|
||||
name: cert-domains-getter
|
||||
mergeScript: |
|
||||
return {
|
||||
component:{
|
||||
inputKey: ctx.compute(({form})=>{
|
||||
return form.cert
|
||||
}),
|
||||
}
|
||||
}
|
||||
required: true
|
||||
accessId:
|
||||
title: Access授权
|
||||
helper: xxxx的授权
|
||||
component:
|
||||
name: access-selector # 授权选择组件名称
|
||||
type: aliyun # 授权类型
|
||||
required: true
|
||||
key1:
|
||||
title: 输入示例1
|
||||
required: false
|
||||
key2:
|
||||
title: 可选项
|
||||
component:
|
||||
name: a-select
|
||||
vMode: value
|
||||
options:
|
||||
- value: "1"
|
||||
label: 选项1
|
||||
- value: "2"
|
||||
label: 选项2
|
||||
required: false
|
||||
#output: # 输出参数,一般插件都不需要配置此项
|
||||
# outputName:
|
||||
#
|
|
@ -0,0 +1,82 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||
import { HuaweiAccess } from "../../access/index.js";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { createCertDomainGetterInputDefine } from "@certd/plugin-lib";
|
||||
import { resetLogConfigure } from "@certd/basic";
|
||||
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'HauweiUploadToCCM',
|
||||
title: '华为云-上传证书至CCM',
|
||||
icon: 'svg:icon-huawei',
|
||||
group: pluginGroups.huawei.key,
|
||||
desc: '上传证书到华为云CCM',
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
})
|
||||
export class HauweiUploadToCCM extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames]
|
||||
},
|
||||
required: true
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: "Access授权",
|
||||
helper: "华为云授权AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "huawei"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
accessId!: string;
|
||||
@TaskOutput({
|
||||
title: '华为云CertId',
|
||||
})
|
||||
huaweiCertId!: string;
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info("开始部署证书到华为云CCM");
|
||||
const { client } = await this.getCcmClient();
|
||||
|
||||
const res = await client.importCertificate({
|
||||
name: this.appendTimeSuffix("certd"),
|
||||
certificate: this.cert.crt,
|
||||
private_key: this.cert.key,
|
||||
duplicate_check: false
|
||||
});
|
||||
this.huaweiCertId = res.certificate_id;
|
||||
this.logger.info(`上传证书到华为云ccm完成,certificate_id:${this.huaweiCertId}`);
|
||||
}
|
||||
|
||||
async getCcmClient() {
|
||||
const access = await this.getAccess<HuaweiAccess>(this.accessId);
|
||||
const { BasicCredentials } = await import("@huaweicloud/huaweicloud-sdk-core");
|
||||
const { ClientBuilder } = await import("@huaweicloud/huaweicloud-sdk-core/ClientBuilder.js");
|
||||
//@ts-ignore
|
||||
const {HuaweiCcmClient} = await import("./ccm-client.js")
|
||||
|
||||
//恢复华为云把log4j的config改了的问题
|
||||
resetLogConfigure();
|
||||
|
||||
const credentials = new BasicCredentials().withAk(access.accessKeyId).withSk(access.accessKeySecret);
|
||||
const client = new ClientBuilder((hcClient) => {
|
||||
return new HuaweiCcmClient(hcClient);
|
||||
}).withCredential(credentials).withEndpoint("https://scm.cn-north-4.myhuaweicloud.com").build();
|
||||
return {
|
||||
client
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue