Compare commits

...

75 Commits

Author SHA1 Message Date
xiaojunnuo
e5da46cfc3 v1.22.2 2024-07-24 02:25:12 +08:00
xiaojunnuo
eabb3e38b5 chore: 2024-07-24 02:24:37 +08:00
xiaojunnuo
46140c8efa build: prepare to build 2024-07-24 02:24:04 +08:00
xiaojunnuo
95d071ba56 chore: 2024-07-24 02:23:09 +08:00
xiaojunnuo
3c9c3ca3b0 build: prepare to build 2024-07-24 02:19:05 +08:00
xiaojunnuo
e7c4ade57d build: prepare to build 2024-07-24 02:18:13 +08:00
xiaojunnuo
ca524657b6 build: prepare to build 2024-07-24 02:17:12 +08:00
xiaojunnuo
bc02559bc7 chore: 2024-07-24 02:17:06 +08:00
xiaojunnuo
741172fd98 chore: 2024-07-24 02:16:12 +08:00
xiaojunnuo
83d0209775 chore: 2024-07-24 02:11:38 +08:00
xiaojunnuo
6693d1acfb chore: 2024-07-24 00:42:50 +08:00
xiaojunnuo
a2c43b50a6 fix: 修复创建流水线时,无法根据dns类型默认正确的dns授权的bug
Closes https://github.com/certd/certd/issues/97
2024-07-24 00:42:33 +08:00
xiaojunnuo
f7fc06e657 chore: 2024-07-23 23:39:13 +08:00
xiaojunnuo
b9fe3b9c87 chore: github action build image 2024-07-23 23:23:45 +08:00
xiaojunnuo
06be993afc chore: github action build image 2024-07-23 23:16:55 +08:00
xiaojunnuo
b6ef39fb30 chore: github action build image 2024-07-23 23:12:50 +08:00
xiaojunnuo
0b131c00ed chore: github action build image 2024-07-23 23:06:11 +08:00
xiaojunnuo
b6b8661c36 chore: github action build image 2024-07-23 23:03:15 +08:00
xiaojunnuo
7bf19f8f6f chore: github action build image 2024-07-23 23:00:56 +08:00
xiaojunnuo
c9d9c6513b chore: github action build image 2024-07-23 22:59:23 +08:00
xiaojunnuo
4e7b7ae974 chore: github action build image 2024-07-23 22:57:55 +08:00
xiaojunnuo
dfcabc02a4 chore: github action build image 2024-07-23 22:56:16 +08:00
xiaojunnuo
6f2c5674c9 chore: github action build image 2024-07-23 22:54:23 +08:00
xiaojunnuo
2877b9b505 chore: github action build image 2024-07-23 22:52:56 +08:00
xiaojunnuo
e40bb9e14d chore: github action build image 2024-07-23 22:50:15 +08:00
xiaojunnuo
d456ff9830 chore: github action build image 2024-07-23 22:48:30 +08:00
xiaojunnuo
ffddb3b4ac chore: github action build image 2024-07-23 22:40:05 +08:00
xiaojunnuo
a6113f237b chore: 2024-07-23 22:38:38 +08:00
xiaojunnuo
093520b686 chore: 2024-07-23 22:37:32 +08:00
xiaojunnuo
72bff652f7 chore: github action build 2024-07-23 13:30:36 +08:00
xiaojunnuo
9559bdf817 chore: github action build 2024-07-23 13:27:17 +08:00
xiaojunnuo
5a88b8c24e chore: github action build 2024-07-23 12:44:42 +08:00
xiaojunnuo
a9ebac82c7 chore: github action build 2024-07-23 12:43:10 +08:00
xiaojunnuo
cfd8836083 chore: github action build 2024-07-23 12:42:48 +08:00
xiaojunnuo
e01e59b188 chore: github action build 2024-07-23 12:41:36 +08:00
xiaojunnuo
d2fd729961 chore: github action build 2024-07-23 12:40:36 +08:00
xiaojunnuo
5d4ff2e3b7 chore: github action build 2024-07-23 12:39:03 +08:00
xiaojunnuo
6e5133f6b8 chore: github action build 2024-07-23 12:37:21 +08:00
xiaojunnuo
a96d5839b2 chore: github action build 2024-07-23 12:35:24 +08:00
xiaojunnuo
a827bc306a chore: 2024-07-21 03:21:51 +08:00
xiaojunnuo
d8b3d7a6e0 v1.22.1 2024-07-21 03:11:54 +08:00
xiaojunnuo
b8f072909b build: prepare to build 2024-07-21 03:10:14 +08:00
xiaojunnuo
fa48f2b2f0 build: prepare to build 2024-07-21 03:07:32 +08:00
xiaojunnuo
019a1fe24e chore: 2024-07-21 03:02:13 +08:00
xiaojunnuo
427620d34f perf: 创建证书任务增加定时任务和邮件通知输入 2024-07-21 02:59:02 +08:00
xiaojunnuo
a5a0c1f6e7 perf: 支持配置启动后自动触发一次任务 2024-07-21 02:32:03 +08:00
xiaojunnuo
affef13037 perf: 创建证书任务可以选择lege插件 2024-07-21 02:26:03 +08:00
xiaojunnuo
4afbf20c1a chore: 重构image build 2024-07-20 19:38:15 +08:00
xiaojunnuo
0ef7b036dd chore: 1 2024-07-20 19:27:07 +08:00
xiaojunnuo
17ef7b8b9e chore: 1 2024-07-20 19:25:54 +08:00
xiaojunnuo
15eba52fad chore: 1 2024-07-20 19:25:45 +08:00
xiaojunnuo
f2d894b036 chore: 1 2024-07-20 18:39:51 +08:00
xiaojunnuo
d9da27710e chore: 1 2024-07-20 18:33:11 +08:00
xiaojunnuo
981bff70c3 chore: 1 2024-07-20 18:28:19 +08:00
xiaojunnuo
bb30d6e02f chore: 1 2024-07-20 18:18:34 +08:00
xiaojunnuo
b09ccda54d chore: 1 2024-07-20 18:17:48 +08:00
xiaojunnuo
a5de8d79ec chore: 1 2024-07-20 18:11:56 +08:00
xiaojunnuo
a092a1e843 chore: 1 2024-07-20 18:11:38 +08:00
xiaojunnuo
1c6740feff chore: sqlite换成better-sqlite 2024-07-20 18:07:32 +08:00
xiaojunnuo
79c6e05e02 chore: sqlite换成better-sqlite 2024-07-20 18:04:07 +08:00
xiaojunnuo
31e2085c16 chore: 1 2024-07-20 17:53:19 +08:00
xiaojunnuo
64fda2f1a0 chore: 1 2024-07-20 17:35:07 +08:00
xiaojunnuo
a674719a8b chore: 1 2024-07-20 17:27:12 +08:00
xiaojunnuo
2f7ef0620b chore: 1 2024-07-20 14:27:41 +08:00
xiaojunnuo
153e98b593 chore: 1 2024-07-20 14:26:01 +08:00
xiaojunnuo
d62ea41671 chore: 1 2024-07-20 10:17:38 +08:00
xiaojunnuo
8fcd9813d3 chore: 1 2024-07-20 10:11:05 +08:00
xiaojunnuo
dcbf8c85dd chore: 1 2024-07-20 10:09:18 +08:00
xiaojunnuo
ea0eafdb16 chore: 1 2024-07-20 10:05:39 +08:00
xiaojunnuo
eda89a057a chore: 1 2024-07-20 09:22:20 +08:00
xiaojunnuo
21e6eef1d3 chore: mv libs 2024-07-19 18:08:51 +08:00
xiaojunnuo
54a27c1840 chore: mv libs 2024-07-19 17:22:54 +08:00
xiaojunnuo
a3be0a1618 chore: 1 2024-07-19 16:01:55 +08:00
xiaojunnuo
8e19e44f4c chore: 1 2024-07-19 15:44:10 +08:00
xiaojunnuo
e5d93bd114 chore: 1 2024-07-19 15:41:36 +08:00
109 changed files with 800 additions and 528 deletions

