Compare commits
139 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8515bce0 | ||
|
|
c747ffee5a | ||
|
|
7d601b45a2 | ||
|
|
8be886daf6 | ||
|
|
d471d2416d | ||
|
|
f4c00ee0b6 | ||
|
|
009c131819 | ||
|
|
b6722897a0 | ||
|
|
1b46278f86 | ||
|
|
1274f56da8 | ||
|
|
0f572f4cb3 | ||
|
|
cbe3498125 | ||
|
|
e6ab0b6864 | ||
|
|
5b3931ecb7 | ||
|
|
ddd70ab8ce | ||
|
|
ba4cc234ae | ||
|
|
3563a4cc36 | ||
|
|
0526734ca1 | ||
|
|
f4f8d45a8e | ||
|
|
b3153eed64 | ||
|
|
ba11febad6 | ||
|
|
0cea8db0f9 | ||
|
|
8b7572a9e5 | ||
|
|
dd20af4ba0 | ||
|
|
222ef2f850 | ||
|
|
b1117ed54a | ||
|
|
7ad4b55ee0 | ||
|
|
396dc34a84 | ||
|
|
9b4a31fa6a | ||
|
|
8c7f976ef5 | ||
|
|
01f61d3c73 | ||
|
|
69b4bcbd09 | ||
|
|
bb397fb8d0 | ||
|
|
17ecf05215 | ||
|
|
e340b3e6fa | ||
|
|
4ab8677173 | ||
|
|
343d803d8e | ||
|
|
c643d7edc3 | ||
|
|
a4b37d01ab | ||
|
|
a59eb0c4c7 | ||
|
|
2dcc3206e1 | ||
|
|
dc9040a68e | ||
|
|
5160b9fbd6 | ||
|
|
a2af45e1c7 | ||
|
|
0165ccbaac | ||
|
|
b817cb4a1b | ||
|
|
584378a32b | ||
|
|
6d9ef26eca | ||
|
|
1bc170b069 | ||
|
|
babd5897ae | ||
|
|
63ec5b5519 | ||
|
|
e5e468a463 | ||
|
|
ee65c9f47d | ||
|
|
f92935d93f | ||
|
|
d282045683 | ||
|
|
129bf53edc | ||
|
|
6113c388b7 | ||
|
|
764326ab16 | ||
|
|
262ad0b51c | ||
|
|
8cc2b64066 | ||
|
|
ceb4b76cdb | ||
|
|
80af1fa9e6 | ||
|
|
844fd4358c | ||
|
|
79b41954f9 | ||
|
|
5a4a7814e1 | ||
|
|
c4630aaf7b | ||
|
|
d35ad50254 | ||
|
|
b1cc6f2a9c | ||
|
|
0d94329940 | ||
|
|
04150e1c0a | ||
|
|
385757b54b | ||
|
|
ccfe922c30 | ||
|
|
b3e0546f78 | ||
|
|
aaaf8d7db3 | ||
|
|
b1b2cd088b | ||
|
|
d1ea61debc | ||
|
|
12cebea29e | ||
|
|
81a3fdbc29 | ||
|
|
fea4669d82 | ||
|
|
241f9ed383 | ||
|
|
3d06ce444c | ||
|
|
06fed944c9 | ||
|
|
5d225c2583 | ||
|
|
e626367a06 | ||
|
|
5c992c3214 | ||
|
|
5575c83970 | ||
|
|
6dabad76ba | ||
|
|
1c656f8b90 | ||
|
|
51b6fed468 | ||
|
|
f92d918a1e | ||
|
|
3e290f057f | ||
|
|
13eb0231ac | ||
|
|
6089f0aa8e | ||
|
|
b0c4050567 | ||
|
|
3f9244542d | ||
|
|
70b6098ee5 | ||
|
|
1656e91296 | ||
|
|
5b7df9c175 | ||
|
|
8d8600aaa8 | ||
|
|
54d136cc6a | ||
|
|
661293c189 | ||
|
|
d10d42e206 | ||
|
|
b780eab5f5 | ||
|
|
315e43746b | ||
|
|
526c48450b | ||
|
|
abd2dcf2e8 | ||
|
|
87defa569c | ||
|
|
b4db5518db | ||
|
|
a50b635424 | ||
|
|
40a794f624 | ||
|
|
6876790374 | ||
|
|
586725a15c | ||
|
|
34300a19a6 | ||
|
|
11def7e42a | ||
|
|
4f3fb3766e | ||
|
|
cbc3eb9453 | ||
|
|
c31bc0266a | ||
|
|
b6176d7629 | ||
|
|
bc2e78db39 | ||
|
|
fdda8985de | ||
|
|
be2f0aa435 | ||
|
|
513a5b49c1 | ||
|
|
0c50ede129 | ||
|
|
d5a17f9e6a | ||
|
|
4b09a0a27f | ||
|
|
cba38f6e12 | ||
|
|
a672043e2e | ||
|
|
e1c6d8a2d0 | ||
|
|
9041602cfd | ||
|
|
bcbefaaa35 | ||
|
|
925edef0a5 | ||
|
|
90c54fd9e0 | ||
|
|
95df56cc5c | ||
|
|
ebced940d4 | ||
|
|
b21db8da6b | ||
|
|
55c76cb89c | ||
|
|
de62abf0e7 | ||
|
|
0e859d32ee | ||
|
|
5840247f3e |
79
.github/workflows/build-image-for-test.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
name: build-image-for-test
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ['v2-dev']
|
||||||
|
paths:
|
||||||
|
- "build-dev.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@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: v2-dev
|
||||||
|
|
||||||
|
- 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: Use Node.js
|
||||||
|
# uses: actions/setup-node@v4
|
||||||
|
# with:
|
||||||
|
# node-version: 18
|
||||||
|
# cache: 'npm'
|
||||||
|
# working-directory: ./packages/ui/certd-client
|
||||||
|
- run: |
|
||||||
|
npm install -g pnpm@8.15.7
|
||||||
|
pnpm install
|
||||||
|
npm run build
|
||||||
|
working-directory: ./packages/ui/certd-client
|
||||||
|
|
||||||
|
- 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: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.dockerhub_username }}
|
||||||
|
password: ${{ secrets.dockerhub_password }}
|
||||||
|
|
||||||
|
- name: Build default platforms
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
context: ./packages/ui/
|
||||||
|
tags: |
|
||||||
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd-dev:latest
|
||||||
|
greper/certd-dev:latest
|
||||||
|
|
||||||
3
.github/workflows/build-image.yml
vendored
@@ -17,6 +17,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout Code
|
- name: Checkout Code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
lfs: true
|
||||||
|
|
||||||
- name: get_certd_version
|
- name: get_certd_version
|
||||||
id: get_certd_version
|
id: get_certd_version
|
||||||
|
|||||||
22
.github/workflows/deploy-demo.yml
vendored
@@ -2,8 +2,8 @@ name: deploy-demo
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['v2-dev']
|
branches: ['v2-dev']
|
||||||
# paths:
|
paths:
|
||||||
# - "deploy.trigger"
|
- "deploy.trigger"
|
||||||
workflow_run:
|
workflow_run:
|
||||||
workflows: [ "build-image" ]
|
workflows: [ "build-image" ]
|
||||||
types:
|
types:
|
||||||
@@ -21,6 +21,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout Code
|
- name: Checkout Code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: v2-dev
|
||||||
- name: get_certd_version
|
- name: get_certd_version
|
||||||
id: get_certd_version
|
id: get_certd_version
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v6
|
||||||
@@ -37,8 +40,7 @@ jobs:
|
|||||||
- uses: GuillaumeFalourd/wait-sleep-action@v1
|
- uses: GuillaumeFalourd/wait-sleep-action@v1
|
||||||
with:
|
with:
|
||||||
time: '10' # for 60 seconds
|
time: '10' # for 60 seconds
|
||||||
- name: Send HTTP request
|
- name: deploy-certd-demo
|
||||||
id: request
|
|
||||||
uses: tyrrrz/action-http-request@master
|
uses: tyrrrz/action-http-request@master
|
||||||
with:
|
with:
|
||||||
url: http://flow-openapi.aliyun.com/pipeline/webhook/lzCzlGrLCOHQaTMMt0mG
|
url: http://flow-openapi.aliyun.com/pipeline/webhook/lzCzlGrLCOHQaTMMt0mG
|
||||||
@@ -52,4 +54,14 @@ jobs:
|
|||||||
retry-count: 3
|
retry-count: 3
|
||||||
retry-delay: 5000
|
retry-delay: 5000
|
||||||
|
|
||||||
|
- name: deploy-certd-doc
|
||||||
|
uses: tyrrrz/action-http-request@master
|
||||||
|
with:
|
||||||
|
url: http://flow-openapi.aliyun.com/pipeline/webhook/IiSxLDp9aOhgDUxJPytv
|
||||||
|
method: POST
|
||||||
|
body: |
|
||||||
|
{}
|
||||||
|
headers: |
|
||||||
|
Content-Type: application/json
|
||||||
|
retry-count: 3
|
||||||
|
retry-delay: 5000
|
||||||
|
|||||||
3
.github/workflows/sync-to-gitee-dev.yml
vendored
@@ -13,9 +13,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout work repo # 1. 检出当前仓库(certd-sync-work)
|
- name: Checkout work repo # 1. 检出当前仓库(certd-sync-work)
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
lfs: true
|
||||||
- name: Set git user # 2. 给git命令设置用户名和邮箱,↙↙↙ 改成你的name和email
|
- name: Set git user # 2. 给git命令设置用户名和邮箱,↙↙↙ 改成你的name和email
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "xiaojunnuo"
|
git config --global user.name "xiaojunnuo"
|
||||||
|
|||||||
3
.github/workflows/sync-to-gitee.yml
vendored
@@ -13,9 +13,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout work repo # 1. 检出当前仓库(certd-sync-work)
|
- name: Checkout work repo # 1. 检出当前仓库(certd-sync-work)
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
lfs: true
|
||||||
- name: Set git user # 2. 给git命令设置用户名和邮箱,↙↙↙ 改成你的name和email
|
- name: Set git user # 2. 给git命令设置用户名和邮箱,↙↙↙ 改成你的name和email
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name "xiaojunnuo"
|
git config --global user.name "xiaojunnuo"
|
||||||
|
|||||||
78
CHANGELOG.md
@@ -3,6 +3,84 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复头像没有更新的bug ([9b4a31f](https://github.com/certd/certd/commit/9b4a31fa6a32b9cab2e22bd141cf96ca29120445))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 禁止页面缓存,点击tab页签可以刷新数据 ([7ad4b55](https://github.com/certd/certd/commit/7ad4b55ee000c1dd0747832b11107f32b0ffb889))
|
||||||
|
* 优化时间选择器,自动填写分钟和秒钟 ([396dc34](https://github.com/certd/certd/commit/396dc34a841c7d016b033736afdba8366fb2d211))
|
||||||
|
* cname 域名映射记录可读性优化 ([b1117ed](https://github.com/certd/certd/commit/b1117ed54a3ef015752999324ff72b821ef5e4b9))
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复历史记录不能按名称查询的bug ([6113c38](https://github.com/certd/certd/commit/6113c388b7fc58b11ca19ff05cc1286d096c8d28))
|
||||||
|
* pfx兼容windows server 2016 ([e5e468a](https://github.com/certd/certd/commit/e5e468a463f66d02f235de54b7c1e09ace5f1cb1))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 首页全新改版 ([63ec5b5](https://github.com/certd/certd/commit/63ec5b5519c760a3330569c0da6dac157302a330))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 管理控制台数据统计 ([babd589](https://github.com/certd/certd/commit/babd5897ae013ff7c04ebfcbfac8a00d84dd627c))
|
||||||
|
* 增加向导 ([6d9ef26](https://github.com/certd/certd/commit/6d9ef26ecab71d752c2c55d75aed4fb5f6c05a39))
|
||||||
|
* lego 升级到 4.19.2 ([129bf53](https://github.com/certd/certd/commit/129bf53edc9bbb001fe49fbd7e239bd1d09cc128))
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复lego No help topic for 错误 ([aaaf8d7](https://github.com/certd/certd/commit/aaaf8d7db34896cf8f2ff8f12eec1ab0cae58f0f))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持白山云cdn部署 ([b1b2cd0](https://github.com/certd/certd/commit/b1b2cd088b684eda764962abd61754c26a204d1c))
|
||||||
|
* 支持华为云cdn ([81a3fdb](https://github.com/certd/certd/commit/81a3fdbc29b71f380762008cc151493ec97458f9))
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 顶部菜单变...的bug ([6dabad7](https://github.com/certd/certd/commit/6dabad76baba96be0f8af36a3fbfb9f5182aecf1))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 默认证书更新时间设置为35天,增加腾讯云删除过期证书插件,可以避免腾讯云过期证书邮件 ([51b6fed](https://github.com/certd/certd/commit/51b6fed468eaa6f28ce4497ce303ace1a52abb96))
|
||||||
|
* 授权加密支持解密查看 ([5575c83](https://github.com/certd/certd/commit/5575c839705f6987ad2bdcd33256b0962c6a9c6a))
|
||||||
|
* 重置管理员密码同时启用管理员账户,避免之前禁用了,重置密码还是登录不进去 ([f92d918](https://github.com/certd/certd/commit/f92d918a1e28e29b794ad4754661ea760c18af46))
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复阿里云部署大杀器报插件_还未注册错误的bug ([abd2dcf](https://github.com/certd/certd/commit/abd2dcf2e85a545321bae6451406d081f773b132))
|
||||||
|
* 修复启动时自签证书无法保存的bug ([526c484](https://github.com/certd/certd/commit/526c48450bcd37b3ccded9b448f17de8140bdc6e))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 顶部菜单自定义 ([54d136c](https://github.com/certd/certd/commit/54d136cc6ae122f7c891b7a5c7232fe5de8e5cb5))
|
||||||
|
* 禁用readonly用户 ([d10d42e](https://github.com/certd/certd/commit/d10d42e20619bb55a50d636b8867ff33db4e3b4b))
|
||||||
|
* 限制其他用户流水线数量 ([315e437](https://github.com/certd/certd/commit/315e43746baf01682737f82e41579237a48409af))
|
||||||
|
* 用户管理优化头像上传 ([661293c](https://github.com/certd/certd/commit/661293c189a3abf3cdc953b5225192372f57930d))
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复对话框全屏按钮与关闭按钮重叠的bug ([95df56c](https://github.com/certd/certd/commit/95df56cc5ca5e3eb843cd17cb7078cde47729f1e))
|
||||||
|
* deprecated的运行时不要报错,只报警告 ([bcbefaa](https://github.com/certd/certd/commit/bcbefaaa35cf6d0eec085b3a2c5bfc7c6a8de9e1))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 更新certd本身的证书文档说明 ([0c50ede](https://github.com/certd/certd/commit/0c50ede129337b82df54575cbd2f4c2a783a0732))
|
||||||
|
* 支持同时监听https端口,7002 ([d5a17f9](https://github.com/certd/certd/commit/d5a17f9e6afd63fda2df0981118480f25a1fac2e))
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
187
README.md
@@ -5,7 +5,6 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
|||||||
|
|
||||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
||||||
|
|
||||||
|
|
||||||
## 一、特性
|
## 一、特性
|
||||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||||
|
|
||||||
@@ -13,10 +12,12 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
|||||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
||||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||||
* 邮件通知
|
* 邮件通知
|
||||||
* 私有化部署,保障数据安全
|
* 私有化部署,数据保存本地,镜像由Github Actions构建,过程公开透明
|
||||||
* 支持sqlite,postgresql数据库
|
* 支持sqlite,postgresql数据库
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 二、在线体验
|
## 二、在线体验
|
||||||
|
|
||||||
官方Demo地址,自助注册后体验
|
官方Demo地址,自助注册后体验
|
||||||
@@ -26,78 +27,47 @@ https://certd.handsfree.work/
|
|||||||
> 注意数据将不定期清理,不定期停止定时任务,生产使用请自行部署
|
> 注意数据将不定期清理,不定期停止定时任务,生产使用请自行部署
|
||||||
> 包含敏感信息,务必自己本地部署进行生产使用
|
> 包含敏感信息,务必自己本地部署进行生产使用
|
||||||
|
|
||||||
## 三、使用教程
|

|
||||||
本案例演示,如何配置自动申请证书,并部署到阿里云CDN,然后快要到期前自动更新证书并重新部署
|
|
||||||
|
## 三、使用教程
|
||||||
|
|
||||||
|
仅需3步,让你的证书永不过期
|
||||||
|
|
||||||
|
### 1. 创建证书流水线
|
||||||
|

|
||||||
|
|
||||||
|
> 添加成功后,就可以直接运行流水线申请证书了
|
||||||
|
|
||||||
|
### 2. 添加部署任务
|
||||||
|
当然我们一般需要把证书部署到应用上,certd支持海量的部署插件,您可以根据自身实际情况进行选择,比如部署到Nginx、阿里云、腾讯云、K8S、CDN、宝塔、1Panel等等
|
||||||
|
|
||||||
|
此处演示部署证书到主机的nginx上
|
||||||
|

|
||||||
|
|
||||||
|
### 3. 定时运行
|
||||||
|

|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||||
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
||||||
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||||
|
|
||||||
当前支持的部署插件列表
|
更多教程请访问文档网站 [certd.docmirror.cn](https://certd.docmirror.cn/)
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## 四、私有化部署
|
## 四、私有化部署
|
||||||
|
|
||||||
由于证书、授权信息等属于高度敏感数据,请务必私有化部署,保障数据安全
|
由于证书、授权信息等属于高度敏感数据,请务必私有化部署,保障数据安全
|
||||||
|
|
||||||
### 4.1 宝塔面板一键部署
|
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
||||||
|
|
||||||
1. 安装宝塔面板,前往 [宝塔面板](https://www.bt.cn/u/CL3JHS) 官网,选择9.2.0以上正式版的脚本下载安装
|
1. [宝塔面板方式部署](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
2. [1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
|
||||||
|
3. [Docker方式部署](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
4. [源码方式部署](https://certd.docmirror.cn/guide/install/source/)
|
||||||
|
|
||||||
2. 安装后登录宝塔面板,在菜单栏中点击 Docker,首次进入会提示安装Docker服务,点击立即安装,按提示完成安装
|
#### Docker镜像说明:
|
||||||
|
|
||||||
3. 安装完成后在应用商店中找到`certd`(要先点右上角更新应用),点击安装,配置域名等基本信息即可完成安装
|
|
||||||
|
|
||||||
### 4.2 宝塔面板容器编排部署
|
|
||||||
|
|
||||||
[宝塔面板容器编排部署教程](./doc/deploy/baota/baota.md)
|
|
||||||
|
|
||||||
### 4.3 Docker部署
|
|
||||||
#### 1. 安装docker、docker-compose
|
|
||||||
|
|
||||||
1.1 准备一台云服务器
|
|
||||||
* 【阿里云】云服务器2核2G,新老用户同享,99元/年,续费同价!【 [立即购买](https://www.aliyun.com/benefit?scm=20140722.M_10244282._.V_1&source=5176.11533457&userCode=qya11txb )】
|
|
||||||
* 【腾讯云】云服务器2核2G,新老用户同享,99元/年,续费同价!【 [立即购买](https://cloud.tencent.com/act/cps/redirect?redirect=6094&cps_key=b3ef73330335d7a6efa4a4bbeeb6b2c9&from=console)】
|
|
||||||
|
|
||||||
1.2 安装docker
|
|
||||||
|
|
||||||
https://docs.docker.com/engine/install/
|
|
||||||
选择对应的操作系统,按照官方文档执行命令即可
|
|
||||||
|
|
||||||
#### 2. 运行certd
|
|
||||||
|
|
||||||
[docker-compose.yaml 下载](https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml)
|
|
||||||
|
|
||||||
当前版本号: 
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 随便创建一个目录
|
|
||||||
mkdir certd
|
|
||||||
# 进入目录
|
|
||||||
cd certd
|
|
||||||
# 下载docker-compose.yaml文件,或者手动下载放到certd目录下
|
|
||||||
wget https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
|
||||||
|
|
||||||
# 可以根据需要修改里面的配置
|
|
||||||
# 1.修改镜像版本号【可选】
|
|
||||||
# 2.配置数据保存路径【可选】
|
|
||||||
# 3.修改端口号【可选】
|
|
||||||
vi docker-compose.yaml # 【可选】
|
|
||||||
|
|
||||||
# 启动certd
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
```
|
|
||||||
> 如果提示 没有compose命令,请安装docker-compose
|
|
||||||
> https://docs.docker.com/compose/install/linux/
|
|
||||||
|
|
||||||
#### 3. 镜像说明:
|
|
||||||
* 国内镜像地址:
|
* 国内镜像地址:
|
||||||
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
||||||
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7`、`[version]-armv7`
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7`、`[version]-armv7`
|
||||||
@@ -109,25 +79,7 @@ docker compose up -d
|
|||||||
* 镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
* 镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
||||||
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 4. 访问测试
|
|
||||||
|
|
||||||
http://your_server_ip:7001
|
|
||||||
默认账号密码:admin/123456
|
|
||||||
记得修改密码
|
|
||||||
|
|
||||||
### 4.4 源码部署
|
|
||||||
```shell
|
|
||||||
# 克隆代码
|
|
||||||
git clone https://github.com/certd/certd
|
|
||||||
git checkout v1.26.7 # 这里换成最新版本号
|
|
||||||
cd certd
|
|
||||||
# 启动服务
|
|
||||||
./start.sh
|
|
||||||
# 数据默认保存在 ./packages/ui/certd-server/data 目录下,注意数据备份
|
|
||||||
```
|
|
||||||
如果是windows,请先安装`git for windows` ,然后右键,选择`open git bash here`打开终端,再执行`./start.sh`命令
|
|
||||||
|
|
||||||
|
|
||||||
## 五、 升级
|
## 五、 升级
|
||||||
@@ -151,7 +103,7 @@ docker compose up -d
|
|||||||
|
|
||||||
|
|
||||||
## 六、一些说明
|
## 六、一些说明
|
||||||
* 本项目ssl证书提供商为letencrypt
|
* 本项目ssl证书提供商为letencrypt/Google/ZeroSSL
|
||||||
* 申请过程遵循acme协议
|
* 申请过程遵循acme协议
|
||||||
* 需要验证域名所有权,一般有两种方式(目前本项目仅支持dns-01)
|
* 需要验证域名所有权,一般有两种方式(目前本项目仅支持dns-01)
|
||||||
* http-01: 在网站根目录下放置一份txt文件
|
* http-01: 在网站根目录下放置一份txt文件
|
||||||
@@ -165,48 +117,26 @@ docker compose up -d
|
|||||||
|
|
||||||
## 七、不同平台的设置说明
|
## 七、不同平台的设置说明
|
||||||
|
|
||||||
* [Cloudflare](./docs/plugins/cf/cf.md)
|
* 已迁移到新的文档网站,请到常见问题章节查看
|
||||||
* [腾讯云](./docs/plugins/tencent/tencent.md)
|
* [最新文档站链接 https://certd.docmirror.cn](https://certd.docmirror.cn/)
|
||||||
* [windows主机](./docs/plugins/host/host.md)
|
|
||||||
* [google证书](./docs/plugins/google/google.md)
|
|
||||||
* [群晖部署certd及证书更新教程](./docs/plugins/synology/index.md)
|
|
||||||
|
|
||||||
* [CNAME证书校验方式说明](./docs/feature/cname/index.md)
|
|
||||||
|
|
||||||
## 八、问题处理
|
## 八、问题处理
|
||||||
### 7.1 忘记管理员密码
|
### 7.1 忘记管理员密码
|
||||||
解决方法如下:
|
[重置管理员密码方法](https://certd.docmirror.cn/guide/use/forgotpasswd/)
|
||||||
1. 修改docker-compose.yaml文件,将环境变量`certd_system_resetAdminPasswd`改为`true`
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
certd:
|
|
||||||
environment: # 环境变量
|
|
||||||
- certd_system_resetAdminPasswd=false
|
|
||||||
```
|
|
||||||
2. 重启容器
|
|
||||||
```shell
|
|
||||||
docker compose up -d
|
|
||||||
docker logs -f --tail 500 certd
|
|
||||||
# 观察日志,当日志中输出“重置1号管理员用户的密码完成”,即可操作下一步
|
|
||||||
```
|
|
||||||
3. 修改docker-compose.yaml,将`certd_system_resetAdminPasswd`改回`false`
|
|
||||||
4. 再次重启容器
|
|
||||||
```shell
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
5. 使用`admin/123456`登录系统,请及时修改管理员密码
|
|
||||||
|
|
||||||
## 九、联系作者
|
## 九、联系作者
|
||||||
如有疑问,欢迎加入群聊(请备注certd)
|
如有疑问,欢迎加入群聊(请备注certd)
|
||||||
* QQ群:141236433
|
|
||||||
* 微信群:
|
|
||||||

|
|
||||||
|
|
||||||
|
| 加群 | 微信群 | QQ群 |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| 二维码 | <img height="230" src="./docs/guide/contact/images/wx.png"> | <img height="230" src="./docs/guide/contact/images/qq.png"> |
|
||||||
|
|
||||||
|
也可以加作者好友
|
||||||
|
|
||||||
|
| 加作者好友 | 微信 QQ |
|
||||||
|
|---------|-------------------------------------------------------------|
|
||||||
|
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||||
|
|
||||||
加作者好友
|
|
||||||
<p align="center">
|
|
||||||
<img height="230" src="./doc/images/me.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## 十、捐赠
|
## 十、捐赠
|
||||||
************************
|
************************
|
||||||
@@ -222,18 +152,18 @@ https://afdian.com/a/greper
|
|||||||
|
|
||||||
专业版特权对比
|
专业版特权对比
|
||||||
|
|
||||||
| 功能 | 免费版 | 专业版 |
|
| 功能 | 免费版 | 专业版 |
|
||||||
|---------|------------------------|-----------------------|
|
|---------|-------------------|-----------------------|
|
||||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
| 自动部署插件 | 阿里云、腾讯云、七牛云、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||||
| 发邮件功能 | 需要配置 | 免配置 |
|
| 发邮件功能 | 需要配置 | 免配置 |
|
||||||
| 证书流水线条数 | 10条 | 无限制 |
|
| 证书流水线条数 | 10条 | 无限制 |
|
||||||
|
|
||||||
************************
|
************************
|
||||||
|
|
||||||
## 十一、贡献代码
|
## 十一、贡献代码
|
||||||
|
|
||||||
1. 本地开发 [贡献插件教程](./doc/dev/development.md)
|
1. 本地开发 [贡献插件教程](https://certd.docmirror.cn/guide/development/)
|
||||||
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
||||||
1. 可以调整开源协议以使其更严格或更宽松。
|
1. 可以调整开源协议以使其更严格或更宽松。
|
||||||
2. 可以用于商业用途。
|
2. 可以用于商业用途。
|
||||||
@@ -242,14 +172,17 @@ https://afdian.com/a/greper
|
|||||||
|
|
||||||
## 十二、 开源许可
|
## 十二、 开源许可
|
||||||
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
||||||
* 允许个人和公司使用、复制、修改和分发本项目,禁止任何形式的商业用途
|
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
||||||
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
||||||
* 如需商业授权,请联系作者。
|
* 如需商业授权,请联系作者。
|
||||||
|
|
||||||
## 十三、我的其他项目(求Star)
|
## 十三、我的其他项目(求Star)
|
||||||
* [袖手GPT](https://ai.handsfree.work/) ChatGPT,国内可用,无需FQ,每日免费额度
|
|
||||||
* [fast-crud](https://gitee.com/fast-crud/fast-crud/) 基于vue3的crud快速开发框架
|
| 项目名称 | stars | 项目描述 |
|
||||||
* [dev-sidecar](https://github.com/docmirror/dev-sidecar/) 直连访问github工具,无需FQ,解决github无法访问的问题
|
|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------------------------------|
|
||||||
|
| [袖手AI](https://ai.handsfree.work/) | | 袖手GPT,国内可用,无需FQ,每日免费额度 |
|
||||||
|
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | 基于vue3的crud快速开发框架 |
|
||||||
|
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | 直连访问github工具,无需FQ,解决github无法访问的问题 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
build-dev.trigger
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -1 +1 @@
|
|||||||
10:38
|
2
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
# 宝塔部署教程
|
|
||||||
|
|
||||||
## 编排模版部署
|
|
||||||
|
|
||||||
### 创建docker模版
|
|
||||||
打开docker-compose.yaml,
|
|
||||||
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
|
||||||
|
|
||||||
整个内容复制下来
|
|
||||||
|
|
||||||
然后到宝塔里面进到docker的编排模版,新建模版
|
|
||||||

|
|
||||||
|
|
||||||
### 启动应用
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
等待启动完成
|
|
||||||
|
|
||||||
### 打开应用
|
|
||||||
|
|
||||||
http://ip:7001
|
|
||||||
|
|
||||||
|
|
||||||
## 二、一键应用部署
|
|
||||||
需要宝塔9.2.0版本
|
|
||||||
|
|
||||||
### 应用商店
|
|
||||||
进入应用商店,更新应用列表
|
|
||||||
|
|
||||||
### 搜索certd
|
|
||||||
点击安装
|
|
||||||
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,96 +0,0 @@
|
|||||||
# 本地开发
|
|
||||||
欢迎贡献插件
|
|
||||||
|
|
||||||
## 1.本地调试运行
|
|
||||||
|
|
||||||
### 克隆代码
|
|
||||||
```shell
|
|
||||||
|
|
||||||
# 克隆代码
|
|
||||||
git clone https://github.com/certd/certd
|
|
||||||
|
|
||||||
#进入项目目录
|
|
||||||
cd certd
|
|
||||||
|
|
||||||
# 切换到最新版本代码
|
|
||||||
git checkout v1.26.7 # 这里换成最新版本号
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### 修改pnpm-workspace.yaml文件
|
|
||||||
重要:否则无法正确加载专业版的access和plugin
|
|
||||||
```yaml
|
|
||||||
# pnpm-workspace.yaml
|
|
||||||
packages:
|
|
||||||
- 'packages/**' # <--------------注释掉这一行,PR时不要提交此修改
|
|
||||||
- 'packages/ui/**'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 安装依赖和初始化:
|
|
||||||
```shell
|
|
||||||
# 安装pnpm,如果提示npm命令不存在,就需要先安装nodejs
|
|
||||||
npm install -g pnpm@8.15.7 --registry=https://registry.npmmirror.com
|
|
||||||
|
|
||||||
# 使用国内镜像源,如果有代理,就不需要
|
|
||||||
pnpm config set registry https://registry.npmmirror.com
|
|
||||||
# 安装依赖
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
# 初始化构建
|
|
||||||
npm run init
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动 server:
|
|
||||||
```shell
|
|
||||||
cd packages/ui/certd-server
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动 client:
|
|
||||||
```shell
|
|
||||||
cd packages/ui/certd-client
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# 会自动打开浏览器,确认正常运行
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## 开发插件
|
|
||||||
进入 `packages/ui/certd-server/src/plugins`
|
|
||||||
|
|
||||||
### 1.复制`plugin-demo`目录作为你的插件目录
|
|
||||||
比如你想做`cloudflare`的插件,那么你可以复制`plugin-demo`目录,将其命名成`plugin-cloudflare`。
|
|
||||||
以下均以`plugin-cloudflare`为例进行说明,你需要将其替换成你的插件名称
|
|
||||||
|
|
||||||
### 2. access授权
|
|
||||||
如果这是一个新的平台,它应该有授权方式,比如accessKey accessSecret之类的
|
|
||||||
参考`plugin-cloudflare/access.ts` 修改为你要做的平台的`access`
|
|
||||||
这样用户就可以在`certd`后台中创建这种授权凭证了
|
|
||||||
|
|
||||||
### 3. dns-provider
|
|
||||||
如果域名是这个平台进行解析的,那么你需要实现dns-provider,(申请证书需要)
|
|
||||||
参考`plugin-cloudflare/dns-provider.ts` 修改为你要做的平台的`dns-provider`
|
|
||||||
|
|
||||||
### 4. plugin-deploy
|
|
||||||
如果这个平台有需要部署证书的地方
|
|
||||||
参考`plugin-cloudflare/plugins/plugin-deploy-to-xx.ts` 修改为你要做的平台的`plugin-deploy-to-xx`
|
|
||||||
|
|
||||||
### 5. 增加导入
|
|
||||||
在`plugin-cloudflare/index.ts`中增加你的插件的`import`
|
|
||||||
```ts
|
|
||||||
export * from './dns-provider'
|
|
||||||
export * from './access'
|
|
||||||
export * from './plugins/plugin-deploy-to-xx'
|
|
||||||
````
|
|
||||||
|
|
||||||
在`./src/plugins/index.ts`中增加`import`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export * from "./plugin-cloudflare.js"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 重启服务进行调试
|
|
||||||
刷新浏览器,检查你的插件是否工作正常, 确保能够正常进行证书申请和部署
|
|
||||||
|
|
||||||
## 提交PR
|
|
||||||
我们将尽快审核PR
|
|
||||||
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 374 KiB |
|
Before Width: | Height: | Size: 327 KiB |
@@ -11,33 +11,28 @@ services:
|
|||||||
ports: # 端口映射
|
ports: # 端口映射
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号
|
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号
|
||||||
- "7001:7001"
|
- "7001:7001"
|
||||||
|
# ↓↓↓↓ ---------------------------------------------------------- https端口,可以根据实际情况,是否暴露相关服务端口
|
||||||
|
- "7002:7002"
|
||||||
dns:
|
dns:
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- 如果出现getaddrinfo ENOTFOUND等错误,可以尝试修改或注释dns配置
|
# ↓↓↓↓ ---------------------------------------------------------- 如果出现getaddrinfo ENOTFOUND等错误,可以尝试修改或注释dns配置
|
||||||
- 223.5.5.5
|
- 223.5.5.5
|
||||||
- 223.6.6.6
|
- 223.6.6.6
|
||||||
|
# ↓↓↓↓ ---------------------------------------------------------- 如果你服务器在腾讯云,可以用这个dns地址
|
||||||
|
# - 119.29.29.29
|
||||||
|
# - 182.254.116.116
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- 如果你服务器部署在国外,可以用8.8.8.8替换上面的dns
|
# ↓↓↓↓ ---------------------------------------------------------- 如果你服务器部署在国外,可以用8.8.8.8替换上面的dns
|
||||||
# - 8.8.8.8
|
# - 8.8.8.8
|
||||||
# - 8.8.4.4
|
# - 8.8.4.4
|
||||||
# extra_hosts:
|
# extra_hosts:
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- 这里可以配置自定义hosts,外网域名可以指向本地局域网ip地址
|
# ↓↓↓↓ ---------------------------------------------------------- 这里可以配置自定义hosts,外网域名可以指向本地局域网ip地址
|
||||||
# - "localdomain.comm:192.168.1.3"
|
# - "localdomain.comm:192.168.1.3"
|
||||||
environment: # 环境变量
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
# 设置环境变量即可自定义certd配置
|
# 设置环境变量即可自定义certd配置
|
||||||
# 配置项见: packages/ui/certd-server/src/config/config.default.ts
|
# 配置项见: packages/ui/certd-server/src/config/config.default.ts
|
||||||
# 配置规则: certd_ + 配置项, 点号用_代替
|
# 配置规则: certd_ + 配置项, 点号用_代替
|
||||||
|
|
||||||
# ↓↓↓↓ ------------------------------------ 这里可以设置http代理
|
|
||||||
#- HTTPS_PROXY=http://xxxxxx:xx
|
|
||||||
#- HTTP_PROXY=http://xxxxxx:xx
|
|
||||||
# ↓↓↓↓ ----------------------------- 如果忘记管理员密码,可以设置为true,重启之后,管理员密码将改成123456,然后请及时修改回false
|
# ↓↓↓↓ ----------------------------- 如果忘记管理员密码,可以设置为true,重启之后,管理员密码将改成123456,然后请及时修改回false
|
||||||
- certd_system_resetAdminPasswd=false
|
- certd_system_resetAdminPasswd=false
|
||||||
# ↓↓↓↓ -------------------------- 如果设置为true,启动后所有配置了cron的流水线任务都将被立即触发一次
|
|
||||||
- certd_cron_immediateTriggerOnce=false
|
|
||||||
# ↓↓↓↓ -------------------------------- 配置证书和key,则表示https方式启动,使用https协议访问,https://your.domain:7001
|
|
||||||
#- certd_koa_key=./data/ssl/cert.key
|
|
||||||
#- certd_koa_cert=./data/ssl/cert.crt
|
|
||||||
|
|
||||||
# ↓↓↓↓ ------------------------------- 使用postgresql数据库
|
# ↓↓↓↓ ------------------------------- 使用postgresql数据库
|
||||||
# - certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录
|
# - certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录
|
||||||
# - certd_typeorm_dataSource_default_type=postgres # 数据库类型
|
# - certd_typeorm_dataSource_default_type=postgres # 数据库类型
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import lightbox from "vitepress-plugin-lightbox";
|
|||||||
// https://vitepress.dev/reference/site-config
|
// https://vitepress.dev/reference/site-config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: "Certd",
|
title: "Certd",
|
||||||
description: "Certd帮助文档,Certd是一款开源免费的全自动SSL证书管理工具;自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔。",
|
description: "Certd帮助文档,Certd是一款开源免费的全自动SSL证书管理工具;证书自动化申请部署流水线;自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔。",
|
||||||
markdown: {
|
markdown: {
|
||||||
config: (md) => {
|
config: (md) => {
|
||||||
// Use lightbox plugin
|
// Use lightbox plugin
|
||||||
@@ -23,12 +23,11 @@ export default defineConfig({
|
|||||||
// ],
|
// ],
|
||||||
["meta", {
|
["meta", {
|
||||||
name: "keywords",
|
name: "keywords",
|
||||||
content: "证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具、Certd、SSL证书自动部署、证书自动化,https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署"
|
content: "证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具、Certd、SSL证书自动部署、证书自动化,https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署,SSL平台,证书管理平台,证书流水线"
|
||||||
}],
|
|
||||||
["meta", {
|
|
||||||
name: "google-site-verification",
|
|
||||||
content: "V5XLTSnXoT15uQotwpxJoQolUo2d5UbSL-TacsyOsC0"
|
|
||||||
}],
|
}],
|
||||||
|
["meta", { name: "google-site-verification",content: "V5XLTSnXoT15uQotwpxJoQolUo2d5UbSL-TacsyOsC0"}],
|
||||||
|
//<meta name="baidu-site-verification" content="codeva-MiWN8Y07Ua" />
|
||||||
|
["meta", {name: "baidu-site-verification",content: "codeva-MiWN8Y07Ua"}],
|
||||||
["link", { rel: "icon", href: "/static/logo/logo.svg" }]
|
["link", { rel: "icon", href: "/static/logo/logo.svg" }]
|
||||||
],
|
],
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
@@ -95,8 +94,12 @@ export default defineConfig({
|
|||||||
{ text: "腾讯云密钥获取", link: "/guide/use/tencent/" },
|
{ text: "腾讯云密钥获取", link: "/guide/use/tencent/" },
|
||||||
{ text: "连接windows主机", link: "/guide/use/host/windows.md" },
|
{ text: "连接windows主机", link: "/guide/use/host/windows.md" },
|
||||||
{ text: "Google EAB获取", link: "/guide/use/google/" },
|
{ text: "Google EAB获取", link: "/guide/use/google/" },
|
||||||
|
{ text: "阿里云相关", link: "/guide/use/aliyun/" },
|
||||||
{ text: "忘记密码", link: "/guide/use/forgotpasswd/" },
|
{ text: "忘记密码", link: "/guide/use/forgotpasswd/" },
|
||||||
{ text: "数据备份", link: "/guide/use/backup/" },
|
{ text: "数据备份", link: "/guide/use/backup/" },
|
||||||
|
{ text: "Certd本身的证书更新", link: "/guide/use/https/index.md" },
|
||||||
|
{ text: "js脚本插件使用", link: "/guide/use/custom-script/index.md" },
|
||||||
|
{ text: "邮箱配置", link: "/guide/use/email/index.md" },
|
||||||
{ text: "如何贡献代码", link: "/guide/development/index.md" },
|
{ text: "如何贡献代码", link: "/guide/development/index.md" },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,19 +2,14 @@
|
|||||||
|
|
||||||
## 1. 交流群
|
## 1. 交流群
|
||||||
如有疑问,欢迎加入群聊(请备注certd)
|
如有疑问,欢迎加入群聊(请备注certd)
|
||||||
### QQ群:141236433
|
如有疑问,欢迎加入群聊(请备注certd)
|
||||||
<p align="center">
|
|
||||||
<img height="230" src="./images/qq.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
### 微信群:
|
|
||||||
<p align="center">
|
|
||||||
<img height="230" src="./images/wx.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
| 加群 | 微信群 | QQ群 |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| 二维码 | <img height="230" src="./images/wx.png"> | <img height="230" src="./images/qq.png"> |
|
||||||
|
|
||||||
## 2. 加作者好友
|
## 2. 加作者好友
|
||||||
<p align="center">
|
|
||||||
<img height="230" src="./images/me.png">
|
| 加作者好友 | 微信 QQ |
|
||||||
</p>
|
|---------|-------------------------------------------------------------|
|
||||||
|
| 二维码 | <img height="230" src="./images/me.png"> |
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
```shell
|
```shell
|
||||||
|
|
||||||
# 克隆代码
|
# 克隆代码
|
||||||
git clone https://github.com/certd/certd
|
git clone https://github.com/certd/certd --depth=1
|
||||||
|
|
||||||
#进入项目目录
|
#进入项目目录
|
||||||
cd certd
|
cd certd
|
||||||
|
|
||||||
# 切换到最新版本代码
|
# 切换到最新版本代码【如果v2分支无法编译,请尝试切换到最新版tag】
|
||||||
git checkout v1.26.7 # 这里换成最新版本号
|
# git checkout v1.27.0 # 这里换成最新版本号
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -28,3 +28,7 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
|||||||
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||||
* 设置每天自动运行,当证书过期前20天,会自动重新申请证书并部署
|
* 设置每天自动运行,当证书过期前20天,会自动重新申请证书并部署
|
||||||
|
|
||||||
|
## 三、证书颁发机构对比
|
||||||
|
* Let's Encrypt:申请最简单。
|
||||||
|
* Google: 大厂光环,兼容性好,需要翻墙获取EAB。
|
||||||
|
* ZeroSSL: 有数量限制,获取EAB无需翻墙。
|
||||||
@@ -23,8 +23,11 @@ https://1panel.cn/docs/installation/online_installation/
|
|||||||
|
|
||||||
3. 访问测试
|
3. 访问测试
|
||||||
|
|
||||||
http://ip:7001
|
http://ip:7001
|
||||||
|
https://ip:7002
|
||||||
|
默认账号密码
|
||||||
|
admin/123456
|
||||||
|
登录后请及时修改密码
|
||||||
|
|
||||||
## 三、升级
|
## 三、升级
|
||||||
|
|
||||||
@@ -42,3 +45,7 @@ http://ip:7001
|
|||||||
|
|
||||||
> 默认数据保存在`/data/certd`目录下,可以手动备份
|
> 默认数据保存在`/data/certd`目录下,可以手动备份
|
||||||
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
||||||
|
|
||||||
|
## 五、备份恢复
|
||||||
|
|
||||||
|
将备份的`db.sqlite`覆盖到原来的位置即可
|
||||||
|
|||||||
BIN
docs/guide/install/baota/images/upgrade.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
@@ -31,19 +31,26 @@
|
|||||||
|
|
||||||
## 二、访问应用
|
## 二、访问应用
|
||||||
|
|
||||||
http://ip:7001
|
http://ip:7001
|
||||||
|
https://ip:7002
|
||||||
|
默认账号密码
|
||||||
|
admin/123456
|
||||||
|
登录后请及时修改密码
|
||||||
|
|
||||||
## 三、如何升级
|
## 三、如何升级
|
||||||
|
|
||||||
### 1. 通用方式
|
### 1. 应用商店安装,直接更新镜像即可
|
||||||
|
|
||||||
先主机上拉取最新镜像,然后面板上重启容器
|

|
||||||
|
|
||||||
|
|
||||||
|
### 2. latest更新方式
|
||||||
|
在主机上拉取最新镜像,然后面板上重启容器
|
||||||
```shell
|
```shell
|
||||||
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 固定版本号方式
|
### 3. 固定版本号方式
|
||||||
|
|
||||||
修改容器编排模版中的镜像版本号,然后面板上重启容器
|
修改容器编排模版中的镜像版本号,然后面板上重启容器
|
||||||
```shell
|
```shell
|
||||||
@@ -71,3 +78,7 @@ services:
|
|||||||
### 4.3 自动备份
|
### 4.3 自动备份
|
||||||
|
|
||||||
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
||||||
|
|
||||||
|
## 五、备份恢复
|
||||||
|
|
||||||
|
将备份的`db.sqlite`覆盖到原来的位置即可
|
||||||
|
|||||||
@@ -45,9 +45,10 @@ docker compose up -d
|
|||||||
|
|
||||||
### 3. 访问测试
|
### 3. 访问测试
|
||||||
|
|
||||||
http://your_server_ip:7001
|
http://your_server_ip:7001
|
||||||
默认账号密码:admin/123456
|
https://your_server_ip:7002
|
||||||
记得修改密码
|
默认账号密码:admin/123456
|
||||||
|
记得修改密码
|
||||||
|
|
||||||
|
|
||||||
## 二、升级
|
## 二、升级
|
||||||
@@ -64,6 +65,10 @@ docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
|||||||
docker compose down
|
docker compose down
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
## 三、数据备份
|
||||||
> 数据默认存在`/data/certd`目录下,不用担心数据丢失
|
> 数据默认存在`/data/certd`目录下,不用担心数据丢失
|
||||||
> 建议配置一条[数据库备份流水线](../../use/backup/) 自动备份
|
> 建议配置一条[数据库备份流水线](../../use/backup/) 自动备份
|
||||||
|
|
||||||
|
## 四、备份恢复
|
||||||
|
|
||||||
|
将备份的`db.sqlite`覆盖到原来的位置即可
|
||||||
@@ -17,7 +17,8 @@ cd certd
|
|||||||
|
|
||||||
### 访问测试
|
### 访问测试
|
||||||
|
|
||||||
http://your_server_ip:7001
|
http://your_server_ip:7001
|
||||||
|
https://your_server_ip:7002
|
||||||
默认账号密码:admin/123456
|
默认账号密码:admin/123456
|
||||||
记得修改密码
|
记得修改密码
|
||||||
|
|
||||||
@@ -33,8 +34,12 @@ kill -9 $(lsof -t -i:7001)
|
|||||||
# 重新编译启动
|
# 重新编译启动
|
||||||
./start.sh
|
./start.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 三、数据备份
|
||||||
> 数据默认保存在 `./packages/ui/certd-server/data` 目录下
|
> 数据默认保存在 `./packages/ui/certd-server/data` 目录下
|
||||||
> 建议配置一条[数据库备份流水线](../../use/backup/) 自动备份
|
> 建议配置一条[数据库备份流水线](../../use/backup/) 自动备份
|
||||||
|
|
||||||
|
|
||||||
|
## 四、备份恢复
|
||||||
|
|
||||||
|
将备份的`db.sqlite`覆盖到原来的位置即可
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ https://certd.handsfree.work/
|
|||||||
|
|
||||||
### 2. 访问测试
|
### 2. 访问测试
|
||||||
|
|
||||||
http://your_server_ip:7001
|
http://your_server_ip:7001
|
||||||
|
https://your_server_ip:7002
|
||||||
默认账号密码:admin/123456
|
默认账号密码:admin/123456
|
||||||
记得修改密码
|
记得修改密码
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# 数据库自动备份
|
# 数据库自动备份
|
||||||
|
|
||||||
|
## 一、手动备份
|
||||||
|
数据库文件根据不同的部署方式保存的位置不一样,您可以手动复制出来进行备份
|
||||||
|
|
||||||
|
* docker: 默认保存在`/data/certd/db.sqlite`
|
||||||
|
* 源码: 默认保存在 `./packages/ui/certd-server/data/db.sqlite`
|
||||||
|
* 宝塔: [手动数据备份位置](https://certd.docmirror.cn/guide/install/baota/#%E5%9B%9B%E3%80%81%E6%95%B0%E6%8D%AE%E5%A4%87%E4%BB%BD)
|
||||||
|
* 1panel: 默认保存在`/data/certd/db.sqlite`
|
||||||
|
|
||||||
|
|
||||||
|
## 二、自动备份
|
||||||
|
通过配置数据库自动备份流水线实现数据备份
|
||||||
|
|
||||||
## 1. 创建自动备份流水线
|
## 1. 创建自动备份流水线
|
||||||

|

|
||||||
|
|
||||||
@@ -7,7 +19,12 @@
|
|||||||

|

|
||||||
|
|
||||||
## 3. 选择备份方法
|
## 3. 选择备份方法
|
||||||

|

|
||||||
|
|
||||||
## 4. 配置定时和失败通知
|
## 4. 配置定时和失败通知
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
## 三、备份恢复
|
||||||
|
|
||||||
|
将备份的`db.sqlite`覆盖到原来的位置即可
|
||||||
80
docs/guide/use/custom-script/index.md
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# 自定义脚本插件
|
||||||
|
|
||||||
|
## 1. 介绍
|
||||||
|
|
||||||
|
自定义脚本插件是一个通用的插件,可以通过编写脚本来实现各种功能,例如:调用第三方API、执行系统命令、发送邮件等。
|
||||||
|
|
||||||
|
## 2. 使用示例
|
||||||
|
```js
|
||||||
|
const certPem = ctx.self.cert.crt
|
||||||
|
const certKey = ctx.self.cert.key
|
||||||
|
|
||||||
|
//axios发起http请求上传证书
|
||||||
|
const res = await ctx.http.request({
|
||||||
|
url:"your_cert_deploy_url",
|
||||||
|
method:"post",
|
||||||
|
data:{
|
||||||
|
crt : certPem,
|
||||||
|
key : certKey
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ctx.logger.info("上传成功",res.data)
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
## 3. API
|
||||||
|
下面是`ctx`对象的`typescript`类型定义
|
||||||
|
|
||||||
|
```ts
|
||||||
|
|
||||||
|
type ctx = {
|
||||||
|
CertReader: typeof CertReader;
|
||||||
|
self: CustomScriptPlugin;
|
||||||
|
//流水线定义
|
||||||
|
pipeline: Pipeline;
|
||||||
|
//步骤定义
|
||||||
|
step: Step;
|
||||||
|
//日志
|
||||||
|
logger: Logger;
|
||||||
|
//当前步骤输入参数跟上一次执行比较是否有变化
|
||||||
|
inputChanged: boolean;
|
||||||
|
//授权获取服务
|
||||||
|
accessService: IAccessService;
|
||||||
|
//邮件服务
|
||||||
|
emailService: IEmailService;
|
||||||
|
//cname记录服务
|
||||||
|
cnameProxyService: ICnameProxyService;
|
||||||
|
//插件配置服务
|
||||||
|
pluginConfigService: IPluginConfigService;
|
||||||
|
//流水线上下文
|
||||||
|
pipelineContext: IContext;
|
||||||
|
//用户上下文
|
||||||
|
userContext: IContext;
|
||||||
|
//http请求客户端
|
||||||
|
http: HttpClient; // http.request(AxiosConfig)
|
||||||
|
//文件存储
|
||||||
|
fileStore: FileStore;
|
||||||
|
//上一次执行结果状态
|
||||||
|
lastStatus?: Runnable;
|
||||||
|
//用户取消信号
|
||||||
|
signal: AbortSignal;
|
||||||
|
//工具类
|
||||||
|
utils: typeof utils;
|
||||||
|
//用户信息
|
||||||
|
user: UserInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CertInfo = {
|
||||||
|
crt:string; //fullchain证书,即 cert.pem, cert.crt
|
||||||
|
key:string; // 私钥
|
||||||
|
ic: string; //中间证书
|
||||||
|
pfx: string;//PFX证书,base64编码
|
||||||
|
der: string;//DER证书,base64编码
|
||||||
|
}
|
||||||
|
|
||||||
|
type CustomScriptPlugin = {
|
||||||
|
//可以获取证书
|
||||||
|
cert: CertInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
BIN
docs/guide/use/email/images/qq-0.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/guide/use/email/images/qq-1.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
docs/guide/use/email/images/qq-11.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/guide/use/email/images/qq-2.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/guide/use/email/images/qq-3.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
23
docs/guide/use/email/index.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 邮箱配置
|
||||||
|
|
||||||
|
|
||||||
|
## 腾讯企业邮箱配置
|
||||||
|
1. 开启smtp
|
||||||
|

|
||||||
|
2. 获取授权码作为密码
|
||||||
|

|
||||||
|

|
||||||
|
3. 填写域名、端口和密码
|
||||||
|

|
||||||
|
|
||||||
|
## QQ邮箱配置
|
||||||
|
1. smtp配置
|
||||||
|
```yaml
|
||||||
|
smtp域名: smtp.qq.com
|
||||||
|
smtp端口: 465
|
||||||
|
密码: 授权码,获取方式见下方
|
||||||
|
是否SSL: 是
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 获取授权码
|
||||||
|

|
||||||
@@ -4,7 +4,10 @@
|
|||||||
|
|
||||||
## windows开启OpenSSH Server
|
## windows开启OpenSSH Server
|
||||||
### 1. 安装OpenSSH Server
|
### 1. 安装OpenSSH Server
|
||||||
请前往Microsoft官方文档查看如何开启openSSH
|
|
||||||
|
* 下载安装包安装: https://github.com/PowerShell/Win32-OpenSSH/releases OpenSSH-Win64-vxx.xx.x.msi
|
||||||
|
|
||||||
|
* 前往Microsoft官方文档查看如何开启openSSH,以及其他设置
|
||||||
https://learn.microsoft.com/zh-cn/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui#install-openssh-for-windows
|
https://learn.microsoft.com/zh-cn/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui#install-openssh-for-windows
|
||||||
|
|
||||||
### 2. 启动OpenSSH Server服务
|
### 2. 启动OpenSSH Server服务
|
||||||
|
|||||||
BIN
docs/guide/use/https/images/1.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
docs/guide/use/https/images/2.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
docs/guide/use/https/images/3.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/guide/use/https/images/ok.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
38
docs/guide/use/https/index.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Certd本身的https证书配置
|
||||||
|
|
||||||
|
## 一、启用https
|
||||||
|
|
||||||
|
`Certd`默认启用https,监听7002端口
|
||||||
|
如果你想关闭https,或者修改端口,可以在环境变量中配置
|
||||||
|
```shell
|
||||||
|
CERTD_HTTPS_ENABLE=true
|
||||||
|
CERTD_HTTPS_port=7002
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 二、自动更新Certd的https证书
|
||||||
|
|
||||||
|
### 1、创建证书流水线
|
||||||
|
|
||||||
|
参考Certd顶部的创建证书流水线教程
|
||||||
|
|
||||||
|
### 2、配置复制到本机任务
|
||||||
|
将证书复制到certd的证书安装位置
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### 3、配置重启Certd任务
|
||||||
|
重启certd的https server,让证书生效
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 4、配置定时任务
|
||||||
|
每天定时执行,最终效果如下
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
:::warning
|
||||||
|
建议将本流水线的触发时间与其他流水线时间错开,避免重启时影响其他流水线的执行
|
||||||
|
:::
|
||||||
BIN
docs/guide/use/tencent/images/delete.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/guide/use/tencent/images/delete2.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -6,3 +6,16 @@
|
|||||||
打开 https://console.cloud.tencent.com/cam/capi
|
打开 https://console.cloud.tencent.com/cam/capi
|
||||||
然后按如下方式获取腾讯云的API密钥
|
然后按如下方式获取腾讯云的API密钥
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
## 如何避免收到腾讯云证书过期邮件
|
||||||
|
|
||||||
|
腾讯云在证书有效期还剩28天时会发送过期通知邮件
|
||||||
|
您可以通过配置“腾讯云过期证书删除”任务来避免收到此类邮件。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
注意点:
|
||||||
|
> 1. 选择腾讯云授权,需授权`服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate`权限
|
||||||
|
> 2. `1.26.14`版本之前Certd创建的证书流水线默认是到期前20天才更新证书,需要将之前创建的证书申请任务的更新天数修改为35天,保证删除之前就已经替换掉即将过期证书
|
||||||
|

|
||||||
BIN
docs/images/start/home.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
@@ -28,7 +28,7 @@ features:
|
|||||||
- title: 多域名、泛域名打到一个证书上
|
- title: 多域名、泛域名打到一个证书上
|
||||||
details: 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
details: 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||||
- title: 多证书格式支持
|
- title: 多证书格式支持
|
||||||
details: 支持pem、pfx、der等多种证书格式,支持Google、Letsencrypt、ZeroSSL证书颁发机构
|
details: 支持pem、pfx、der、jks等多种证书格式,支持Google、Letsencrypt、ZeroSSL证书颁发机构
|
||||||
- title: 支持私有化部署
|
- title: 支持私有化部署
|
||||||
details: 保障数据安全
|
details: 保障数据安全
|
||||||
- title: 多数据库支持
|
- title: 多数据库支持
|
||||||
|
|||||||
2
docs/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.26.12"
|
"version": "1.27.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,32 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/publishlab/node-acme-client/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/publishlab/node-acme-client/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/publishlab/node-acme-client/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/publishlab/node-acme-client/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/publishlab/node-acme-client/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复启动时自签证书无法保存的bug ([526c484](https://github.com/publishlab/node-acme-client/commit/526c48450bcd37b3ccded9b448f17de8140bdc6e))
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/publishlab/node-acme-client/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
## [1.26.12](https://github.com/publishlab/node-acme-client/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/publishlab/node-acme-client/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "Simple and unopinionated ACME client",
|
"description": "Simple and unopinionated ACME client",
|
||||||
"private": false,
|
"private": false,
|
||||||
"author": "nmorsman",
|
"author": "nmorsman",
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "types/index.d.ts",
|
"types": "types/index.d.ts",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -60,5 +60,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function createAgent(opts = {}) {
|
|||||||
let httpAgent;
|
let httpAgent;
|
||||||
let
|
let
|
||||||
httpsAgent;
|
httpsAgent;
|
||||||
const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
|
const httpProxy = opts.httpProxy || process.env.HTTP_PROXY || process.env.http_proxy;
|
||||||
if (httpProxy) {
|
if (httpProxy) {
|
||||||
log(`acme use httpProxy:${httpProxy}`);
|
log(`acme use httpProxy:${httpProxy}`);
|
||||||
httpAgent = new HttpProxyAgent(httpProxy, opts);
|
httpAgent = new HttpProxyAgent(httpProxy, opts);
|
||||||
@@ -16,7 +16,7 @@ function createAgent(opts = {}) {
|
|||||||
else {
|
else {
|
||||||
httpAgent = new nodeHttp.Agent(opts);
|
httpAgent = new nodeHttp.Agent(opts);
|
||||||
}
|
}
|
||||||
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
|
const httpsProxy = opts.httpsProxy || process.env.HTTPS_PROXY || process.env.https_proxy;
|
||||||
if (httpsProxy) {
|
if (httpsProxy) {
|
||||||
log(`acme use httpsProxy:${httpsProxy}`);
|
log(`acme use httpsProxy:${httpsProxy}`);
|
||||||
httpsAgent = new HttpsProxyAgent(httpsProxy, opts);
|
httpsAgent = new HttpsProxyAgent(httpsProxy, opts);
|
||||||
@@ -38,30 +38,30 @@ function getGlobalAgents() {
|
|||||||
|
|
||||||
function setGlobalProxy(opts) {
|
function setGlobalProxy(opts) {
|
||||||
log('acme setGlobalProxy:', opts);
|
log('acme setGlobalProxy:', opts);
|
||||||
if (opts.httpProxy) {
|
defaultAgents = createAgent(opts);
|
||||||
process.env.HTTP_PROXY = opts.httpProxy;
|
|
||||||
}
|
|
||||||
if (opts.httpsProxy) {
|
|
||||||
process.env.HTTPS_PROXY = opts.httpsProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAgents = createAgent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HttpError extends Error {
|
class HttpError extends Error {
|
||||||
|
// eslint-disable-next-line constructor-super
|
||||||
constructor(error) {
|
constructor(error) {
|
||||||
super(error || error.message);
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
super(error.message);
|
||||||
|
|
||||||
if (error.message.indexOf('ssl3_get_record:wrong version number') >= 0) {
|
this.message = error.message;
|
||||||
this.message = 'http协议错误,服务端要求http协议,请检查是否使用了https请求';
|
const { message } = error;
|
||||||
|
if (message && typeof message === 'string') {
|
||||||
|
if (message.indexOf && message.indexOf('ssl3_get_record:wrong version number') >= 0) {
|
||||||
|
this.message = `${message}(http协议错误,服务端要求http协议,请检查是否使用了https请求)`;
|
||||||
|
}
|
||||||
|
else if (message.indexOf('getaddrinfo EAI_AGAIN')) {
|
||||||
|
this.message = `${message}(无法解析域名,请检查网络连接或dns配置)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.name = error.name;
|
this.name = error.name;
|
||||||
this.code = error.code;
|
this.code = error.code;
|
||||||
this.cause = error.cause;
|
|
||||||
|
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
this.status = error.response.status;
|
this.status = error.response.status;
|
||||||
@@ -69,6 +69,9 @@ class HttpError extends Error {
|
|||||||
this.response = {
|
this.response = {
|
||||||
data: error.response.data,
|
data: error.response.data,
|
||||||
};
|
};
|
||||||
|
if (!this.message) {
|
||||||
|
this.message = this.statusText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = '';
|
let url = '';
|
||||||
@@ -80,12 +83,18 @@ class HttpError extends Error {
|
|||||||
params: error.config.params,
|
params: error.config.params,
|
||||||
data: error.config.data,
|
data: error.config.data,
|
||||||
};
|
};
|
||||||
url = error.config.baseURL + error.config.url;
|
url = (error.config.baseURL || '') + error.config.url;
|
||||||
}
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
this.message = `${this.message}:${url}`;
|
this.message = `${this.message}:${url}`;
|
||||||
}
|
}
|
||||||
|
// const { stack, cause } = error;
|
||||||
|
delete this.cause;
|
||||||
|
delete this.stack;
|
||||||
|
// this.cause = cause;
|
||||||
|
// this.stack = stack;
|
||||||
|
delete error.stack;
|
||||||
|
delete error.cause;
|
||||||
delete error.response;
|
delete error.response;
|
||||||
delete error.config;
|
delete error.config;
|
||||||
delete error.request;
|
delete error.request;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
const { readCsrDomains } = require('./crypto');
|
const { readCsrDomains } = require('./crypto');
|
||||||
const { log } = require('./logger');
|
const { log } = require('./logger');
|
||||||
const { wait } = require('./wait');
|
const { wait } = require('./wait');
|
||||||
|
const { CancelError } = require('./error');
|
||||||
|
|
||||||
const defaultOpts = {
|
const defaultOpts = {
|
||||||
csr: null,
|
csr: null,
|
||||||
@@ -250,7 +251,7 @@ module.exports = async (client, userOpts) => {
|
|||||||
i += 1;
|
i += 1;
|
||||||
log(`开始第${i}组`);
|
log(`开始第${i}组`);
|
||||||
if (opts.signal && opts.signal.aborted) {
|
if (opts.signal && opts.signal.aborted) {
|
||||||
throw new Error('用户取消');
|
throw new CancelError('用户取消');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -114,17 +114,19 @@ instance.interceptors.response.use(null, async (error) => {
|
|||||||
const code = response ? `HTTP ${response.status}` : error.code;
|
const code = response ? `HTTP ${response.status}` : error.code;
|
||||||
log(`Caught ${code}, retry attempt ${config.retryAttempt}/${retryMaxAttempts} to URL ${config.url}`);
|
log(`Caught ${code}, retry attempt ${config.retryAttempt}/${retryMaxAttempts} to URL ${config.url}`);
|
||||||
|
|
||||||
|
const retryAfter = (retryDefaultDelay * config.retryAttempt);
|
||||||
/* Attempt to parse Retry-After header, fallback to default delay */
|
/* Attempt to parse Retry-After header, fallback to default delay */
|
||||||
let retryAfter = response ? parseRetryAfterHeader(response.headers['retry-after']) : 0;
|
const headerRetryAfter = response ? parseRetryAfterHeader(response.headers['retry-after']) : 0;
|
||||||
|
|
||||||
if (retryAfter > 0) {
|
if (headerRetryAfter > 0) {
|
||||||
log(`Found retry-after response header with value: ${response.headers['retry-after']}, waiting ${retryAfter} seconds`);
|
const waitMinutes = (headerRetryAfter / 60).toFixed(1);
|
||||||
}
|
log(`Found retry-after response header with value: ${response.headers['retry-after']}, waiting ${waitMinutes} minutes`);
|
||||||
else {
|
log(JSON.stringify(response.data));
|
||||||
retryAfter = (retryDefaultDelay * config.retryAttempt);
|
return Promise.reject(new Agents.HttpError(error));
|
||||||
log(`Unable to locate or parse retry-after response header, waiting ${retryAfter} seconds`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(`waiting ${retryAfter} seconds`);
|
||||||
|
|
||||||
/* Wait and retry the request */
|
/* Wait and retry the request */
|
||||||
await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); });
|
await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); });
|
||||||
return instance(config);
|
return instance(config);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const AcmeApi = require('./api');
|
|||||||
const verify = require('./verify');
|
const verify = require('./verify');
|
||||||
const util = require('./util');
|
const util = require('./util');
|
||||||
const auto = require('./auto');
|
const auto = require('./auto');
|
||||||
|
const { CancelError } = require('./error');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ACME states
|
* ACME states
|
||||||
@@ -490,9 +491,10 @@ class AcmeClient {
|
|||||||
|
|
||||||
const keyAuthorization = await this.getChallengeKeyAuthorization(challenge);
|
const keyAuthorization = await this.getChallengeKeyAuthorization(challenge);
|
||||||
|
|
||||||
const verifyFn = async () => {
|
const verifyFn = async (abort) => {
|
||||||
if (this.opts.signal && this.opts.signal.aborted) {
|
if (this.opts.signal && this.opts.signal.aborted) {
|
||||||
throw new Error('用户取消');
|
abort();
|
||||||
|
throw new CancelError('用户取消');
|
||||||
}
|
}
|
||||||
await verify[challenge.type](authz, challenge, keyAuthorization);
|
await verify[challenge.type](authz, challenge, keyAuthorization);
|
||||||
};
|
};
|
||||||
@@ -518,7 +520,7 @@ class AcmeClient {
|
|||||||
|
|
||||||
async completeChallenge(challenge) {
|
async completeChallenge(challenge) {
|
||||||
if (this.opts.signal && this.opts.signal.aborted) {
|
if (this.opts.signal && this.opts.signal.aborted) {
|
||||||
throw new Error('用户取消');
|
throw new CancelError('用户取消');
|
||||||
}
|
}
|
||||||
const resp = await this.api.completeChallenge(challenge.url, {});
|
const resp = await this.api.completeChallenge(challenge.url, {});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
@@ -559,7 +561,7 @@ class AcmeClient {
|
|||||||
const verifyFn = async (abort) => {
|
const verifyFn = async (abort) => {
|
||||||
if (this.opts.signal && this.opts.signal.aborted) {
|
if (this.opts.signal && this.opts.signal.aborted) {
|
||||||
abort();
|
abort();
|
||||||
throw new Error('用户取消');
|
throw new CancelError('用户取消');
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await this.api.apiRequest(item.url, null, [200]);
|
const resp = await this.api.apiRequest(item.url, null, [200]);
|
||||||
|
|||||||
10
packages/core/acme-client/src/error.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class CancelError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'CancelError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
CancelError,
|
||||||
|
};
|
||||||
@@ -48,3 +48,4 @@ exports.agents = require('./agents');
|
|||||||
exports.setLogger = require('./logger').setLogger;
|
exports.setLogger = require('./logger').setLogger;
|
||||||
|
|
||||||
exports.walkTxtRecord = require('./verify').walkTxtRecord;
|
exports.walkTxtRecord = require('./verify').walkTxtRecord;
|
||||||
|
exports.CancelError = require('./error').CancelError;
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ async function wait(ms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
wait
|
wait,
|
||||||
};
|
};
|
||||||
|
|||||||
4
packages/core/acme-client/types/index.d.ts
vendored
@@ -198,6 +198,8 @@ export const agents: any;
|
|||||||
* Logger
|
* Logger
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function setLogger(fn: (msg: string) => void): void;
|
export function setLogger(fn: (message: any, ...args: any[]) => void): void;
|
||||||
|
|
||||||
export function walkTxtRecord(record: any): Promise<string[]>;
|
export function walkTxtRecord(record: any): Promise<string[]>;
|
||||||
|
|
||||||
|
export const CancelError: Error;
|
||||||
|
|||||||
@@ -3,6 +3,36 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* cname 域名映射记录可读性优化 ([b1117ed](https://github.com/certd/certd/commit/b1117ed54a3ef015752999324ff72b821ef5e4b9))
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持华为云cdn ([81a3fdb](https://github.com/certd/certd/commit/81a3fdbc29b71f380762008cc151493ec97458f9))
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复启动时自签证书无法保存的bug ([526c484](https://github.com/certd/certd/commit/526c48450bcd37b3ccded9b448f17de8140bdc6e))
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
23:57
|
21:35
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -64,5 +64,5 @@
|
|||||||
"vite": "^4.3.8",
|
"vite": "^4.3.8",
|
||||||
"vue-tsc": "^1.6.5"
|
"vue-tsc": "^1.6.5"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './util.request.js';
|
export * from './util.request.js';
|
||||||
|
export * from './util.env.js';
|
||||||
export * from './util.log.js';
|
export * from './util.log.js';
|
||||||
export * from './util.file.js';
|
export * from './util.file.js';
|
||||||
export * from './util.sp.js';
|
export * from './util.sp.js';
|
||||||
@@ -7,8 +8,8 @@ export * from './util.hash.js';
|
|||||||
export * from './util.merge.js';
|
export * from './util.merge.js';
|
||||||
export * from './util.cache.js';
|
export * from './util.cache.js';
|
||||||
import sleep from './util.sleep.js';
|
import sleep from './util.sleep.js';
|
||||||
import { http } from './util.request.js';
|
import { http, download } from './util.request.js';
|
||||||
import { nanoid } from 'nanoid';
|
|
||||||
import { mergeUtils } from './util.merge.js';
|
import { mergeUtils } from './util.merge.js';
|
||||||
import { sp } from './util.sp.js';
|
import { sp } from './util.sp.js';
|
||||||
import { hashUtils } from './util.hash.js';
|
import { hashUtils } from './util.hash.js';
|
||||||
@@ -19,10 +20,12 @@ import { cache } from './util.cache.js';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { domainUtils } from './util.domain.js';
|
import { domainUtils } from './util.domain.js';
|
||||||
import { optionsUtils } from './util.options.js';
|
import { optionsUtils } from './util.options.js';
|
||||||
|
import { nanoid } from 'nanoid';
|
||||||
|
import * as id from './util.id.js';
|
||||||
export const utils = {
|
export const utils = {
|
||||||
sleep,
|
sleep,
|
||||||
http,
|
http,
|
||||||
|
download,
|
||||||
sp,
|
sp,
|
||||||
hash: hashUtils,
|
hash: hashUtils,
|
||||||
promises,
|
promises,
|
||||||
@@ -31,6 +34,7 @@ export const utils = {
|
|||||||
mergeUtils,
|
mergeUtils,
|
||||||
cache,
|
cache,
|
||||||
nanoid,
|
nanoid,
|
||||||
|
id,
|
||||||
dayjs,
|
dayjs,
|
||||||
domain: domainUtils,
|
domain: domainUtils,
|
||||||
options: optionsUtils,
|
options: optionsUtils,
|
||||||
|
|||||||
3
packages/core/basic/src/utils/util.env.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function isDev() {
|
||||||
|
return process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'local';
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import crypto from "crypto";
|
import crypto from 'crypto';
|
||||||
|
|
||||||
function md5(data: string) {
|
function md5(data: string) {
|
||||||
return crypto.createHash("md5").update(data).digest("hex");
|
return crypto.createHash('md5').update(data).digest('hex');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hashUtils = {
|
export const hashUtils = {
|
||||||
|
|||||||
3
packages/core/basic/src/utils/util.id.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { customAlphabet } from 'nanoid';
|
||||||
|
|
||||||
|
export const simpleNanoId = customAlphabet('1234567890abcdefghijklmopqrstuvwxyz', 12);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import log4js, { LoggingEvent, Logger } from "log4js";
|
import log4js, { LoggingEvent, Logger } from 'log4js';
|
||||||
|
|
||||||
const OutputAppender = {
|
const OutputAppender = {
|
||||||
configure: (config: any, layouts: any, findAppender: any, levels: any) => {
|
configure: (config: any, layouts: any, findAppender: any, levels: any) => {
|
||||||
@@ -18,18 +18,22 @@ const OutputAppender = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
export function resetLogConfigure() {
|
||||||
log4js.configure({
|
// @ts-ignore
|
||||||
appenders: { std: { type: "stdout" }, output: { type: OutputAppender } },
|
log4js.configure({
|
||||||
categories: { default: { appenders: ["std"], level: "info" }, pipeline: { appenders: ["std", "output"], level: "info" } },
|
appenders: { std: { type: 'stdout' }, output: { type: OutputAppender } },
|
||||||
});
|
categories: { default: { appenders: ['std'], level: 'info' }, pipeline: { appenders: ['std', 'output'], level: 'info' } },
|
||||||
export const logger = log4js.getLogger("default");
|
});
|
||||||
|
}
|
||||||
|
resetLogConfigure();
|
||||||
|
export const logger = log4js.getLogger('default');
|
||||||
|
|
||||||
export function buildLogger(write: (text: string) => void) {
|
export function buildLogger(write: (text: string) => void) {
|
||||||
const logger = log4js.getLogger("pipeline");
|
const logger = log4js.getLogger('pipeline');
|
||||||
logger.addContext("outputHandler", {
|
logger.addContext('outputHandler', {
|
||||||
write,
|
write,
|
||||||
});
|
});
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ILogger = Logger;
|
export type ILogger = Logger;
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import axios, { AxiosRequestConfig } from 'axios';
|
import axios, { AxiosRequestConfig } from 'axios';
|
||||||
import { logger } from './util.log.js';
|
import { ILogger, logger } from './util.log.js';
|
||||||
import { Logger } from 'log4js';
|
import { Logger } from 'log4js';
|
||||||
import { HttpProxyAgent } from 'http-proxy-agent';
|
import { HttpProxyAgent } from 'http-proxy-agent';
|
||||||
import { HttpsProxyAgent } from 'https-proxy-agent';
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||||
import nodeHttp from 'http';
|
import nodeHttp from 'http';
|
||||||
import * as https from 'node:https';
|
import * as https from 'node:https';
|
||||||
import { merge } from 'lodash-es';
|
import { merge } from 'lodash-es';
|
||||||
|
import { safePromise } from './util.promise.js';
|
||||||
|
import fs from 'fs';
|
||||||
export class HttpError extends Error {
|
export class HttpError extends Error {
|
||||||
status?: number;
|
status?: number;
|
||||||
statusText?: string;
|
statusText?: string;
|
||||||
@@ -17,15 +19,19 @@ export class HttpError extends Error {
|
|||||||
if (!error) {
|
if (!error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super(error.message);
|
super(error.message || error.response?.statusText);
|
||||||
|
|
||||||
if (error?.message?.indexOf('ssl3_get_record:wrong version number') >= 0) {
|
const message = error?.message;
|
||||||
this.message = 'http协议错误,服务端要求http协议,请检查是否使用了https请求';
|
if (message && typeof message === 'string') {
|
||||||
|
if (message.indexOf && message.indexOf('ssl3_get_record:wrong version number') >= 0) {
|
||||||
|
this.message = `${message}(http协议错误,服务端要求http协议,请检查是否使用了https请求)`;
|
||||||
|
} else if (message.indexOf('getaddrinfo EAI_AGAIN')) {
|
||||||
|
this.message = `${message}(无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.name = error.name;
|
this.name = error.name;
|
||||||
this.code = error.code;
|
this.code = error.code;
|
||||||
this.cause = error.cause;
|
|
||||||
|
|
||||||
this.status = error.response?.status;
|
this.status = error.response?.status;
|
||||||
this.statusText = error.response?.statusText;
|
this.statusText = error.response?.statusText;
|
||||||
@@ -38,7 +44,7 @@ export class HttpError extends Error {
|
|||||||
};
|
};
|
||||||
let url = error.config?.url;
|
let url = error.config?.url;
|
||||||
if (error.config?.baseURL) {
|
if (error.config?.baseURL) {
|
||||||
url = error.config?.baseURL + url;
|
url = (error.config?.baseURL || '') + url;
|
||||||
}
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
this.message = `${this.message} : url=${url}`;
|
this.message = `${this.message} : url=${url}`;
|
||||||
@@ -48,6 +54,9 @@ export class HttpError extends Error {
|
|||||||
data: error.response?.data,
|
data: error.response?.data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const { stack, cause } = error;
|
||||||
|
// this.cause = cause;
|
||||||
|
// this.stack = stack;
|
||||||
delete error.response;
|
delete error.response;
|
||||||
delete error.config;
|
delete error.config;
|
||||||
delete error.request;
|
delete error.request;
|
||||||
@@ -61,14 +70,7 @@ let defaultAgents = createAgent();
|
|||||||
|
|
||||||
export function setGlobalProxy(opts: { httpProxy?: string; httpsProxy?: string }) {
|
export function setGlobalProxy(opts: { httpProxy?: string; httpsProxy?: string }) {
|
||||||
logger.info('setGlobalProxy:', opts);
|
logger.info('setGlobalProxy:', opts);
|
||||||
if (opts.httpProxy) {
|
defaultAgents = createAgent(opts);
|
||||||
process.env.HTTP_PROXY = opts.httpProxy;
|
|
||||||
}
|
|
||||||
if (opts.httpsProxy) {
|
|
||||||
process.env.HTTPS_PROXY = opts.httpsProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAgents = createAgent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGlobalAgents() {
|
export function getGlobalAgents() {
|
||||||
@@ -86,7 +88,7 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
|||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config: any) => {
|
(config: any) => {
|
||||||
logger.info(`http request:${config.url},method:${config.method}`);
|
logger.info(`http request:${config.url},method:${config.method}`);
|
||||||
if (config.logParams !== false) {
|
if (config.logParams !== false && config.params) {
|
||||||
logger.info(`params:${JSON.stringify(config.params)}`);
|
logger.info(`params:${JSON.stringify(config.params)}`);
|
||||||
}
|
}
|
||||||
if (config.timeout == null) {
|
if (config.timeout == null) {
|
||||||
@@ -118,7 +120,12 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
|||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response: any) => {
|
(response: any) => {
|
||||||
if (response?.config?.logRes !== false) {
|
if (response?.config?.logRes !== false) {
|
||||||
logger.info(`http response : status=${response?.status},data=${JSON.stringify(response?.data)}`);
|
let resData = response?.data;
|
||||||
|
try {
|
||||||
|
resData = JSON.stringify(response?.data);
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
logger.info(`http response : status=${response?.status},data=${resData}`);
|
||||||
} else {
|
} else {
|
||||||
logger.info('http response status:', response?.status);
|
logger.info('http response status:', response?.status);
|
||||||
}
|
}
|
||||||
@@ -182,7 +189,7 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
|||||||
|
|
||||||
export const http = createAxiosService({ logger }) as HttpClient;
|
export const http = createAxiosService({ logger }) as HttpClient;
|
||||||
export type HttpClientResponse<R> = any;
|
export type HttpClientResponse<R> = any;
|
||||||
export type HttpRequestConfig<D=any> = {
|
export type HttpRequestConfig<D = any> = {
|
||||||
skipSslVerify?: boolean;
|
skipSslVerify?: boolean;
|
||||||
skipCheckRes?: boolean;
|
skipCheckRes?: boolean;
|
||||||
logParams?: boolean;
|
logParams?: boolean;
|
||||||
@@ -192,9 +199,13 @@ export type HttpClient = {
|
|||||||
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createAgent(opts: nodeHttp.AgentOptions = {}) {
|
export type CreateAgentOptions = {
|
||||||
|
httpProxy?: string;
|
||||||
|
httpsProxy?: string;
|
||||||
|
} & nodeHttp.AgentOptions;
|
||||||
|
export function createAgent(opts: CreateAgentOptions = {}) {
|
||||||
let httpAgent, httpsAgent;
|
let httpAgent, httpsAgent;
|
||||||
const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
|
const httpProxy = opts.httpProxy || process.env.HTTP_PROXY || process.env.http_proxy;
|
||||||
if (httpProxy) {
|
if (httpProxy) {
|
||||||
logger.info('use httpProxy:', httpProxy);
|
logger.info('use httpProxy:', httpProxy);
|
||||||
httpAgent = new HttpProxyAgent(httpProxy, opts as any);
|
httpAgent = new HttpProxyAgent(httpProxy, opts as any);
|
||||||
@@ -202,7 +213,7 @@ export function createAgent(opts: nodeHttp.AgentOptions = {}) {
|
|||||||
} else {
|
} else {
|
||||||
httpAgent = new nodeHttp.Agent(opts);
|
httpAgent = new nodeHttp.Agent(opts);
|
||||||
}
|
}
|
||||||
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
|
const httpsProxy = opts.httpsProxy || process.env.HTTPS_PROXY || process.env.https_proxy;
|
||||||
if (httpsProxy) {
|
if (httpsProxy) {
|
||||||
logger.info('use httpsProxy:', httpsProxy);
|
logger.info('use httpsProxy:', httpsProxy);
|
||||||
httpsAgent = new HttpsProxyAgent(httpsProxy, opts as any);
|
httpsAgent = new HttpsProxyAgent(httpsProxy, opts as any);
|
||||||
@@ -215,3 +226,44 @@ export function createAgent(opts: nodeHttp.AgentOptions = {}) {
|
|||||||
httpsAgent,
|
httpsAgent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function download(req: { http: HttpClient; config: HttpRequestConfig; savePath: string; logger: ILogger }) {
|
||||||
|
const { http, config, savePath, logger } = req;
|
||||||
|
return safePromise((resolve, reject) => {
|
||||||
|
http
|
||||||
|
.request({
|
||||||
|
logRes: false,
|
||||||
|
responseType: 'stream',
|
||||||
|
...config,
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
const writer = fs.createWriteStream(savePath);
|
||||||
|
res.pipe(writer);
|
||||||
|
writer.on('close', () => {
|
||||||
|
logger.info('文件下载成功');
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
//error
|
||||||
|
writer.on('error', err => {
|
||||||
|
logger.error('下载失败', err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
//进度条打印
|
||||||
|
const totalLength = res.headers['content-length'];
|
||||||
|
let currentLength = 0;
|
||||||
|
// 每5%打印一次
|
||||||
|
const step = (totalLength / 100) * 5;
|
||||||
|
res.on('data', (chunk: any) => {
|
||||||
|
currentLength += chunk.length;
|
||||||
|
if (currentLength % step < chunk.length) {
|
||||||
|
const percent = ((currentLength / totalLength) * 100).toFixed(2);
|
||||||
|
logger.info(`下载进度:${percent}%`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
logger.info('下载失败', err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//转换为import
|
//转换为import
|
||||||
import childProcess from "child_process";
|
import childProcess from 'child_process';
|
||||||
import { safePromise } from "./util.promise.js";
|
import { safePromise } from './util.promise.js';
|
||||||
import { ILogger, logger } from "./util.log.js";
|
import { ILogger, logger } from './util.log.js';
|
||||||
|
import iconv from 'iconv-lite';
|
||||||
export type ExecOption = {
|
export type ExecOption = {
|
||||||
cmd: string | string[];
|
cmd: string | string[];
|
||||||
env: any;
|
env: any;
|
||||||
@@ -11,12 +11,12 @@ export type ExecOption = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function exec(opts: ExecOption): Promise<string> {
|
async function exec(opts: ExecOption): Promise<string> {
|
||||||
let cmd = "";
|
let cmd = '';
|
||||||
const log = opts.logger || logger;
|
const log = opts.logger || logger;
|
||||||
if (opts.cmd instanceof Array) {
|
if (opts.cmd instanceof Array) {
|
||||||
for (const item of opts.cmd) {
|
for (const item of opts.cmd) {
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
cmd += " && " + item;
|
cmd += ' && ' + item;
|
||||||
} else {
|
} else {
|
||||||
cmd = item;
|
cmd = item;
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ async function exec(opts: ExecOption): Promise<string> {
|
|||||||
log.error(`exec error: ${error}`);
|
log.error(`exec error: ${error}`);
|
||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
const res = stdout.toString("utf-8");
|
const res = stdout.toString('utf-8');
|
||||||
log.info(`stdout: ${res}`);
|
log.info(`stdout: ${res}`);
|
||||||
resolve(res);
|
resolve(res);
|
||||||
}
|
}
|
||||||
@@ -55,13 +55,31 @@ export type SpawnOption = {
|
|||||||
logger?: ILogger;
|
logger?: ILogger;
|
||||||
options?: any;
|
options?: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isWindows() {
|
||||||
|
return process.platform === 'win32';
|
||||||
|
}
|
||||||
|
function convert(buffer: any) {
|
||||||
|
if (isWindows()) {
|
||||||
|
const decoded = iconv.decode(buffer, 'GBK');
|
||||||
|
// 检查是否有有效字符
|
||||||
|
return decoded && decoded.trim().length > 0 ? decoded : buffer.toString();
|
||||||
|
} else {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function convert(buffer: any) {
|
||||||
|
// return buffer;
|
||||||
|
// }
|
||||||
|
|
||||||
async function spawn(opts: SpawnOption): Promise<string> {
|
async function spawn(opts: SpawnOption): Promise<string> {
|
||||||
let cmd = "";
|
let cmd = '';
|
||||||
const log = opts.logger || logger;
|
const log = opts.logger || logger;
|
||||||
if (opts.cmd instanceof Array) {
|
if (opts.cmd instanceof Array) {
|
||||||
for (const item of opts.cmd) {
|
for (const item of opts.cmd) {
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
cmd += " && " + item;
|
cmd += ' && ' + item;
|
||||||
} else {
|
} else {
|
||||||
cmd = item;
|
cmd = item;
|
||||||
}
|
}
|
||||||
@@ -70,8 +88,8 @@ async function spawn(opts: SpawnOption): Promise<string> {
|
|||||||
cmd = opts.cmd;
|
cmd = opts.cmd;
|
||||||
}
|
}
|
||||||
log.info(`执行命令: ${cmd}`);
|
log.info(`执行命令: ${cmd}`);
|
||||||
let stdout = "";
|
let stdout = '';
|
||||||
let stderr = "";
|
let stderr = '';
|
||||||
return safePromise((resolve, reject) => {
|
return safePromise((resolve, reject) => {
|
||||||
const ls = childProcess.spawn(cmd, {
|
const ls = childProcess.spawn(cmd, {
|
||||||
shell: true,
|
shell: true,
|
||||||
@@ -81,21 +99,23 @@ async function spawn(opts: SpawnOption): Promise<string> {
|
|||||||
},
|
},
|
||||||
...opts.options,
|
...opts.options,
|
||||||
});
|
});
|
||||||
ls.stdout.on("data", (data) => {
|
ls.stdout.on('data', data => {
|
||||||
|
data = convert(data);
|
||||||
log.info(`stdout: ${data}`);
|
log.info(`stdout: ${data}`);
|
||||||
stdout += data;
|
stdout += data;
|
||||||
});
|
});
|
||||||
|
|
||||||
ls.stderr.on("data", (data) => {
|
ls.stderr.on('data', data => {
|
||||||
log.error(`stderr: ${data}`);
|
data = convert(data);
|
||||||
|
log.warn(`stderr: ${data}`);
|
||||||
stderr += data;
|
stderr += data;
|
||||||
});
|
});
|
||||||
ls.on("error", (error) => {
|
ls.on('error', error => {
|
||||||
log.error(`child process error: ${error}`);
|
log.error(`child process error: ${error}`);
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
ls.on("close", (code: number) => {
|
ls.on('close', (code: number) => {
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
log.error(`child process exited with code ${code}`);
|
log.error(`child process exited with code ${code}`);
|
||||||
reject(new Error(stderr));
|
reject(new Error(stderr));
|
||||||
|
|||||||
@@ -3,6 +3,36 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化时间选择器,自动填写分钟和秒钟 ([396dc34](https://github.com/certd/certd/commit/396dc34a841c7d016b033736afdba8366fb2d211))
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持白山云cdn部署 ([b1b2cd0](https://github.com/certd/certd/commit/b1b2cd088b684eda764962abd61754c26a204d1c))
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 默认证书更新时间设置为35天,增加腾讯云删除过期证书插件,可以避免腾讯云过期证书邮件 ([51b6fed](https://github.com/certd/certd/commit/51b6fed468eaa6f28ce4497ce303ace1a52abb96))
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/pipeline
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
|
"module": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -15,8 +16,8 @@
|
|||||||
"test": "mocha --loader=ts-node/esm"
|
"test": "mocha --loader=ts-node/esm"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.26.12",
|
"@certd/basic": "^1.27.1",
|
||||||
"@certd/plus-core": "^1.26.12",
|
"@certd/plus-core": "^1.27.1",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"fix-path": "^4.0.0",
|
"fix-path": "^4.0.0",
|
||||||
@@ -66,5 +67,5 @@
|
|||||||
"vite": "^4.3.8",
|
"vite": "^4.3.8",
|
||||||
"vue-tsc": "^1.6.5"
|
"vue-tsc": "^1.6.5"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Registrable } from "../registry/index.js";
|
import { Registrable } from "../registry/index.js";
|
||||||
import { FormItemProps } from "../dt/index.js";
|
import { FormItemProps } from "../dt/index.js";
|
||||||
import { HttpClient, ILogger, utils } from "../utils/index.js";
|
import { HttpClient, ILogger, utils } from "@certd/basic";
|
||||||
import _ from "lodash-es";
|
import _ from "lodash-es";
|
||||||
import { AccessRequestHandleReq } from "../core";
|
import { AccessRequestHandleReq } from "../core";
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { AccessContext, AccessDefine, AccessInputDefine } from "./api.js";
|
|||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import _ from "lodash-es";
|
import _ from "lodash-es";
|
||||||
import { accessRegistry } from "./registry.js";
|
import { accessRegistry } from "./registry.js";
|
||||||
import { http, logger, utils } from "../utils/index.js";
|
import { http, logger, utils } from "@certd/basic";
|
||||||
|
|
||||||
// 提供一个唯一 key
|
// 提供一个唯一 key
|
||||||
export const ACCESS_CLASS_KEY = "pipeline:access";
|
export const ACCESS_CLASS_KEY = "pipeline:access";
|
||||||
|
|||||||
5
packages/core/pipeline/src/core/exceptions.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export class CancelError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import { RunHistory, RunnableCollection } from "./run-history.js";
|
|||||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
||||||
import { ContextFactory, IContext } from "./context.js";
|
import { ContextFactory, IContext } from "./context.js";
|
||||||
import { IStorage } from "./storage.js";
|
import { IStorage } from "./storage.js";
|
||||||
import { createAxiosService, hashUtils, logger, utils } from "../utils/index.js";
|
import { createAxiosService, hashUtils, HttpRequestConfig, logger, utils } from "@certd/basic";
|
||||||
import { Logger } from "log4js";
|
import { Logger } from "log4js";
|
||||||
import { IAccessService } from "../access/index.js";
|
import { IAccessService } from "../access/index.js";
|
||||||
import { RegistryItem } from "../registry/index.js";
|
import { RegistryItem } from "../registry/index.js";
|
||||||
@@ -135,7 +135,12 @@ export class Executor {
|
|||||||
this.runtime.success(runnable);
|
this.runtime.success(runnable);
|
||||||
return ResultType.success;
|
return ResultType.success;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.runtime.error(runnable, e);
|
if (e.name === "CancelError" || this.abort.signal.aborted) {
|
||||||
|
this.runtime.cancel(runnable);
|
||||||
|
return ResultType.canceled;
|
||||||
|
} else {
|
||||||
|
this.runtime.error(runnable, e);
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
this.runtime.finally(runnable);
|
this.runtime.finally(runnable);
|
||||||
@@ -285,11 +290,20 @@ export class Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const http = createAxiosService({ logger: currentLogger });
|
const http = createAxiosService({ logger: currentLogger });
|
||||||
|
const download = async (config: HttpRequestConfig, savePath: string) => {
|
||||||
|
await utils.download({
|
||||||
|
http,
|
||||||
|
logger: currentLogger,
|
||||||
|
config,
|
||||||
|
savePath,
|
||||||
|
});
|
||||||
|
};
|
||||||
const taskCtx: TaskInstanceContext = {
|
const taskCtx: TaskInstanceContext = {
|
||||||
pipeline: this.pipeline,
|
pipeline: this.pipeline,
|
||||||
step,
|
step,
|
||||||
lastStatus,
|
lastStatus,
|
||||||
http,
|
http,
|
||||||
|
download,
|
||||||
logger: currentLogger,
|
logger: currentLogger,
|
||||||
inputChanged,
|
inputChanged,
|
||||||
accessService: this.options.accessService,
|
accessService: this.options.accessService,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { fileUtils } from "../utils/index.js";
|
import { fileUtils } from "@certd/basic";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { logger } from "../utils/index.js";
|
import { logger } from "@certd/basic";
|
||||||
|
|
||||||
export type FileStoreOptions = {
|
export type FileStoreOptions = {
|
||||||
rootDir?: string;
|
rootDir?: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { HttpClient, ILogger, utils } from "../utils/index.js";
|
import { HttpClient, ILogger, utils } from "@certd/basic";
|
||||||
|
|
||||||
export type PluginRequestHandleReq<T = any> = {
|
export type PluginRequestHandleReq<T = any> = {
|
||||||
typeName: string;
|
typeName: string;
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ export * from "./run-history.js";
|
|||||||
export * from "./context.js";
|
export * from "./context.js";
|
||||||
export * from "./storage.js";
|
export * from "./storage.js";
|
||||||
export * from "./file-store.js";
|
export * from "./file-store.js";
|
||||||
export * from "./license.js";
|
|
||||||
export * from "./handler.js";
|
export * from "./handler.js";
|
||||||
|
export * from "./exceptions.js";
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import { logger } from "../utils/index.js";
|
|
||||||
import { setLogger, isPlus, isComm } from "@certd/plus-core";
|
|
||||||
setLogger(logger);
|
|
||||||
export * from "@certd/plus-core";
|
|
||||||
|
|
||||||
export function checkPlus() {
|
|
||||||
if (!isPlus()) {
|
|
||||||
throw new Error("此为专业版功能,请升级到专业版");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkComm() {
|
|
||||||
if (!isComm()) {
|
|
||||||
throw new Error("此为商业版功能,请升级到商业版");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../dt/index.js";
|
import { HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../dt/index.js";
|
||||||
import _ from "lodash-es";
|
import _ from "lodash-es";
|
||||||
import { buildLogger } from "../utils/index.js";
|
import { buildLogger } from "@certd/basic";
|
||||||
import { Logger } from "log4js";
|
import { Logger } from "log4js";
|
||||||
|
|
||||||
export type HistoryStatus = {
|
export type HistoryStatus = {
|
||||||
@@ -117,7 +117,8 @@ export class RunHistory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logError(runnable: Runnable, e: Error) {
|
logError(runnable: Runnable, e: Error) {
|
||||||
// @ts-ignore
|
// delete e.stack;
|
||||||
|
// delete e.cause;
|
||||||
const errorInfo = runnable.runnableType === "step" ? e : e.message;
|
const errorInfo = runnable.runnableType === "step" ? e : e.message;
|
||||||
this._loggers[runnable.id].error(`[${runnable.runnableType}] [${runnable.title}]<id:${runnable.id}> :`, errorInfo);
|
this._loggers[runnable.id].error(`[${runnable.runnableType}] [${runnable.title}]<id:${runnable.id}> :`, errorInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileUtils } from "../utils/index.js";
|
import { fileUtils } from "@certd/basic";
|
||||||
|
|
||||||
export interface IStorage {
|
export interface IStorage {
|
||||||
get(scope: string, namespace: string, version: string, key: string): Promise<string | null>;
|
get(scope: string, namespace: string, version: string, key: string): Promise<string | null>;
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
/**
|
|
||||||
* [x]-col的配置
|
|
||||||
*/
|
|
||||||
export type ColProps = {
|
|
||||||
span?: number;
|
|
||||||
[props: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FormItemProps = {
|
|
||||||
/**
|
|
||||||
* 字段label
|
|
||||||
*/
|
|
||||||
title?: string;
|
|
||||||
/**
|
|
||||||
* 表单字段组件配置
|
|
||||||
*/
|
|
||||||
component?: ComponentProps;
|
|
||||||
/**
|
|
||||||
* 表单字段 [a|el|n]-col的配置
|
|
||||||
* 一般用来配置跨列:{span:24} 占满一行
|
|
||||||
*/
|
|
||||||
col?: ColProps;
|
|
||||||
/**
|
|
||||||
* 默认值
|
|
||||||
*/
|
|
||||||
value?: any;
|
|
||||||
/**
|
|
||||||
* 帮助提示配置
|
|
||||||
*/
|
|
||||||
helper?: string | FormItemHelperProps;
|
|
||||||
/**
|
|
||||||
* 排序号
|
|
||||||
*/
|
|
||||||
order?: number;
|
|
||||||
/**
|
|
||||||
* 是否显示此字段
|
|
||||||
*/
|
|
||||||
show?: boolean;
|
|
||||||
/**
|
|
||||||
* 是否是空白占位栏
|
|
||||||
*/
|
|
||||||
blank?: boolean;
|
|
||||||
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单字段帮助说明配置
|
|
||||||
*/
|
|
||||||
export type FormItemHelperProps = {
|
|
||||||
/**
|
|
||||||
* 自定义渲染帮助说明
|
|
||||||
* @param scope
|
|
||||||
*/
|
|
||||||
render?: (scope: any) => any;
|
|
||||||
/**
|
|
||||||
* 帮助文本
|
|
||||||
*/
|
|
||||||
text?: string;
|
|
||||||
/**
|
|
||||||
* 帮助说明所在的位置,[ undefined | label]
|
|
||||||
*/
|
|
||||||
position?: string;
|
|
||||||
/**
|
|
||||||
* [a|el|n]-tooltip配置
|
|
||||||
*/
|
|
||||||
tooltip?: object;
|
|
||||||
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组件配置
|
|
||||||
*/
|
|
||||||
export type ComponentProps = {
|
|
||||||
/**
|
|
||||||
* 组件的名称
|
|
||||||
*/
|
|
||||||
name?: string | object;
|
|
||||||
/**
|
|
||||||
* vmodel绑定的目标属性名
|
|
||||||
*/
|
|
||||||
vModel?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当原始组件名的参数被以上属性名占用时,可以配置在这里
|
|
||||||
* 例如:原始组件有一个叫name的属性,你想要配置它,则可以按如下配置
|
|
||||||
* ```
|
|
||||||
* component:{
|
|
||||||
* name:"组件的名称"
|
|
||||||
* props:{
|
|
||||||
* name:"组件的name属性" <-----------
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
props?: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组件事件监听
|
|
||||||
*/
|
|
||||||
on?: {
|
|
||||||
[key: string]: (context?: any) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组件其他参数
|
|
||||||
* 事件:onXxx:(event)=>void 组件原始事件监听
|
|
||||||
* on.onXxx:(context)=>void 组件事件监听(对原始事件包装)
|
|
||||||
* 样式:style、class等
|
|
||||||
*/
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export * from "./pipeline";
|
|
||||||
export * from "./fast-crud";
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
export enum RunStrategy {
|
|
||||||
AlwaysRun,
|
|
||||||
SkipWhenSucceed,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ConcurrencyStrategy {
|
|
||||||
Serial,
|
|
||||||
Parallel,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum NextStrategy {
|
|
||||||
AllSuccess,
|
|
||||||
OneSuccess,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum HandlerType {
|
|
||||||
//清空后续任务的状态
|
|
||||||
ClearFollowStatus,
|
|
||||||
SendEmail,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EventHandler = {
|
|
||||||
type: HandlerType;
|
|
||||||
params: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunnableStrategy = {
|
|
||||||
runStrategy?: RunStrategy;
|
|
||||||
onSuccess?: EventHandler[];
|
|
||||||
onError?: EventHandler[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Step = Runnable & {
|
|
||||||
type: string; //插件类型
|
|
||||||
input: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export type Task = Runnable & {
|
|
||||||
steps: Step[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Stage = Runnable & {
|
|
||||||
tasks: Task[];
|
|
||||||
concurrency: ConcurrencyStrategy;
|
|
||||||
next: NextStrategy;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Trigger = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
cron: string;
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FileItem = {
|
|
||||||
id: string;
|
|
||||||
filename: string;
|
|
||||||
path: string;
|
|
||||||
};
|
|
||||||
export type Runnable = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
strategy?: RunnableStrategy;
|
|
||||||
runnableType?: string; // pipeline, stage, task , step
|
|
||||||
status?: HistoryResult;
|
|
||||||
timeout?: number;
|
|
||||||
default?: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
context?: Context;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EmailOptions = {
|
|
||||||
receivers: string[];
|
|
||||||
};
|
|
||||||
export type NotificationWhen = "error" | "success" | "turnToSuccess" | "start";
|
|
||||||
export type NotificationType = "email" | "url";
|
|
||||||
export type Notification = {
|
|
||||||
type: NotificationType;
|
|
||||||
when: NotificationWhen[];
|
|
||||||
options: EmailOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Pipeline = Runnable & {
|
|
||||||
version?: number;
|
|
||||||
userId: any;
|
|
||||||
stages: Stage[];
|
|
||||||
triggers: Trigger[];
|
|
||||||
notifications?: Notification[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Context = {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Log = {
|
|
||||||
title: string;
|
|
||||||
time: number;
|
|
||||||
level: string;
|
|
||||||
text: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum ResultType {
|
|
||||||
start = "start",
|
|
||||||
success = "success",
|
|
||||||
error = "error",
|
|
||||||
canceled = "canceled",
|
|
||||||
skip = "skip",
|
|
||||||
none = "none",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HistoryResultGroup = {
|
|
||||||
[key: string]: {
|
|
||||||
runnable: Runnable;
|
|
||||||
res: HistoryResult;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export type HistoryResult = {
|
|
||||||
input: any;
|
|
||||||
output: any;
|
|
||||||
files?: FileItem[];
|
|
||||||
/**
|
|
||||||
* 任务状态
|
|
||||||
*/
|
|
||||||
status: ResultType;
|
|
||||||
startTime: number;
|
|
||||||
endTime?: number;
|
|
||||||
/**
|
|
||||||
* 处理结果
|
|
||||||
*/
|
|
||||||
result?: ResultType; //success, error,skip
|
|
||||||
message?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunnableMap = {
|
|
||||||
[id: string]: Runnable;
|
|
||||||
};
|
|
||||||
@@ -3,7 +3,6 @@ export * from "./dt/index.js";
|
|||||||
export * from "./access/index.js";
|
export * from "./access/index.js";
|
||||||
export * from "./registry/index.js";
|
export * from "./registry/index.js";
|
||||||
export * from "./plugin/index.js";
|
export * from "./plugin/index.js";
|
||||||
export * from "./utils/index.js";
|
|
||||||
export * from "./context/index.js";
|
export * from "./context/index.js";
|
||||||
export * from "./decorator/index.js";
|
export * from "./decorator/index.js";
|
||||||
export * from "./service/index.js";
|
export * from "./service/index.js";
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { FileStore } from "../core/file-store.js";
|
|||||||
import { Logger } from "log4js";
|
import { Logger } from "log4js";
|
||||||
import { IAccessService } from "../access/index.js";
|
import { IAccessService } from "../access/index.js";
|
||||||
import { ICnameProxyService, IEmailService } from "../service/index.js";
|
import { ICnameProxyService, IEmailService } from "../service/index.js";
|
||||||
import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/index.js";
|
import { CancelError, IContext, PluginRequestHandleReq, RunnableCollection } from "../core/index.js";
|
||||||
import { ILogger, logger, utils } from "../utils/index.js";
|
import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
|
||||||
import { HttpClient } from "../utils/index.js";
|
import { HttpClient } from "@certd/basic";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { IPluginConfigService } from "../service/config";
|
import { IPluginConfigService } from "../service/config";
|
||||||
import { upperFirst } from "lodash-es";
|
import { upperFirst } from "lodash-es";
|
||||||
@@ -85,6 +85,8 @@ export type TaskInstanceContext = {
|
|||||||
userContext: IContext;
|
userContext: IContext;
|
||||||
//http请求客户端
|
//http请求客户端
|
||||||
http: HttpClient;
|
http: HttpClient;
|
||||||
|
//下载文件方法
|
||||||
|
download: (config: HttpRequestConfig, savePath: string) => Promise<void>;
|
||||||
//文件存储
|
//文件存储
|
||||||
fileStore: FileStore;
|
fileStore: FileStore;
|
||||||
//上一次执行结果状态
|
//上一次执行结果状态
|
||||||
@@ -111,13 +113,19 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
|||||||
return this._result.files;
|
return this._result.files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkSignal() {
|
||||||
|
if (this.ctx.signal && this.ctx.signal.aborted) {
|
||||||
|
throw new CancelError("用户取消");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCtx(ctx: TaskInstanceContext) {
|
setCtx(ctx: TaskInstanceContext) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.logger = ctx.logger;
|
this.logger = ctx.logger;
|
||||||
this.accessService = ctx.accessService;
|
this.accessService = ctx.accessService;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccess(accessId: string) {
|
async getAccess<T = any>(accessId: string) {
|
||||||
if (accessId == null) {
|
if (accessId == null) {
|
||||||
throw new Error("您还没有配置授权");
|
throw new Error("您还没有配置授权");
|
||||||
}
|
}
|
||||||
@@ -125,7 +133,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
|||||||
if (res == null) {
|
if (res == null) {
|
||||||
throw new Error("授权不存在,可能已被删除,请前往任务配置里面重新选择授权");
|
throw new Error("授权不存在,可能已被删除,请前往任务配置里面重新选择授权");
|
||||||
}
|
}
|
||||||
return res;
|
return res as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
randomFileId() {
|
randomFileId() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { logger } from "../utils/index.js";
|
import { isDev, logger } from "@certd/basic";
|
||||||
|
|
||||||
export type Registrable = {
|
export type Registrable = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -71,6 +71,9 @@ export class Registry<T> {
|
|||||||
if (define?.deprecated) {
|
if (define?.deprecated) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!isDev() && define.name.startsWith("demo")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
list.push({ ...define, key });
|
list.push({ ...define, key });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
export * from "@certd/basic";
|
|
||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-huawei
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-huawei",
|
"name": "@certd/lib-huawei",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
@@ -17,5 +17,5 @@
|
|||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"rollup": "^3.7.4"
|
"rollup": "^3.7.4"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-iframe
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-iframe",
|
"name": "@certd/lib-iframe",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -39,5 +39,5 @@
|
|||||||
"tslib": "^2.5.2",
|
"tslib": "^2.5.2",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-jdcloud
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-jdcloud",
|
"name": "@certd/lib-jdcloud",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"main": "./dist/bundle.mjs",
|
"main": "./dist/bundle.mjs",
|
||||||
"module": "./dist/bundle.mjs",
|
"module": "./dist/bundle.mjs",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
@@ -27,5 +27,5 @@
|
|||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"rollup": "^3.7.4"
|
"rollup": "^3.7.4"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-k8s
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-k8s",
|
"name": "@certd/lib-k8s",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/pipeline": "^1.26.12",
|
"@certd/basic": "^1.27.1",
|
||||||
"@rollup/plugin-commonjs": "^23.0.4",
|
"@rollup/plugin-commonjs": "^23.0.4",
|
||||||
"@rollup/plugin-json": "^6.0.0",
|
"@rollup/plugin-json": "^6.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
@@ -40,5 +40,5 @@
|
|||||||
"tslib": "^2.5.2",
|
"tslib": "^2.5.2",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from '@kubernetes/client-node';
|
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from '@kubernetes/client-node';
|
||||||
import dns from 'dns';
|
import dns from 'dns';
|
||||||
import { ILogger } from '@certd/pipeline';
|
import { ILogger } from '@certd/basic';
|
||||||
import _ from 'lodash-es';
|
import _ from 'lodash-es';
|
||||||
|
|
||||||
export type K8sClientOpts = {
|
export type K8sClientOpts = {
|
||||||
|
|||||||
@@ -3,6 +3,35 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.27.1](https://github.com/certd/certd/compare/v1.27.0...v1.27.1) (2024-11-04)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* cname 域名映射记录可读性优化 ([b1117ed](https://github.com/certd/certd/commit/b1117ed54a3ef015752999324ff72b821ef5e4b9))
|
||||||
|
|
||||||
|
# [1.27.0](https://github.com/certd/certd/compare/v1.26.16...v1.27.0) (2024-10-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.26.16](https://github.com/certd/certd/compare/v1.26.15...v1.26.16) (2024-10-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.26.15](https://github.com/certd/certd/compare/v1.26.14...v1.26.15) (2024-10-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.26.14](https://github.com/certd/certd/compare/v1.26.13...v1.26.14) (2024-10-26)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 限制其他用户流水线数量 ([315e437](https://github.com/certd/certd/commit/315e43746baf01682737f82e41579237a48409af))
|
||||||
|
* 用户管理优化头像上传 ([661293c](https://github.com/certd/certd/commit/661293c189a3abf3cdc953b5225192372f57930d))
|
||||||
|
|
||||||
|
## [1.26.13](https://github.com/certd/certd/compare/v1.26.12...v1.26.13) (2024-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
## [1.26.12](https://github.com/certd/certd/compare/v1.26.11...v1.26.12) (2024-10-25)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-server
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.26.12",
|
"version": "1.27.1",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -26,9 +26,10 @@
|
|||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.26.12",
|
"@certd/acme-client": "^1.27.1",
|
||||||
"@certd/basic": "^1.26.12",
|
"@certd/basic": "^1.27.1",
|
||||||
"@certd/pipeline": "^1.26.12",
|
"@certd/pipeline": "^1.27.1",
|
||||||
|
"@certd/plus-core": "^1.27.1",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
"@midwayjs/core": "~3.17.1",
|
"@midwayjs/core": "~3.17.1",
|
||||||
"@midwayjs/i18n": "~3.17.3",
|
"@midwayjs/i18n": "~3.17.3",
|
||||||
@@ -69,5 +70,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "3a78cb9929fd63bb72f0e00f4389e775c926c789"
|
"gitHead": "c643d7edc3721a6d2ac701a35ef600f6b6ff4b34"
|
||||||
}
|
}
|
||||||
|
|||||||