From 3d9620abb055d9e73741729674facfcbe8a8cfa6 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Fri, 11 Apr 2025 23:39:40 +0800 Subject: [PATCH] =?UTF-8?q?refactor(plugin):=20=E9=87=8D=E6=9E=84=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=AE=9A=E4=B9=89=E5=92=8C=E5=AE=89=E8=A3=85=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新插件配置格式,增加依赖库和插件类型字段 - 修改插件安装流程,支持安装依赖插件和第三方库 - 优化插件列表过滤逻辑,按类型筛选插件 - 调整 Dockerfile,使用 Node.js22 镜像并更新 pnpm 安装方式 --- .github/workflows/build-image.yml | 2 +- packages/core/pipeline/src/plugin/api.ts | 2 + packages/ui/Dockerfile | 6 +- .../ui/certd-client/src/utils/util.common.ts | 7 +- .../src/views/sys/plugin/crud.tsx | 58 +++++- .../service/builtin-plugin-service.ts | 4 + .../modules/plugin/service/default-plugin.ts | 176 ++++++++++-------- .../modules/plugin/service/plugin-service.ts | 6 +- 8 files changed, 176 insertions(+), 85 deletions(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index d4d4c22f..c3866f71 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -44,7 +44,7 @@ jobs: # cache: 'npm' # working-directory: ./packages/ui/certd-client - run: | - npm install -g pnpm@8.15.7 + npm install -g pnpm pnpm install npm run build working-directory: ./packages/ui/certd-client diff --git a/packages/core/pipeline/src/plugin/api.ts b/packages/core/pipeline/src/plugin/api.ts index 93d085ef..20f5ff54 100644 --- a/packages/core/pipeline/src/plugin/api.ts +++ b/packages/core/pipeline/src/plugin/api.ts @@ -65,6 +65,8 @@ export type PluginDefine = Registrable & { }; needPlus?: boolean; showRunStrategy?: boolean; + pluginType?: string; //类型 + type?: string; //来源 }; export type ITaskPlugin = { diff --git a/packages/ui/Dockerfile b/packages/ui/Dockerfile index 9a98cbad..05e03c5c 100644 --- a/packages/ui/Dockerfile +++ b/packages/ui/Dockerfile @@ -1,16 +1,16 @@ -FROM node:20-alpine AS builder +FROM node:22-alpine AS builder WORKDIR /workspace/ COPY . /workspace/ # armv7 目前只能用node18, pnpm9不支持node18,所以pnpm只能用8.15.7版本 # https://github.com/nodejs/docker-node/issues/1946 -RUN npm install -g pnpm@8.15.7 +RUN npm install -g pnpm #RUN cd /workspace/certd-client && pnpm install && npm run build RUN cp /workspace/certd-client/dist/* /workspace/certd-server/public/ -rf RUN cd /workspace/certd-server && pnpm install && npm run build-on-docker -FROM node:20-alpine +FROM node:22-alpine EXPOSE 7001 EXPOSE 7002 RUN apk add --no-cache openssl diff --git a/packages/ui/certd-client/src/utils/util.common.ts b/packages/ui/certd-client/src/utils/util.common.ts index c1c83bde..afa2f7a3 100644 --- a/packages/ui/certd-client/src/utils/util.common.ts +++ b/packages/ui/certd-client/src/utils/util.common.ts @@ -32,7 +32,7 @@ export default { }, async sleep(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); + return new Promise(resolve => setTimeout(resolve, ms)); }, maxLength(str?: string, length = 100) { @@ -42,6 +42,9 @@ export default { return ""; }, transformLink(desc: string = "") { + if (!desc) { + return ""; + } return desc.replace(/\[(.*)\]\((.*)\)/g, '$1'); - } + }, }; diff --git a/packages/ui/certd-client/src/views/sys/plugin/crud.tsx b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx index 98ee8f79..33084de4 100644 --- a/packages/ui/certd-client/src/views/sys/plugin/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx @@ -241,7 +241,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat data: [ { label: "授权", value: "access" }, { label: "DNS", value: "dnsProvider" }, - { label: "部署插件", value: "plugin" }, + { label: "部署插件", value: "deploy" }, ], }), column: { @@ -279,10 +279,60 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, }, + "extra.dependLibs": { + title: "第三方依赖", + type: "text", + form: { + helper: "依赖的第三方库,package.dependencies的格式:name[:^version]", + component: { + name: "a-select", + mode: "tags", + allowClear: true, + open: false, + }, + }, + column: { + show: false, + }, + }, + "extra.dependPlugins": { + title: "插件依赖", + type: "text", + form: { + component: { + name: "a-select", + mode: "tags", + open: false, + allowClear: true, + }, + helper: "安装时会先安装依赖的插件,格式:[author/]pluginName[:version]", + }, + column: { + show: false, + }, + }, + "extra.showRunStrategy": { + title: "可修改运行策略", + type: "dict-switch", + dict: dict({ + data: [ + { value: false, label: "不可修改" }, + { value: true, label: "可修改" }, + ], + }), + form: { + value: false, + rules: [{ required: true }], + }, + column: { + width: 100, + align: "left", + show: false, + }, + }, "extra.default.strategy.runStrategy": { title: "运行策略", type: "dict-select", - dict: dict({ data: [ { value: 0, label: "正常运行" }, @@ -293,6 +343,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat value: 1, rules: [{ required: true }], helper: "默认运行策略", + show: compute(({ form }) => { + return form.extra.showRunStrategy; + }), }, column: { width: 100, @@ -300,6 +353,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat component: { color: "auto", }, + show: false, }, valueBuilder({ row }) { if (row.extra) { diff --git a/packages/ui/certd-server/src/modules/pipeline/service/builtin-plugin-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/builtin-plugin-service.ts index 7004e50b..ca1e791d 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/builtin-plugin-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/builtin-plugin-service.ts @@ -13,6 +13,10 @@ export class BuiltInPluginService { if (Plugin?.define?.deprecated) { continue; } + //@ts-ignore + if(Plugin.define?.type && Plugin.define?.type !== 'builtin'){ + continue; + } list.push({ ...Plugin.define, key }); } list = list.sort((a, b) => { diff --git a/packages/ui/certd-server/src/modules/plugin/service/default-plugin.ts b/packages/ui/certd-server/src/modules/plugin/service/default-plugin.ts index 248fc27e..e876aaf0 100644 --- a/packages/ui/certd-server/src/modules/plugin/service/default-plugin.ts +++ b/packages/ui/certd-server/src/modules/plugin/service/default-plugin.ts @@ -1,28 +1,36 @@ import yaml from "js-yaml"; -const CertOutputs = [ - "CertApply", - "CertApplyLego", - "CertApplyUpload" -]; +import { CertApplyPluginNames } from "@certd/plugin-cert"; + export function getDefaultAccessPlugin() { - const metadata = { - username: { - title: "用户名", - required: true, - encrypt: false - }, - password: { - title: "密码", - required: true, - encrypt: true - } - }; + const metadata = ` +input: + username: # 授权参数名 + title: 用户名 # 授权参数标题 + required: true # 是否必填项 + encrypt: false # 是否加密 + component: # 输入组件配置 + name: a-input #输入组件名称 + allowClear: true # 组件的参数,参考 https://www.antdv.com/components/input#api + password: + title: 密码 + required: true + encrypt: true + component: + name: a-input + allowClear: true - const script = `const { BaseAccess } = await import("@certd/pipeline") + +` + + const script = ` +# 必须使用 await import 来引入模块 +const { BaseAccess } = await import("@certd/pipeline") +# 需要返回一个继承BaseAccess的类 return class DemoAccess extends BaseAccess { -username; -password; + # 授权的字段,跟左边input一一对应 + username; + password; } `; return { @@ -32,82 +40,93 @@ password; } export function getDefaultDeployPlugin() { - const metadata = { - cert: { - title: "前置任务证书", - component: { - name: "output-selector", - from: [...CertOutputs] - }, - required: true - }, - certDomains: { - title: "当前证书域名", - component: { - name: "cert-domains-getter" - }, - mergeScript: ` - return { - component:{ - inputKey: ctx.compute(({form})=>{ - return form.cert - }), - } + + let certApplyNames = '' + for (const name of CertApplyPluginNames) { + certApplyNames += ` + - ${name}` + } + const metadata =` +input: # 插件的输入参数 + cert: + title: 前置任务证书 + helper: 请选择前置任务产生的证书 # 帮助说明 + component: + name: output-selector # 输入组件名称 + vModel: modelValue # 组件参数 + from:${certApplyNames} + 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 - } - }; + } + 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: +# +` + const script = ` +// 要用await来import模块 const { AbstractTaskPlugin } = await import("@certd/pipeline") +// 要返回一个继承AbstractTaskPlugin的class return class DemoTask extends AbstractTaskPlugin { + // 这里是插件的输入参数,对应左边的input配置 cert; certDomains; accessId; key1; key2; + // 编写执行方法 async execute(){ + # 根据accessId获取授权配置 const access = await this.accessService.getById(this.accessId) - this.logger.info("cert:",this.cert); + //必须使用this.logger打印日志 + // this.logger.info("cert:",this.cert); this.logger.info("certDomains:",this.certDomains); this.logger.info("access:",access); this.logger.info("key1:",this.key1); this.logger.info("key2:",this.key2); - //开始你的部署任务 - const res = await this.ctx.http.request({url:"xxxxxx"}) + // 开始你的部署任务 + // this.ctx里面有一些常用的方法类,比如utils、http、logger等 + const res = await this.ctx.http.request({url:"https://www.baidu.com"}) if(res.error){ //抛出异常,终止任务,否则将被判定为执行成功 throw new Error("部署失败:"+res.message) } - //必须使用this.logger打印日志 this.logger.info("执行成功") + // this.outputName = xxxx //设置输出参数,可以被其他插件选择使用 } } ` @@ -118,7 +137,14 @@ return class DemoTask extends AbstractTaskPlugin { } export function getDefaultDnsPlugin() { - const metadata = `accessType: aliyun #授权类型名称` + const metadata = ` +accessType: aliyun # 授权类型名称 +#dependPlugins: # 依赖第三方库,安装插件时会安装依赖库,尽量使用certd已安装的库,比如http、lodash-es、utils +# @alicloud/openapi-client: ^0.4.12 +#dependLibs: # 依赖的插件,应用商店安装时会先安装依赖插件 +# aliyun: * + + ` const script = ` const { AbstractDnsProvider } = await import("@certd/pipeline") diff --git a/packages/ui/certd-server/src/modules/plugin/service/plugin-service.ts b/packages/ui/certd-server/src/modules/plugin/service/plugin-service.ts index d75ab4a1..e99a8f7f 100644 --- a/packages/ui/certd-server/src/modules/plugin/service/plugin-service.ts +++ b/packages/ui/certd-server/src/modules/plugin/service/plugin-service.ts @@ -86,7 +86,9 @@ export class PluginService extends BaseService { }); const disabledNames = list.map(it => it.name); - return builtInList.filter(it => !disabledNames.includes(it.name)); + return builtInList.filter(it =>{ + return !disabledNames.includes(it.name) + }); } async getBuiltInEntityList() { @@ -253,7 +255,7 @@ export class PluginService extends BaseService { let registry = null; if (item.pluginType === "access") { registry = accessRegistry; - } else if (item.pluginType === "plugin") { + } else if (item.pluginType === "deploy") { registry = pluginRegistry; } else if (item.pluginType === "dnsProvider") { registry = dnsProviderRegistry;