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;