mirror of
https://github.com/certd/certd.git
synced 2026-04-24 04:17:25 +08:00
refactor: plugins
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extension": ["ts"],
|
||||
"spec": "test/**/*.test.ts",
|
||||
"require": "ts-node/register"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"printWidth": 160
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./src";
|
||||
@@ -0,0 +1,27 @@
|
||||
import { AbstractAccess, IsAccess } from "@certd/pipeline";
|
||||
|
||||
@IsAccess({
|
||||
name: "dnspod",
|
||||
title: "dnspod",
|
||||
desc: "腾讯云的域名解析接口已迁移到dnspod",
|
||||
input: {
|
||||
id: {
|
||||
title: "账户id",
|
||||
component: {
|
||||
placeholder: "dnspod接口账户id",
|
||||
},
|
||||
rules: [{ required: true, message: "该项必填" }],
|
||||
},
|
||||
token: {
|
||||
title: "token",
|
||||
component: {
|
||||
placeholder: "开放接口token",
|
||||
},
|
||||
rules: [{ required: true, message: "该项必填" }],
|
||||
},
|
||||
},
|
||||
})
|
||||
export class DnspodAccess extends AbstractAccess {
|
||||
token = "";
|
||||
id = "";
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./dnspod-access";
|
||||
export * from "./tencent-access";
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./access";
|
||||
export * from "./plugin";
|
||||
export * from "./dns-provider";
|
||||
@@ -0,0 +1,101 @@
|
||||
import { AbstractPlugin, IsTask, RunStrategy, TaskInput, TaskOutput, TaskPlugin } from "@certd/pipeline";
|
||||
import tencentcloud from "tencentcloud-sdk-nodejs/index";
|
||||
import { TencentAccess } from "../../access";
|
||||
|
||||
@IsTask(() => {
|
||||
return {
|
||||
name: "DeployCertToTencentCDN",
|
||||
title: "部署到腾讯云CDN",
|
||||
input: {
|
||||
domainName: {
|
||||
title: "cdn加速域名",
|
||||
rules: [{ required: true, message: "该项必填" }],
|
||||
},
|
||||
certName: {
|
||||
title: "证书名称",
|
||||
helper: "证书上传后将以此参数作为名称前缀",
|
||||
},
|
||||
cert: {
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "pi-output-selector",
|
||||
from: "CertApply",
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
accessId: {
|
||||
title: "Access提供者",
|
||||
helper: "access 授权",
|
||||
component: {
|
||||
name: "pi-access-selector",
|
||||
type: "tencent",
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
output: {},
|
||||
};
|
||||
})
|
||||
export class DeployToCdnPlugin extends AbstractPlugin implements TaskPlugin {
|
||||
async execute(input: TaskInput): Promise<TaskOutput> {
|
||||
const { cert, accessId } = input;
|
||||
const accessProvider: TencentAccess = (await this.accessService.getById(accessId)) as TencentAccess;
|
||||
const client = this.getClient(accessProvider);
|
||||
const params = this.buildParams(input, cert);
|
||||
await this.doRequest(client, params);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
getClient(accessProvider: TencentAccess) {
|
||||
const CdnClient = tencentcloud.cdn.v20180606.Client;
|
||||
|
||||
const clientConfig = {
|
||||
credential: {
|
||||
secretId: accessProvider.secretId,
|
||||
secretKey: accessProvider.secretKey,
|
||||
},
|
||||
region: "",
|
||||
profile: {
|
||||
httpProfile: {
|
||||
endpoint: "cdn.tencentcloudapi.com",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return new CdnClient(clientConfig);
|
||||
}
|
||||
|
||||
buildParams(props: TaskInput, cert: any) {
|
||||
const { domainName } = props;
|
||||
return {
|
||||
Https: {
|
||||
Switch: "on",
|
||||
CertInfo: {
|
||||
Certificate: cert.crt,
|
||||
PrivateKey: cert.key,
|
||||
},
|
||||
},
|
||||
Domain: domainName,
|
||||
};
|
||||
}
|
||||
|
||||
async doRequest(client: any, params: any) {
|
||||
const ret = await client.UpdateDomainConfig(params);
|
||||
this.checkRet(ret);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./deploy-to-clb";
|
||||
export * from "./deploy-to-tke-ingress";
|
||||
export * from "./deploy-to-cdn";
|
||||
export * from "./upload-to-tencent";
|
||||
@@ -0,0 +1,58 @@
|
||||
export const fakeCrt = `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
AHxTaXliTVvS83dogw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw
|
||||
GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2
|
||||
MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw
|
||||
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0
|
||||
8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym
|
||||
oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0
|
||||
ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN
|
||||
xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56
|
||||
dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9
|
||||
AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw
|
||||
HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0
|
||||
BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu
|
||||
b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu
|
||||
Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF
|
||||
UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9
|
||||
AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp
|
||||
DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7
|
||||
IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf
|
||||
zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI
|
||||
PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w
|
||||
SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em
|
||||
2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0
|
||||
WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt
|
||||
n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=
|
||||
-----END CERTIFICATE-----`;
|
||||
@@ -0,0 +1,11 @@
|
||||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { EchoPlugin } from "../src/plugin";
|
||||
describe("task_plugin", function () {
|
||||
it("#taskplugin", function () {
|
||||
const echoPlugin = new EchoPlugin();
|
||||
const define = echoPlugin.define;
|
||||
echoPlugin.execute({ context: {}, props: { test: 111 } });
|
||||
expect(define.name).eq("EchoPlugin");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { IAccessService } from "../../src/access/access-service";
|
||||
import { AbstractAccess, HostAccess } from "../../src";
|
||||
import { aliyunSecret } from "../user.secret";
|
||||
export class AccessServiceTest implements IAccessService {
|
||||
async getById(id: any): Promise<AbstractAccess> {
|
||||
return {
|
||||
...aliyunSecret,
|
||||
} as HostAccess;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ContextFactory } from "../../src/core/context";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { logger } from "../../src/utils/util.log";
|
||||
|
||||
const contextFactory = new ContextFactory(new FileStorage());
|
||||
|
||||
const userContext = contextFactory.getContext("user", "test");
|
||||
const pipelineContext = contextFactory.getContext("pipeline", "test");
|
||||
export const pluginInitProps = {
|
||||
accessService: new AccessServiceTest(),
|
||||
pipelineContext: pipelineContext,
|
||||
userContext: userContext,
|
||||
logger: logger,
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { ConcurrencyStrategy, NextStrategy, Pipeline, RunStrategy } from "../../src";
|
||||
|
||||
let idIndex = 0;
|
||||
function generateId() {
|
||||
idIndex++;
|
||||
return idIndex + "";
|
||||
}
|
||||
export const pipeline: Pipeline = {
|
||||
version: 1,
|
||||
id: generateId(),
|
||||
title: "测试管道",
|
||||
userId: 1,
|
||||
triggers: [],
|
||||
stages: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "证书申请阶段",
|
||||
concurrency: ConcurrencyStrategy.Serial,
|
||||
next: NextStrategy.AllSuccess,
|
||||
tasks: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "申请证书任务",
|
||||
steps: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "申请证书",
|
||||
type: "CertApply",
|
||||
input: {
|
||||
domains: ["*.docmirror.cn"],
|
||||
email: "xiaojunnuo@qq.com",
|
||||
dnsProviderType: "aliyun",
|
||||
accessId: "111",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: generateId(),
|
||||
title: "证书部署阶段",
|
||||
concurrency: ConcurrencyStrategy.Serial,
|
||||
next: NextStrategy.AllSuccess,
|
||||
tasks: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "测试输出参数任务",
|
||||
steps: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "输出参数(echo插件)",
|
||||
type: "EchoPlugin",
|
||||
input: {
|
||||
cert: "cert",
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
//import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { Executor, RunHistory } from "../../src";
|
||||
import { pipeline } from "./pipeline.define";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
describe("pipeline", function () {
|
||||
it("#pipeline", async function () {
|
||||
this.timeout(120000);
|
||||
function onChanged(history: RunHistory) {
|
||||
console.log("changed:");
|
||||
}
|
||||
|
||||
const executor = new Executor({ userId: "test", pipeline, onChanged, accessService: new AccessServiceTest(), storage: new FileStorage() });
|
||||
await executor.run(1, "user");
|
||||
// expect(define.name).eq("EchoPlugin");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { CertApplyPlugin } from "../../../src/plugin";
|
||||
import { pluginInitProps } from "../init.test";
|
||||
describe("CertApply", function () {
|
||||
it("#execute", async function () {
|
||||
this.timeout(120000);
|
||||
const plugin = new CertApplyPlugin();
|
||||
// @ts-ignore
|
||||
delete plugin.define;
|
||||
await plugin.doInit(pluginInitProps);
|
||||
const output = await plugin.execute({
|
||||
domains: ["*.docmirror.cn", "docmirror.cn"],
|
||||
email: "xiaojunnuo@qq.com",
|
||||
dnsProviderType: "aliyun",
|
||||
accessId: "111",
|
||||
forceUpdate: true,
|
||||
});
|
||||
const cert = output.cert;
|
||||
expect(plugin.getDefine().name).eq("CertApply");
|
||||
expect(cert.crt != null).eq(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { DeployCertToAliyunCDN } from "../../../src/plugin";
|
||||
import { pluginInitProps } from "../init.test";
|
||||
|
||||
describe("DeployToAliyunCDN", function () {
|
||||
it("#execute", async function () {
|
||||
this.timeout(120000);
|
||||
const plugin = new DeployCertToAliyunCDN();
|
||||
// @ts-ignore
|
||||
delete plugin.define;
|
||||
|
||||
await plugin.doInit(pluginInitProps);
|
||||
|
||||
const cert = await pluginInitProps.pipelineContext.get("cert");
|
||||
|
||||
await plugin.execute({
|
||||
cert,
|
||||
domainName: "certd-cdn-upload.docmirror.cn",
|
||||
});
|
||||
expect(plugin.getDefine().name).eq("DeployCertToAliyunCDN");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue","test/**/*.ts"],
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { defineConfig } from "vite";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [],
|
||||
build: {
|
||||
lib: {
|
||||
entry: "src/index.ts",
|
||||
name: "pipeline",
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ["vue", "lodash-es", "dayjs", "@fast-crud/fast-crud", "log4js", "lodash", "@certd/pipeline", "axios"],
|
||||
output: {
|
||||
// Provide global variables to use in the UMD build
|
||||
// for externalized deps
|
||||
globals: {
|
||||
vue: "Vue",
|
||||
"lodash-es": "_",
|
||||
lodash: "_",
|
||||
dayjs: "dayjs",
|
||||
"@fast-crud/fast-crud": "FastCrud",
|
||||
log4js: "log4js",
|
||||
"@certd/pipeline": "pipeline",
|
||||
axios: "axios",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user