57
.github/workflows/build-image.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: build-image
on:
push:
branches: ['v2']
paths:
- "build.trigger"
# schedule:
# - # 国际时间 19:17 执行北京时间3:17 ↙↙↙ 改成你想要每天自动执行的时间
# - cron: '17 19 * * *'
permissions:
contents: read
jobs:
build-certd-image:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: get_certd_version
id: get_certd_version
uses: actions/github-script@v6
with:
result-encoding: string
script: |
const fs = require('fs');
const path = require('path');
const pnpmWorkspace = "./pnpm-workspace.yaml";
fs.unlinkSync(pnpmWorkspace)
const jsonFilePath = "./packages/ui/certd-server/package.json";
const jsonContent = fs.readFileSync(jsonFilePath, 'utf-8');
const pkg = JSON.parse(jsonContent)
console.log("certd_version:",pkg.version);
return pkg.version
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to aliyun container Registry
uses: docker/login-action@v3
with:
registry: registry.cn-shenzhen.aliyuncs.com
username: ${{ secrets.aliyun_cs_username }}
password: ${{ secrets.aliyun_cs_password }}
- name: Build and push
uses: docker/build-push-action@v6.5.0
with:
# platforms: linux/amd64,linux/arm64
push: true
context: ./packages/ui/
tags: |
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}

View File

@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
### Bug Fixes
* 修复创建流水线时无法根据dns类型默认正确的dns授权的bug ([a2c43b5](https://github.com/certd/certd/commit/a2c43b50a6069ed48958fd142844a8568c2af452))
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
### Performance Improvements
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
* 创建证书任务增加定时任务和邮件通知输入 ([427620d](https://github.com/certd/certd/commit/427620d34f3b8ad6933005faf1878908441a2453))
* 支持配置启动后自动触发一次任务 ([a5a0c1f](https://github.com/certd/certd/commit/a5a0c1f6e7a3f05e581005e491d5b102ee854412))
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -14,6 +14,7 @@ CertD 是一个免费全自动申请和自动部署更新SSL证书的工具。
* 支持多个域名打到一个证书上
* 邮件通知
* 证书自动更新
* 私有化部署,安全
* 免费、免费、免费([阿里云单个通配符域名证书最便宜也要1800/年](https://yundun.console.aliyun.com/?p=cas#/certExtend/buy/cn-hangzhou)
@@ -54,52 +55,44 @@ https://docs.docker.com/engine/install/
选择对应的操作系统,按照官方文档执行命令即可
### 2. 下载docker-compose.yaml文件
### 2. 运行certd
[docker-compose.yaml下载](https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml)
```bash
# 随便创建一个目录
mkdir certd
# 进入目录
cd certd
# wget下载docker-compose.yaml文件
wget https://raw.githubusercontent.com/certd/certd/v2/docker/run/docker-compose.yaml
# 或者使用gitee地址
# 下载docker-compose.yaml文件或者手动下载放到certd目录下
wget https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
# 可以根据需要修改里面的配置
# 1.修改镜像版本号【可选】
# 2.配置数据保存路径【可选】
# 3.修改端口号【可选】
vi docker-compose.yaml
```
### 3. 运行
当前版本号: ![](https://img.shields.io/npm/v/%40certd%2Fpipeline)
```bash
# 设置镜像版本号环境变量如果docker-compose.yaml中已经修改请忽略这条命令
export CERTD_VERSION=latest # <---建议设置成固定版本号
vi docker-compose.yaml # 【可选】
# 启动certd
docker compose up -d
```
当前版本号: ![](https://img.shields.io/npm/v/%40certd%2Fpipeline)
如果提示 没有compose命令,请安装docker-compose
https://docs.docker.com/compose/install/linux/
### 4. 访问
### 3. 访问
http://your_server_ip:7001
默认账号密码admin/123456
记得修改密码
### 5. 升级
### 4. 升级
* 修改版本号,重新运行 `docker compose up -d` 即可
* 修改`docker-compose.yaml`中的镜像版本号
* 重新运行 `docker compose up -d` 即可
* 数据存在`/data/certd`目录下,不用担心数据丢失
@@ -143,7 +136,7 @@ docker logs -f --tail 500 certd
```shell
docker compose up -d
```
5. 使用admin/123456登录系统请及时修改管理员密码
5. 使用`admin/123456`登录系统,请及时修改管理员密码
## 八、联系作者
如有疑问欢迎加入群聊请备注certd

1
build.trigger Normal file
View File

@@ -0,0 +1 @@
3

View File

@@ -32,8 +32,9 @@ async function getPackages(directoryPath) {
async function getAllPackages() {
const base = await getPackages("./packages/core")
const plugins = await getPackages("./packages/plugins")
const libs = await getPackages("./packages/libs")
return base.concat(plugins)
return base.concat(plugins).concat(libs)
}
async function sync() {
@@ -48,7 +49,7 @@ async function sync() {
data: {}
})
console.log(`sync success:${pkg}`)
await sleep(100*1000)
await sleep(30*1000)
}
}
@@ -78,7 +79,7 @@ async function triggerBuild() {
}
})
console.log(`webhook success:${webhook}`)
await sleep(10*60*1000)
await sleep(30*60*1000)
}
}
@@ -86,9 +87,9 @@ async function triggerBuild() {
async function start() {
// await build()
console.log("等待60秒")
await sleep(200 * 1000)
await sleep(100* 1000)
await sync()
await sleep(60 * 1000)
await sleep(100 * 1000)
await triggerBuild()
}

View File

@@ -1,20 +0,0 @@
FROM registry.cn-shenzhen.aliyuncs.com/handsfree/node:18-alpine
EXPOSE 7001
ENV NODE_ENV production
ENV MIDWAY_SERVER_ENV production
WORKDIR /app/
#RUN npm install -g pnpm
#RUN npm install cross-env -g --registry=https://registry.npmmirror.com
#RUN npm install pm2 -g --registry=https://registry.npmmirror.com
#RUN pm2 install pm2-logrotate
ADD ./workspace/certd-server/ /app/
RUN sed -i "s/workspace://g" "/app/package.json"
RUN yarn install --production --registry=https://registry.npmmirror.com
#RUN yarn install --production
RUN npm run build
#CMD ["pm2-runtime", "start", "./bootstrap.js","--name", "certd","-i","1"]
CMD ["npm", "run","start"]

View File

@@ -1,38 +0,0 @@
#!/bin/bash
set -e
echo "请先输入一个版本号:"
read version
echo "您输入的版本号是: $version"
echo "登录aliyun镜像仓库"
sudo docker login --username=252959493@qq.com registry.cn-shenzhen.aliyuncs.com
build=$(pwd)
cd ../../
root=$(pwd)
echo "安装依赖"
#pnpm install --registry=https://registry.npmmirror.com
pnpm install
echo "packages build"
lerna run build
echo "packages build success"
echo "server build"
cd $root/packages/ui/certd-server
pnpm run build
echo "server build success"
echo "rm node_modules"
rm ./node_modules -rf
echo "copy to workspace"
mkdir -p $build/workspace/certd-server
\cp ./* $build/workspace/certd-server -rf
\cp ../certd-client/dist/* $build/workspace/certd-server/public/ -rf
#export TAG=$version
#sudo -E docker compose build
#sudo -E docker compose push

View File

@@ -1,8 +1,8 @@
version: '3.3'
services:
certd:
# 镜像 # ↓↓↓↓↓ --- 1、 修改镜像版本号,或者干脆写成latest不推荐 如果设置了环境变量 export CERTD_VERSION=xxx这里可以不修改
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${CERTD_VERSION}
# 镜像 # ↓↓↓↓↓ --- 1、 镜像版本号,建议改成固定版本号【可选】
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
container_name: certd # 容器名
restart: unless-stopped # 自动重启
volumes:
@@ -15,8 +15,10 @@ services:
- TZ=Asia/Shanghai
- certd_system_resetAdminPassword=false
# ↑↑↑↑↑---------------------------4、如果忘记管理员密码可以设置为true重启之后管理员密码将改成123456然后请及时修改回false【可选】
- certd_cron_immediateTriggerOnce=false
# ↑↑↑↑↑---------------------------5、如果设置为true启动后所有配置了cron的流水线任务都将被立即触发一次【可选】
- VITE_APP_ICP_NO=
# ↑↑↑↑↑ -----------------------------------------5、这里可以设置备案号【可选】
# ↑↑↑↑↑ -----------------------------------------6、这里可以设置备案号【可选】
# 设置环境变量即可自定义certd配置
# 服务端配置项见: packages/ui/certd-server/src/config/config.default.ts
# 服务端配置规则: certd_ + 配置项, 点号用_代替

View File

@@ -1,13 +0,0 @@
#!/bin/bash
set -e
# 判断$CERTD_VERSION 是否存在
if [ -n "$CERTD_VERSION" ]; then
echo "CERTD_VERSION is set = $CERTD_VERSION"
else
echo "CERTD_VERSION is not set"
echo "请先输入一个版本号(如 1.0.6)"
read CERTD_VERSION
fi
echo "您输入的版本号是: $CERTD_VERSION"
sudo -E docker compose up -d

View File

@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.22.0"
"version": "1.22.2"
}

View File

@@ -12,7 +12,7 @@
"scripts": {
"start": "lerna bootstrap --hoist",
"i-all": "lerna link && lerna exec npm install ",
"publish": "npm run prepublishOnly1 && lerna publish --conventional-commits && npm run afterpublishOnly && npm run deploy1",
"publish": "npm run prepublishOnly1 && lerna publish --conventional-commits --create-release github && npm run afterpublishOnly && npm run deploy1",
"afterpublishOnly": "",
"prepublishOnly1": "npm run check && npm run before-build && lerna run build ",
"before-build": "cd ./packages/core/acme-client && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/publishlab/node-acme-client/compare/v1.22.1...v1.22.2) (2024-07-23)
**Note:** Version bump only for package @certd/acme-client
## [1.22.1](https://github.com/publishlab/node-acme-client/compare/v1.22.0...v1.22.1) (2024-07-20)
**Note:** Version bump only for package @certd/acme-client
# [1.22.0](https://github.com/publishlab/node-acme-client/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1 +1 @@
15:27
02:24

View File

@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.22.0",
"version": "1.22.2",
"main": "src/index.js",
"types": "types/index.d.ts",
"license": "MIT",
@@ -59,5 +59,5 @@
"bugs": {
"url": "https://github.com/publishlab/node-acme-client/issues"
},
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
**Note:** Version bump only for package @certd/pipeline
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
### Performance Improvements
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.22.0",
"version": "1.22.2",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -55,5 +55,5 @@
"vite": "^4.3.8",
"vue-tsc": "^1.6.5"
},
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -283,7 +283,7 @@ export class Executor {
}
if (notification.type === "email") {
try {
this.options.emailService?.send({
await this.options.emailService?.send({
userId: this.pipeline.userId,
subject,
content,

View File

@@ -23,6 +23,7 @@ export type TaskInputDefine = FormItemProps;
export type PluginDefine = Registrable & {
default?: any;
group?: string;
input?: {
[key: string]: TaskInputDefine;
};

View File

@@ -42,9 +42,9 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
}
inputArray.push([key, _input]);
}
inputArray = _.sortBy(inputArray, (item) => item[1].order);
inputArray = _.sortBy(inputArray, (item: any) => item[1].order);
const inputMap: any = {};
inputArray.forEach((item) => {
inputArray.forEach((item: any) => {
inputMap[item[0]] = item[1];
});

View File

@@ -0,0 +1,25 @@
import { PluginDefine } from "./api";
export class PluginGroup {
key: string;
title: string;
desc?: string;
order: number;
plugins: PluginDefine[];
constructor(key: string, title: string, order = 0, desc = "") {
this.key = key;
this.title = title;
this.order = order;
this.desc = desc;
this.plugins = [];
}
}
export const pluginGroups = {
cert: new PluginGroup("cert", "证书申请", 1),
aliyun: new PluginGroup("aliyun", "阿里云", 2),
huawei: new PluginGroup("huawei", "华为云", 3),
tencent: new PluginGroup("tencent", "腾讯云", 4),
host: new PluginGroup("host", "主机", 5),
other: new PluginGroup("other", "其他", 7),
};

View File

@@ -1,3 +1,4 @@
export * from "./api.js";
export * from "./registry.js";
export * from "./decorator.js";
export * from "./group.js";

View File

@@ -1,4 +1,16 @@
import { Registry } from "../registry/index.js";
import { OnRegisterContext, Registry } from "../registry/index.js";
import { AbstractTaskPlugin } from "./api.js";
import { pluginGroups } from "./group.js";
export const pluginRegistry = new Registry<AbstractTaskPlugin>("plugin");
const onRegister = ({ key, value }: OnRegisterContext<AbstractTaskPlugin>) => {
const group = value?.define?.group as string;
if (group) {
if (pluginGroups.hasOwnProperty(group)) {
// @ts-ignore
pluginGroups[group].plugins.push(value.define);
} else {
pluginGroups.other.plugins.push(value.define);
}
}
};
export const pluginRegistry = new Registry<AbstractTaskPlugin>("plugin", onRegister);

View File

@@ -4,20 +4,31 @@ export type Registrable = {
name: string;
title: string;
desc?: string;
group?: string;
};
export type RegistryItem<T> = {
define: Registrable;
target: T;
};
export type OnRegisterContext<T> = {
registry: Registry<T>;
key: string;
value: RegistryItem<T>;
};
export type OnRegister<T> = (ctx: OnRegisterContext<T>) => void;
export class Registry<T> {
type = "";
storage: {
[key: string]: RegistryItem<T>;
} = {};
constructor(type: string) {
onRegister?: OnRegister<T>;
constructor(type: string, onRegister?: OnRegister<T>) {
this.type = type;
this.onRegister = onRegister;
}
register(key: string, value: RegistryItem<T>) {
@@ -25,6 +36,13 @@ export class Registry<T> {
return;
}
this.storage[key] = value;
if (this.onRegister) {
this.onRegister({
registry: this,
key,
value,
});
}
logger.info(`注册插件:${this.type}:${key}`);
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
**Note:** Version bump only for package @certd/lib-huawei
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/lib-huawei",
"private": false,
"version": "1.22.0",
"version": "1.22.1",
"main": "./dist/bundle.js",
"module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts",
@@ -16,5 +16,5 @@
"axios": "^1.7.2",
"rollup": "^3.7.4"
},
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
**Note:** Version bump only for package @certd/lib-k8s
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
**Note:** Version bump only for package @certd/lib-k8s
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/lib-k8s",
"private": false,
"version": "1.22.0",
"version": "1.22.2",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -13,11 +13,11 @@
"preview": "vite preview"
},
"dependencies": {
"dns": "^0.2.2",
"kubernetes-client": "^9.0.0"
"kubernetes-client": "^9.0.0",
"shelljs": "^0.8.5"
},
"devDependencies": {
"@certd/pipeline": "workspace:^1.22.0",
"@certd/pipeline": "^1.22.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",
@@ -38,5 +38,5 @@
"tslib": "^2.5.2",
"typescript": "^4.8.4"
},
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -1,4 +1,5 @@
import kubernetesClient from 'kubernetes-client';
//@ts-ignore
import dns from 'dns';
import { logger } from '@certd/pipeline';

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
**Note:** Version bump only for package @certd/midway-flyway-js
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/midway-flyway-js",
"version": "1.22.0",
"version": "1.22.2",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -36,6 +36,7 @@
"@types/node": "16",
"@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1",
"better-sqlite3": "^11.1.2",
"cross-env": "^6.0.0",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
@@ -47,10 +48,10 @@
"prettier": "^2.8.8",
"rollup": "^3.7.4",
"rollup-plugin-visualizer": "^5.8.2",
"sqlite3": "^5.0.2",
"ts-node": "^10.9.1",
"tslib": "^2.5.2",
"typeorm": "^0.3.11",
"typescript": "~5.1.0"
}
},
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -227,8 +227,10 @@ export class Flyway {
if (history.hash !== hash && this.allowHashNotMatch === false) {
throw new Error(file + `hash conflict ,old: ${history.hash} != new: ${hash}`);
}
this.logger.info('[ midfly ] script<' + file + '> already executed');
return true;
}
this.logger.info('[ midfly ] script<' + file + '> not yet execute');
return false;
}

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
**Note:** Version bump only for package @certd/plugin-cert
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
### Performance Improvements
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-cert",
"private": false,
"version": "1.22.0",
"version": "1.22.2",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -13,8 +13,8 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/acme-client": "workspace:^1.22.0",
"@certd/pipeline": "workspace:^1.22.0",
"@certd/acme-client": "^1.22.2",
"@certd/pipeline": "^1.22.2",
"jszip": "^3.10.1",
"node-forge": "^0.10.0",
"psl": "^1.9.0"
@@ -53,5 +53,5 @@
"vite": "^3.1.0",
"vue-tsc": "^0.38.9"
},
"gitHead": "a31f1c7f5e71fa946de9bf0283e11d6ce049b3e9"
"gitHead": "47fe3d5826661f678d081ab53e67c847a3239d88"
}

View File

@@ -21,6 +21,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
col: {
span: 24,
},
order: -1,
helper:
"1、支持通配符域名例如 *.foo.com、foo.com、*.test.handsfree.work\n" +
"2、支持多个域名、多个子域名、多个通配符域名打到一个证书上域名必须是在同一个DNS提供商解析\n" +
@@ -36,12 +37,14 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
vModel: "value",
},
required: true,
order: -1,
helper: "请输入邮箱",
})
email!: string;
@TaskInput({
title: "更新天数",
value: 20,
component: {
name: "a-input-number",
vModel: "value",

View File

@@ -1,4 +1,4 @@
import { Decorator, IsTaskPlugin, RunStrategy, TaskInput } from "@certd/pipeline";
import { Decorator, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import type { CertInfo, SSLProvider } from "./acme.js";
import { AcmeService } from "./acme.js";
import _ from "lodash-es";
@@ -11,7 +11,8 @@ export type { CertInfo };
@IsTaskPlugin({
name: "CertApply",
title: "证书申请",
title: "证书申请JS版",
group: pluginGroups.cert.key,
desc: "免费通配符域名证书申请,支持多个域名打到同一个证书上",
default: {
input: {
@@ -32,6 +33,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
vModel: "value",
options: [
{ value: "letsencrypt", label: "Let's Encrypt" },
// { value: "letsencrypt-proxy", label: "Let's Encrypt代理letsencrypt.org无法访问时使用" },
// { value: "buypass", label: "Buypass" },
{ value: "zerossl", label: "ZeroSSL" },
],
@@ -46,6 +48,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
name: "pi-access-selector",
type: "eab",
},
maybeNeed: true,
helper: "如果使用ZeroSSL证书需要提供EAB授权 请前往 https://app.zerossl.com/developer 生成 'EAB Credentials for ACME Clients' ",
})
eabAccessId!: number;

View File

@@ -0,0 +1 @@
export const dnsList = [];

View File

@@ -1,9 +1,9 @@
import { IsTaskPlugin, RunStrategy, sp, Step, TaskInput } from "@certd/pipeline";
import type { CertInfo } from "./acme.js";
import { CertReader } from "./cert-reader.js";
import { CertApplyBasePlugin } from "./base.js";
import { IsTaskPlugin, pluginGroups, RunStrategy, sp, Step, TaskInput } from "@certd/pipeline";
import type { CertInfo } from "../acme.js";
import { CertReader } from "../cert-reader.js";
import { CertApplyBasePlugin } from "../base.js";
import fs from "fs";
import { EabAccess } from "../../access";
import { EabAccess } from "../../../access/index.js";
import path from "path";
export { CertReader };
@@ -12,7 +12,8 @@ export type { CertInfo };
@IsTaskPlugin({
name: "CertApplyLego",
title: "证书申请Lego",
desc: "支持海量DNS解析提供商推荐使用",
group: pluginGroups.cert.key,
desc: "支持海量DNS解析提供商推荐使用一样的免费通配符域名证书申请支持多个域名打到同一个证书上",
default: {
input: {
renewDays: 20,
@@ -24,12 +25,29 @@ export type { CertInfo };
},
})
export class CertApplyLegoPlugin extends CertApplyBasePlugin {
// @TaskInput({
// title: "ACME服务端点",
// default: "https://acme-v02.api.letsencrypt.org/directory",
// component: {
// name: "a-select",
// vModel: "value",
// options: [
// { value: "https://acme-v02.api.letsencrypt.org/directory", label: "Let's Encrypt" },
// { value: "https://letsencrypt.proxy.handsfree.work/directory", label: "Let's Encrypt代理letsencrypt.org无法访问时使用" },
// ],
// },
// required: true,
// })
acmeServer!: string;
@TaskInput({
title: "DNS类型",
component: {
name: "a-input",
vModel: "value",
placeholder: "alidns",
},
helper: "你的域名是通过哪家提供商进行解析的具体应该配置什么请参考lego文档https://go-acme.github.io/lego/dns/",
required: true,
})
dnsType!: string;
@@ -39,10 +57,11 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
component: {
name: "a-textarea",
vModel: "value",
rows: 6,
rows: 4,
placeholder: "ALICLOUD_ACCESS_KEY=abcdefghijklmnopqrstuvwx\nALICLOUD_SECRET_KEY=your-secret-key",
},
required: true,
helper: "一行一条,例如 appKeyId=xxxxx",
helper: "一行一条,例如 appKeyId=xxxxx具体配置请参考lego文档https://go-acme.github.io/lego/dns/",
})
environment!: string;
@@ -52,16 +71,20 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
name: "pi-access-selector",
type: "eab",
},
maybeNeed: true,
helper: "如果需要提供EAB授权",
})
eabAccessId!: number;
legoEabAccessId!: number;
@TaskInput({
title: "自定义LEGO参数",
component: {
name: "a-input",
vModel: "value",
placeholder: "--dns-timeout 30",
},
helper: "额外的lego命令行参数参考文档https://go-acme.github.io/lego/usage/cli/options/",
maybeNeed: true,
})
customArgs = "";
@@ -73,8 +96,8 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
this.userContext = this.ctx.userContext;
this.http = this.ctx.http;
this.lastStatus = this.ctx.lastStatus as Step;
if (this.eabAccessId) {
this.eab = await this.ctx.accessService.getById(this.eabAccessId);
if (this.legoEabAccessId) {
this.eab = await this.ctx.accessService.getById(this.legoEabAccessId);
}
}
async onInit(): Promise<void> {}
@@ -102,8 +125,14 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
const savePathArgs = `--path "${saveDir}"`;
const os_type = process.platform === "win32" ? "windows" : "linux";
const legoPath = path.resolve("./tools", os_type, "lego");
let serverArgs = "";
if (this.acmeServer) {
serverArgs = ` --server ${this.acmeServer}`;
}
const cmds = [
`${legoPath} -a --email "${this.email}" --dns ${this.dnsType} ${keyType} ${domainArgs} ${eabArgs} ${savePathArgs} ${this.customArgs || ""} run`,
`${legoPath} -a --email "${this.email}" --dns ${this.dnsType} ${keyType} ${domainArgs} ${serverArgs} ${eabArgs} ${savePathArgs} ${
this.customArgs || ""
} run`,
];
await sp.spawn({

View File

@@ -1,2 +1,2 @@
export * from "./cert-plugin/index.js";
export * from "./cert-plugin/lego.js";
export * from "./cert-plugin/lego/index.js";

23
packages/ui/Dockerfile Normal file
View File

@@ -0,0 +1,23 @@
FROM node:18-alpine as builder
EXPOSE 7001
WORKDIR /workspace/
COPY . /workspace/
RUN npm install -g pnpm@8.15.7
RUN cd /workspace/certd-client && pnpm install && npm run build
RUN cd /workspace/certd-server && pnpm install && npm run build-on-docker
RUN cp /workspace/certd-client/dist/* /workspace/certd-server/public/ -rf
FROM node:18-alpine
WORKDIR /app/
COPY --from=builder /workspace/certd-server/ /app/
ENV TZ=Asia/Shanghai
ENV NODE_ENV=production
ENV MIDWAY_SERVER_ENV=production
CMD ["npm", "run","start"]

View File

@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
### Bug Fixes
* 修复创建流水线时无法根据dns类型默认正确的dns授权的bug ([a2c43b5](https://github.com/certd/certd/commit/a2c43b50a6069ed48958fd142844a8568c2af452))
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
### Performance Improvements
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
* 创建证书任务增加定时任务和邮件通知输入 ([427620d](https://github.com/certd/certd/commit/427620d34f3b8ad6933005faf1878908441a2453))
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.22.0",
"version": "1.22.2",
"private": true,
"scripts": {
"dev": "vite --open",
@@ -59,7 +59,7 @@
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@certd/pipeline": "^1.22.0",
"@certd/pipeline": "^1.22.2",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",

View File

@@ -0,0 +1,19 @@
import _ from "lodash-es";
import { compute } from "@fast-crud/fast-crud";
export function useReference(form: any) {
if (!form.reference) {
return;
}
for (const reference of form.reference) {
debugger;
_.set(
form,
reference.dest,
compute<any>((scope) => {
debugger;
return _.get(scope, reference.src);
})
);
}
}

View File

@@ -9,12 +9,7 @@ const defaultInputDefine = {
}
};
export async function GetList(query: any) {
const plugins = await request({
url: apiPrefix + "/list",
method: "post",
params: query
});
function initPlugins(plugins: any) {
for (const plugin of plugins) {
for (const key in plugin.input) {
const field = _.merge({}, defaultInputDefine, plugin.input[key]);
@@ -24,7 +19,7 @@ export async function GetList(query: any) {
//嵌套对象
field.key = ["input", key];
if (field.required) {
delete field.required;
// delete field.required;
if (field.rules == null) {
field.rules = [];
}
@@ -34,5 +29,28 @@ export async function GetList(query: any) {
}
}
console.log("plugins", plugins);
}
export async function GetList(query: any) {
const plugins = await request({
url: apiPrefix + "/list",
method: "post",
params: query
});
initPlugins(plugins);
return plugins;
}
export async function GetGroups(query: any) {
const groups = await request({
url: apiPrefix + "/groups",
method: "post",
params: query
});
const plugins: any = [];
for (const groupKey in groups) {
plugins.push(...groups[groupKey].plugins);
}
initPlugins(plugins);
return groups;
}

View File

@@ -1,152 +1,106 @@
import { compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from "@fast-crud/fast-crud";
import { Dicts } from "./dicts";
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
import { PluginGroup } from "@certd/pipeline";
import { useReference } from "/@/use/use-refrence";
import _ from "lodash-es";
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
const inputs: any = {};
for (const plugin of certPluginGroup.plugins) {
for (const inputKey in plugin.input) {
if (inputs[inputKey]) {
inputs[inputKey].form.show = true;
continue;
}
const inputDefine = _.cloneDeep(plugin.input[inputKey]);
if (!inputDefine.required && !inputDefine.maybeNeed) {
continue;
}
useReference(inputDefine);
inputs[inputKey] = {
title: inputDefine.title,
form: {
...inputDefine,
show: compute((ctx) => {
console.log(formWrapperRef);
const form = formWrapperRef.value.getFormData();
if (!form) {
return false;
}
return form?.certApplyPlugin === plugin.name;
})
}
};
}
}
export default function (): CreateCrudOptionsRet {
return {
crudOptions: {
form: {
wrapper: {
width: "1150px"
width: "1150px",
saveRemind: false
}
},
columns: {
domains: {
title: "域名",
certApplyPlugin: {
title: "证书申请插件",
type: "dict-select",
search: {
show: true,
component: {
name: "a-input"
}
},
dict: dict({
data: [
{ value: "CertApply", label: "JS-ACME" },
{ value: "CertApplyLego", label: "Lego-ACME" }
]
}),
form: {
order: 0,
value: "CertApply",
helper: {
render: () => {
return (
<ul>
<li>Lego-ACMELego实现DNS提供商</li>
<li>JS-ACMEDNS属于阿里云Cloudflare可以选择用它来申请</li>
</ul>
);
}
}
}
},
...inputs,
triggerCron: {
title: "定时触发",
type: "text",
form: {
col: {
span: 24
},
wrapperCol: {
span: null
},
component: {
mode: "tags",
open: false
placeholder: "0 0 4 * * *"
},
helper: "请输入cron表达式, 例如0 0 4 * * *每天凌晨4点触发",
order: 100
}
},
emailNotify: {
title: "失败邮件通知",
type: "dict-switch",
dict: dict({
data: [
{ value: true, label: "启用" },
{ value: false, label: "不启用" }
]
}),
form: {
order: 101,
helper: {
render: () => {
return (
<div>
<div> *.foo.com *.test.handsfree.work</div>
<div>DNS提供商解析</div>
<div>*.foo.com的证书不能用于xxx.yyy.foo.com</div>
<div></div>
<router-link to={{ path: "/certd/settings/email" }}></router-link>
</div>
);
}
},
valueResolve({ form }) {
if (form.domains instanceof String) {
form.domains = form.domains?.join(",");
}
},
rules: [{ required: true, message: "请填写域名" }]
}
},
email: {
title: "邮箱",
type: "text",
search: { show: false },
form: {
rules: [{ required: true, type: "email", message: "请填写邮箱" }]
}
},
blank: {
title: "占位",
type: "text",
form: {
blank: true
}
},
sslProvider: {
title: "证书提供商",
type: "dict-select",
dict: Dicts.sslProviderDict
},
eabAccess: {
title: "EAB授权",
type: "dict-select",
form: {
component: {
name: "PiAccessSelector",
type: "eab",
vModel: "modelValue"
},
helper: "如果是ZeroSSL需要配置EAB授权https://app.zerossl.com/developer 生成 'EAB' "
}
},
dnsProviderType: {
title: "DNS提供商",
type: "dict-select",
dict: Dicts.dnsProviderTypeDict,
form: {
value: "aliyun",
rules: [{ required: true, message: "请选择DNS提供商" }],
valueChange({ form }) {
form.dnsProviderAccess = null;
}
}
},
dnsProviderAccess: {
title: "DNS授权",
type: "text",
form: {
component: {
name: "PiAccessSelector",
type: compute(({ form }) => {
return form.dnsProviderType;
}),
vModel: "modelValue"
},
rules: [{ required: true, message: "请选择DNS授权" }]
}
}
// country: {
// title: "国家",
// type: "text",
// form: {
// value: "China"
// }
// },
// state: {
// title: "省份",
// type: "text",
// form: {
// value: "GuangDong"
// }
// },
// locality: {
// title: "市区",
// type: "text",
// form: {
// value: "NanShan"
// }
// },
// organization: {
// title: "单位",
// type: "text",
// form: {
// value: "CertD"
// }
// },
// organizationUnit: {
// title: "部门",
// type: "text",
// form: {
// value: "IT Dept"
// }
// },
// remark: {
// title: "备注",
// type: "text"
// }
}
}
};

View File

@@ -1,5 +1,5 @@
<template>
<fs-form-wrapper ref="formWrapperRef" />
<fs-form-wrapper v-if="formWrapperOptions" ref="formWrapperRef" />
</template>
<script lang="ts">
@@ -7,28 +7,37 @@ import { useColumns, useExpose } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud.jsx";
import { ref } from "vue";
import _ from "lodash-es";
import * as api from "../api.plugin";
import { PluginGroup, PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
export default {
name: "PiCertdForm",
setup(props: any, ctx: any) {
// 自定义表单配置
const { buildFormOptions } = useColumns();
//使用crudOptions结构来构建自定义表单配置
let { crudOptions } = createCrudOptions();
const doSubmitRef = ref();
const formOptions = buildFormOptions(
_.merge(crudOptions, {
form: {
doSubmit({ form }: any) {
// 创建certd 的pipeline
doSubmitRef.value({ form });
}
}
}) as any
);
const formWrapperRef = ref();
const formWrapperOptions = ref();
formWrapperOptions.value = formOptions;
const doSubmitRef = ref();
async function buildFormOptions() {
const pluginGroups: { [key: string]: PluginGroup } = await api.GetGroups({});
const certPluginGroup = pluginGroups.cert;
// 自定义表单配置
const { buildFormOptions } = useColumns();
//使用crudOptions结构来构建自定义表单配置
let { crudOptions } = createCrudOptions(certPluginGroup, formWrapperRef);
const formOptions = buildFormOptions(
_.merge(crudOptions, {
form: {
doSubmit({ form }: any) {
// 创建certd 的pipeline
doSubmitRef.value({ form });
}
}
}) as any
);
formWrapperOptions.value = formOptions;
}
buildFormOptions();
function open(doSubmit: any) {
doSubmitRef.value = doSubmit;
formWrapperRef.value.open(formWrapperOptions.value);

View File

@@ -37,6 +37,21 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp
function addCertdPipeline() {
certdFormRef.value.open(async ({ form }: any) => {
// 添加certd pipeline
const triggers = [];
if (form.triggerCron) {
triggers.push({ id: nanoid(), title: "定时触发", type: "timer", props: { cron: form.triggerCron } });
}
const notifications = [];
if (form.emailNotify) {
notifications.push({
id: nanoid(),
type: "email",
when: ["error", "turnToSuccess"],
options: {
receivers: [form.email]
}
});
}
const pipeline = {
title: form.domains[0] + "证书自动化",
stages: [
@@ -58,13 +73,15 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp
strategy: {
runStrategy: 0 // 正常执行
},
type: "CertApply"
type: form.certApplyPlugin
}
]
}
]
}
]
],
triggers,
notifications
};
const id = await api.Save({

View File

@@ -11,14 +11,14 @@ import * as pluginApi from "./api.plugin";
import * as historyApi from "./api.history";
import * as api from "./api";
import { useRoute } from "vue-router";
import { PipelineDetail, PipelineOptions, RunHistory } from "./pipeline/type";
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./pipeline/type";
export default defineComponent({
name: "PipelineDetail",
components: { PipelineEdit },
setup() {
const route = useRoute();
const pipelineId:Ref = ref(route.query.id);
const pipelineId: Ref = ref(route.query.id);
const pipelineOptions: PipelineOptions = {
async getPipelineDetail({ pipelineId }) {
@@ -43,9 +43,9 @@ export default defineComponent({
return detail;
},
async getPlugins() {
const plugins = await pluginApi.GetList({});
return plugins as any[];
async getPluginGroups() {
const groups = await pluginApi.GetGroups({});
return new PluginGroups(groups);
},
async doSave(pipelineConfig: any) {

View File

@@ -4,13 +4,9 @@
<div class="title">我的流水线</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<!-- <span style="margin-left: 10px">出现<a-tag>Promise rejected attempt #18,retrying in 10000ms:No TXT recordsfound for name</a-tag>属于正常现象多重试几次</span>-->
</template>
<template #actionbar-right> </template>
<template #form-bottom>
<div>
申请证书
</div>
<div>申请证书</div>
</template>
<pi-certd-form ref="certdFormRef"></pi-certd-form>
</fs-crud>

View File

@@ -15,7 +15,7 @@ export default {
}
},
emits: ["update:modelValue"],
setup(props:any, ctx:any) {
setup(props: any, ctx: any) {
const options = ref<any[]>([]);
const pipeline = inject("pipeline") as Ref<any>;
@@ -23,8 +23,10 @@ export default {
const currentStepIndex = inject("currentStepIndex") as Ref<number>;
const currentTask = inject("currentTask") as Ref<any>;
const getPluginGroups = inject("getPluginGroups") as Ref<any>;
const pluginGroups = getPluginGroups();
function onCreate() {
options.value = pluginManager.getPreStepOutputOptions({
options.value = pluginGroups.getPreStepOutputOptions({
pipeline: pipeline.value,
currentStageIndex: currentStageIndex.value,
currentStepIndex: currentStepIndex.value,
@@ -40,14 +42,14 @@ export default {
watch(
() => {
return pluginManager.map;
return pluginGroups.value.map;
},
() => {
onCreate();
}
);
function onChanged(value:any) {
function onChanged(value: any) {
ctx.emit("update:modelValue", value);
}
return {

View File

@@ -1,5 +1,5 @@
<template>
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="600px" @after-open-change="stepDrawerOnAfterVisibleChange">
<a-drawer v-model:open="stepDrawerVisible" placement="right" :closable="true" width="700px" @after-open-change="stepDrawerOnAfterVisibleChange">
<template #title>
编辑步骤
<a-button v-if="editMode" @click="stepDelete()">
@@ -8,30 +8,36 @@
</template>
<template v-if="currentStep">
<pi-container v-if="currentStep._isAdd" class="pi-step-form">
<a-row :gutter="10">
<a-col v-for="(item, index) of stepPluginDefineList" :key="index" class="step-plugin" :span="12">
<a-card
hoverable
:class="{ current: item.name === currentStep.type }"
@click="stepTypeSelected(item)"
@dblclick="
stepTypeSelected(item);
stepTypeSave();
"
>
<a-card-meta>
<template #title>
<a-avatar :src="item.icon || '/images/plugin.png'" />
<span class="title">{{ item.title }}</span>
</template>
<template #description>
<span :title="item.desc">{{ item.desc }}</span>
</template>
</a-card-meta>
</a-card>
</a-col>
</a-row>
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> 确定 </a-button>
<a-tabs tab-position="left">
<a-tab-pane v-for="group of pluginGroups.groups" :key="group.key" :tab="group.title">
<a-row :gutter="10">
<a-col v-for="item of group.plugins" :key="item.key" class="step-plugin" :span="12">
<a-card
hoverable
:class="{ current: item.name === currentStep.type }"
@click="stepTypeSelected(item)"
@dblclick="
stepTypeSelected(item);
stepTypeSave();
"
>
<a-card-meta>
<template #title>
<a-avatar :src="item.icon || '/images/plugin.png'" />
<span class="title">{{ item.title }}</span>
</template>
<template #description>
<span :title="item.desc">{{ item.desc }}</span>
</template>
</a-card-meta>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
<div style="padding: 20px; margin-left: 100px">
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> 确定 </a-button>
</div>
</pi-container>
<pi-container v-else class="pi-step-form">
<a-form ref="stepFormRef" class="step-form" :model="currentStep" :label-col="labelCol" :wrapper-col="wrapperCol">
@@ -91,6 +97,8 @@ import { computed, inject, Ref, ref } from "vue";
import _ from "lodash-es";
import { nanoid } from "nanoid";
import { CopyOutlined } from "@ant-design/icons-vue";
import { PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
export default {
name: "PiStepForm",
components: { CopyOutlined },
@@ -107,8 +115,8 @@ export default {
* @returns
*/
function useStepForm() {
const stepPluginDefineList: any = inject("plugins");
const getPluginGroups: any = inject("getPluginGroups");
const pluginGroups: PluginGroups = getPluginGroups();
const mode: Ref = ref("add");
const callback: Ref = ref();
const currentStep: Ref = ref({ title: undefined, input: {} });
@@ -199,9 +207,7 @@ export default {
const changeCurrentPlugin = (step: any) => {
const stepType = step.type;
const pluginDefine = stepPluginDefineList.value.find((p: any) => {
return p.name === stepType;
});
const pluginDefine = pluginGroups.get(stepType);
if (pluginDefine) {
step.type = stepType;
step._isAdd = false;
@@ -271,7 +277,7 @@ export default {
return {
stepTypeSelected,
stepTypeSave,
stepPluginDefineList,
pluginGroups,
stepFormRef,
mode,
stepAdd,

View File

@@ -1,5 +1,12 @@
<template>
<a-drawer v-model:open="taskDrawerVisible" placement="right" :closable="true" width="600px" class="pi-task-form" @after-open-change="taskDrawerOnAfterVisibleChange">
<a-drawer
v-model:open="taskDrawerVisible"
placement="right"
:closable="true"
width="700px"
class="pi-task-form"
@after-open-change="taskDrawerOnAfterVisibleChange"
>
<template #title>
编辑任务
<a-button v-if="editMode" @click="taskDelete()">
@@ -24,7 +31,13 @@
/>
<div class="steps">
<a-form-item :value="currentTask.steps" name="steps" label="" :wrapper-col="{ span: 24 }" :rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]">
<a-form-item
:value="currentTask.steps"
name="steps"
label=""
:wrapper-col="{ span: 24 }"
:rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]"
>
<a-descriptions title="任务步骤" size="small">
<template #extra>
<a-button type="primary" @click="stepAdd(currentTask)">添加步骤</a-button>
@@ -70,7 +83,7 @@ import { provide, Ref, ref } from "vue";
import _ from "lodash-es";
import { nanoid } from "nanoid";
import PiStepForm from "../step-form/index.vue";
import { message, Modal } from "ant-design-vue";
import { Modal } from "ant-design-vue";
import { CopyOutlined } from "@ant-design/icons-vue";
export default {
@@ -88,7 +101,7 @@ export default {
const stepFormRef: Ref<any> = ref(null);
const currentStepIndex = ref(0);
provide("currentStepIndex", currentStepIndex);
const stepAdd = (task: any, stepDef: any) => {
const stepAdd = (task: any, stepDef?: any) => {
currentStepIndex.value = task.steps.length;
stepFormRef.value.stepAdd((type: any, value: any) => {
if (type === "save") {
@@ -179,7 +192,7 @@ export default {
const taskAdd = (emit: any, taskMerge: any) => {
mode.value = "add";
const blankTask = { id: nanoid(), title: "新任务", steps: [], status: null };
const blankTask: any = { id: nanoid(), title: "新任务", steps: [], status: null };
const task: any = _.merge(blankTask, taskMerge);
taskOpen(task, emit);
};

View File

@@ -223,7 +223,7 @@ import _ from "lodash-es";
import { message, Modal, notification } from "ant-design-vue";
import { pluginManager } from "/@/views/certd/pipeline/pipeline/plugin";
import { nanoid } from "nanoid";
import { PipelineDetail, PipelineOptions, RunHistory } from "./type";
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./type";
import type { Runnable } from "@certd/pipeline";
import PiHistoryTimelineItem from "/@/views/certd/pipeline/pipeline/component/history-timeline-item.vue";
export default defineComponent({
@@ -348,17 +348,17 @@ export default defineComponent({
}
);
const plugins: Ref<any> = ref([]);
const pluginGroupsRef: Ref<PluginGroups> = ref();
const fetchPlugins = async () => {
const list = await props.options.getPlugins();
plugins.value = list;
pluginManager.init(list);
pluginGroupsRef.value = await props.options.getPluginGroups();
};
fetchPlugins();
provide("pipeline", pipeline);
provide("plugins", plugins);
provide("getPluginGroups", () => {
return pluginGroupsRef.value;
});
provide("currentHistory", currentHistory);
function useTask() {

View File

@@ -17,49 +17,7 @@ export class PluginManager {
this.map = map;
}
get(name: string) {
return this.map[name];
}
getPreStepOutputOptions({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
const steps = this.collectionPreStepOutputs({
pipeline,
currentStageIndex,
currentStepIndex,
currentTask
});
const options: any[] = [];
for (const step of steps) {
const stepDefine = this.get(step.type);
for (const key in stepDefine?.output) {
options.push({
value: `step.${step.id}.${key}`,
label: `${stepDefine.output[key].title}【from${step.title}`,
type: step.type
});
}
}
return options;
}
collectionPreStepOutputs({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
const steps: any[] = [];
// 开始放step
for (let i = 0; i < currentStageIndex; i++) {
const stage = pipeline.stages[i];
for (const task of stage.tasks) {
for (const step of task.steps) {
steps.push(step);
}
}
}
//放当前任务下的step
for (let i = 0; i < currentStepIndex; i++) {
const step = currentTask.steps[i];
steps.push(step);
}
return steps;
}
}
export const pluginManager = new PluginManager();

View File

@@ -1,4 +1,5 @@
import type { Pipeline } from "@certd/pipeline";
import { FormItemProps } from "@fast-crud/fast-crud";
export type PipelineDetail = {
pipeline: Pipeline;
};
@@ -10,6 +11,110 @@ export type RunHistory = {
[id: string]: string[];
};
};
export type PluginGroup = {
key: string;
title: string;
desc?: string;
order: number;
plugins: any[];
};
export type PluginDefine = {
key: string;
title: string;
desc?: string;
input: {
[key: string]: FormItemProps;
};
output: {
[key: string]: any;
};
};
export class PluginGroups {
groups: { [key: string]: PluginGroup };
map: { [key: string]: PluginDefine };
constructor(groups: { [key: string]: PluginGroup }) {
this.groups = groups;
this.initGroup(groups);
this.initMap();
}
private initGroup(groups: { [p: string]: PluginGroup }) {
const all: PluginGroup = {
key: "all",
title: "全部",
order: 0,
plugins: []
};
for (const key in groups) {
all.plugins.push(...groups[key].plugins);
}
this.groups = {
all,
...groups
};
}
initMap() {
const map: { [key: string]: PluginDefine } = {};
for (const key in this.groups) {
const group = this.groups[key];
for (const plugin of group.plugins) {
map[plugin.name] = plugin;
}
}
this.map = map;
}
getGroups() {
return this.groups;
}
get(name: string) {
return this.map[name];
}
getPreStepOutputOptions({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
const steps = this.collectionPreStepOutputs({
pipeline,
currentStageIndex,
currentStepIndex,
currentTask
});
const options: any[] = [];
for (const step of steps) {
const stepDefine = this.get(step.type);
for (const key in stepDefine?.output) {
options.push({
value: `step.${step.id}.${key}`,
label: `${stepDefine.output[key].title}【from${step.title}`,
type: step.type
});
}
}
return options;
}
collectionPreStepOutputs({ pipeline, currentStageIndex, currentStepIndex, currentTask }: any) {
const steps: any[] = [];
// 开始放step
for (let i = 0; i < currentStageIndex; i++) {
const stage = pipeline.stages[i];
for (const task of stage.tasks) {
for (const step of task.steps) {
steps.push(step);
}
}
}
//放当前任务下的step
for (let i = 0; i < currentStepIndex; i++) {
const step = currentTask.steps[i];
steps.push(step);
}
return steps;
}
}
export type PipelineOptions = {
doTrigger(options: { pipelineId: number }): Promise<void>;
@@ -17,5 +122,5 @@ export type PipelineOptions = {
getPipelineDetail(query: { pipelineId: number }): Promise<PipelineDetail>;
getHistoryList(query: { pipelineId: number }): Promise<RunHistory[]>;
getHistoryDetail(query: { historyId: number }): Promise<RunHistory>;
getPlugins(): Promise<Pipeline[]>;
getPluginGroups(): Promise<PluginGroups>;
};

View File

@@ -1,2 +1,3 @@
koa:
port: 7001

View File

@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.22.2](https://github.com/certd/certd/compare/v1.22.1...v1.22.2) (2024-07-23)
### Bug Fixes
* 修复创建流水线时无法根据dns类型默认正确的dns授权的bug ([a2c43b5](https://github.com/certd/certd/commit/a2c43b50a6069ed48958fd142844a8568c2af452))
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
### Performance Improvements
* 创建证书任务可以选择lege插件 ([affef13](https://github.com/certd/certd/commit/affef130378030c517250c58a4e787b0fc85d7d1))
* 支持配置启动后自动触发一次任务 ([a5a0c1f](https://github.com/certd/certd/commit/a5a0c1f6e7a3f05e581005e491d5b102ee854412))
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
### Features

View File

@@ -0,0 +1,5 @@
import fs from 'fs';
//读取 packages/core/pipline/package.json的版本号
import { default as packageJson } from './tsconfig.json' assert { type: 'json' };
delete packageJson.references;
fs.writeFileSync('./tsconfig.json', JSON.stringify(packageJson, null, 2));

View File

@@ -1,4 +1,4 @@
INSERT INTO sys_settings ("key", title, setting,access) VALUES ("sys.install","安装信息",'{"installTime":'|| (select timestamp from 'flyway_history' where id = 1 )||'}',"private");
INSERT INTO sys_settings ("key", title, setting,access) VALUES ('sys.install','安装信息','{"installTime":'|| (select timestamp from 'flyway_history' where id = 1 )||'}','private');
ALTER TABLE sys_user ADD COLUMN password_version integer DEFAULT 1;
ALTER TABLE sys_user ADD COLUMN password_salt varchar(36);

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.22.0",
"version": "1.22.2",
"description": "fast-server base midway",
"private": true,
"type": "module",
@@ -13,19 +13,20 @@
"lint": "mwts check",
"lint:fix": "mwts fix",
"ci": "npm run cov",
"build": "mwtsc --cleanOutDir",
"build": "mwtsc --cleanOutDir --skipLibCheck",
"build-on-docker": "node ./before-build.js && npm run build",
"up-mw-deps": "npx midway-version -u -w"
},
"dependencies": {
"@alicloud/cs20151215": "^3.0.3",
"@alicloud/openapi-client": "^0.4.0",
"@alicloud/pop-core": "^1.7.10",
"@certd/acme-client": "^1.22.0",
"@certd/lib-huawei": "^1.22.0",
"@certd/lib-k8s": "^1.22.0",
"@certd/midway-flyway-js": "^1.22.0",
"@certd/pipeline": "^1.22.0",
"@certd/plugin-cert": "^1.22.0",
"@certd/acme-client": "^1.22.2",
"@certd/lib-huawei": "^1.22.1",
"@certd/lib-k8s": "^1.22.2",
"@certd/midway-flyway-js": "^1.22.2",
"@certd/pipeline": "^1.22.2",
"@certd/plugin-cert": "^1.22.2",
"@koa/cors": "^3.4.3",
"@midwayjs/bootstrap": "^3.16.2",
"@midwayjs/cache": "^3.14.0",
@@ -39,9 +40,10 @@
"@midwayjs/validate": "^3.16.4",
"axios": "^1.7.2",
"bcryptjs": "^2.4.3",
"better-sqlite3": "^11.1.2",
"cache-manager": "^3.6.3",
"dayjs": "^1.11.7",
"glob": "^11.0.0",
"glob": "^10.4.5",
"https-proxy-agent": "^7.0.4",
"iconv-lite": "^0.6.3",
"js-yaml": "^4.1.0",
@@ -52,12 +54,12 @@
"log4js": "^6.7.1",
"lru-cache": "^10.0.0",
"md5": "^2.3.0",
"mwtsc": "^1.4.0",
"nanoid": "^4.0.0",
"node-cron": "^3.0.2",
"nodemailer": "^6.9.3",
"pg": "^8.12.0",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.1.4",
"ssh2": "^0.8.9",
"svg-captcha": "^1.4.0",
"tencentcloud-sdk-nodejs": "^4.0.44",
@@ -78,7 +80,6 @@
"cross-env": "^7.0.3",
"mocha": "^10.2.0",
"mwts": "^1.3.0",
"mwtsc": "^1.4.0",
"prettier": "^2.8.8",
"ts-node": "^10.9.2",
"typescript": "~5.1.0"

View File

@@ -0,0 +1 @@
1

View File

@@ -37,7 +37,9 @@ const development = {
},
},
},
cron: {},
cron: {
immediateTriggerOnce: false,
},
/**
* 演示环境
*/
@@ -54,10 +56,10 @@ const development = {
/**
* 单数据库实例
*/
type: 'sqlite',
type: 'better-sqlite3',
database: './data/db.sqlite',
synchronize: false, // 如果第一次使用,不存在表,有同步的需求可以写 true
logging: true,
logging: false,
// 配置实体模型 或者 entities: '/entity',
entities: ['**/modules/*/entity/*.ts', '**/entity/*.js', '**/entity/*.d.ts', PipelineEntity, FlywayHistory, UserEntity],
@@ -84,6 +86,8 @@ const development = {
resetAdminPasswd: false,
},
} as MidwayConfig;
mergeConfig(development, 'development');
mergeConfig(development, env);
export default development;

View File

@@ -8,6 +8,13 @@ const preview = {
preview: {
enabled: true,
},
typeorm: {
dataSource: {
default: {
logging: false,
},
},
},
} as MidwayConfig;
mergeConfig(preview, 'preview');

View File

@@ -8,6 +8,13 @@ const production = {
preview: {
enabled: false,
},
typeorm: {
dataSource: {
default: {
logging: false,
},
},
},
} as MidwayConfig;
mergeConfig(production, 'production');

View File

@@ -1,4 +1,4 @@
import { Autoload, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
import { Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
import { PipelineService } from '../service/pipeline-service.js';
import { logger } from '../../../utils/logger.js';
@@ -10,11 +10,13 @@ export class AutoRegisterCron {
// @Inject()
// echoPlugin: EchoPlugin;
@Config('cron.immediateTriggerOnce')
private immediateTriggerOnce = false;
@Init()
async init() {
logger.info('加载定时trigger开始');
await this.pipelineService.onStartup();
await this.pipelineService.onStartup(this.immediateTriggerOnce);
// logger.info(this.echoPlugin, this.echoPlugin.test);
// logger.info('加载定时trigger完成');
//

View File

@@ -1,11 +1,4 @@
import {
ALL,
Controller,
Inject,
Post,
Provide,
Query,
} from '@midwayjs/core';
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
import { BaseController } from '../../../basic/base-controller.js';
import { PluginService } from '../service/plugin-service.js';
import { Constants } from '../../../basic/constants.js';
@@ -25,4 +18,11 @@ export class PluginController extends BaseController {
const list = this.service.getList();
return this.ok(list);
}
@Post('/groups', { summary: Constants.per.authOnly })
async groups(@Query(ALL) query) {
query.userId = this.ctx.user.id;
const group = this.service.getGroups();
return this.ok(group);
}
}

View File

@@ -1,4 +1,4 @@
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service.js';
@@ -80,7 +80,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
/**
* 应用启动后初始加载记录
*/
async onStartup() {
async onStartup(immediateTriggerOnce: boolean) {
logger.info('加载定时trigger开始');
const idEntityList = await this.repository.find({
select: {
@@ -114,7 +114,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
for (const entity of list) {
const pipeline = JSON.parse(entity.content ?? '{}');
try {
this.registerTriggers(pipeline);
await this.registerTriggers(pipeline, immediateTriggerOnce);
} catch (e) {
logger.error('加载定时trigger失败', e);
}
@@ -123,13 +123,18 @@ export class PipelineService extends BaseService<PipelineEntity> {
logger.info('定时器数量:', this.cron.getListSize());
}
registerTriggers(pipeline?: Pipeline) {
async registerTriggers(pipeline?: Pipeline, immediateTriggerOnce = false) {
if (pipeline?.triggers == null) {
return;
}
for (const trigger of pipeline.triggers) {
this.registerCron(pipeline.id, trigger);
}
if (immediateTriggerOnce) {
await this.trigger(pipeline.id);
await sleep(1000);
}
}
async trigger(id) {

View File

@@ -1,5 +1,5 @@
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { pluginRegistry } from '@certd/pipeline';
import { pluginGroups, pluginRegistry } from '@certd/pipeline';
@Provide()
@Scope(ScopeEnum.Singleton)
export class PluginService {
@@ -12,4 +12,8 @@ export class PluginService {
}
return list;
}
getGroups() {
return pluginGroups;
}
}

View File

@@ -9,8 +9,10 @@ export type CronTask = {
};
export class Cron {
logger;
immediateTriggerOnce: boolean;
constructor(opts) {
this.logger = opts.logger;
this.immediateTriggerOnce = opts.immediateTriggerOnce;
}
register(task: CronTask) {

View File

@@ -1,4 +1,4 @@
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, RunStrategy, TaskInput, utils } from '@certd/pipeline';
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline';
// @ts-ignore
import { ROAClient } from '@alicloud/pop-core';
import { AliyunAccess } from '../../access/index.js';
@@ -9,6 +9,7 @@ import { CertInfo } from '@certd/plugin-cert';
@IsTaskPlugin({
name: 'DeployCertToAliyunAckIngress',
title: '部署到阿里云AckIngress',
group: pluginGroups.aliyun.key,
input: {},
output: {},
default: {

View File

@@ -2,7 +2,7 @@ import {
AbstractTaskPlugin,
IAccessService,
ILogger,
IsTaskPlugin,
IsTaskPlugin, pluginGroups,
RunStrategy,
TaskInput,
} from '@certd/pipeline';
@@ -14,6 +14,7 @@ import { AliyunAccess } from '../../access/index.js';
@IsTaskPlugin({
name: 'DeployCertToAliyunCDN',
title: '部署证书至阿里云CDN',
group: pluginGroups.aliyun.key,
desc: '依赖证书申请前置任务自动部署域名证书至阿里云CDN',
default: {
strategy: {

View File

@@ -1,11 +1,4 @@
import {
AbstractTaskPlugin,
IAccessService,
IsTaskPlugin,
RunStrategy,
TaskInput,
TaskOutput,
} from '@certd/pipeline';
import { AbstractTaskPlugin, IAccessService, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import Core from '@alicloud/pop-core';
import { AliyunAccess } from '../../access/index.js';
import { appendTimeSuffix, checkRet, ZoneOptions } from '../../utils/index.js';
@@ -14,6 +7,7 @@ import { Logger } from 'log4js';
@IsTaskPlugin({
name: 'uploadCertToAliyun',
title: '上传证书到阿里云',
group: pluginGroups.aliyun.key,
desc: '',
default: {
strategy: {
@@ -76,9 +70,7 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
async execute(): Promise<void> {
console.log('开始部署证书到阿里云cdn');
const access = (await this.accessService.getById(
this.accessId
)) as AliyunAccess;
const access = (await this.accessService.getById(this.accessId)) as AliyunAccess;
const client = this.getClient(access);
const certName = appendTimeSuffix(this.name);
const params = {
@@ -92,11 +84,7 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
method: 'POST',
};
const ret = (await client.request(
'CreateUserCertificate',
params,
requestOption
)) as any;
const ret = (await client.request('CreateUserCertificate', params, requestOption)) as any;
checkRet(ret);
this.logger.info('证书上传成功aliyunCertId=', ret.CertId);

View File

@@ -1,16 +1,10 @@
import {
AbstractTaskPlugin,
IAccessService,
ILogger,
IsTaskPlugin,
RunStrategy,
TaskInput,
} from '@certd/pipeline';
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo, CertReader } from '@certd/plugin-cert';
@IsTaskPlugin({
name: 'CloudflareDeployToCDN',
title: '部署证书到CF CDN',
group: pluginGroups.other.key,
desc: '暂未实现,不可用',
default: {
strategy: {

View File

@@ -1,10 +1,11 @@
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, RunStrategy, TaskInput } from '@certd/pipeline';
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { CertInfo, CertReader } from '@certd/plugin-cert';
import { K8sClient } from '@certd/lib-k8s';
@IsTaskPlugin({
name: 'demoTest',
title: 'Demo测试插件',
group: pluginGroups.other.key,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,

View File

@@ -1,16 +1,10 @@
import {
AbstractTaskPlugin,
IAccessService,
ILogger,
IsTaskPlugin,
RunStrategy,
TaskInput,
} from '@certd/pipeline';
import { AbstractTaskPlugin, IAccessService, ILogger, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { SshClient } from '../../lib/ssh.js';
@IsTaskPlugin({
name: 'hostShellExecute',
title: '执行远程主机脚本命令',
group: pluginGroups.host.key,
input: {},
default: {
strategy: {

Some files were not shown because too many files have changed in this diff Show More