mirror of
https://github.com/certd/certd.git
synced 2026-10-25 18:13:00 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b99e78f245 | ||
|
|
289028859c | ||
|
|
e2da200ddb | ||
|
|
7d285840f9 | ||
|
|
5e3958f67a | ||
|
|
0898e2bad9 | ||
|
|
4539c10404 | ||
|
|
e01a84cc7f | ||
|
|
32f65bce9f | ||
|
|
29201d1cf3 | ||
|
|
5326d7dff3 | ||
|
|
cc1c9c7fe7 | ||
|
|
b601b503e2 | ||
|
|
f50651ef91 | ||
|
|
9f18453d2b | ||
|
|
9eb22d3150 | ||
|
|
7ac9101266 | ||
|
|
113c96b866 | ||
|
|
3f118d9c21 | ||
|
|
646a009832 | ||
|
|
bacb141b3b | ||
|
|
9b1cf353b9 | ||
|
|
2b66faef90 | ||
|
|
28e4f70e49 | ||
|
|
93031e7f53 | ||
|
|
d60635f766 | ||
|
|
f5df69fbc9 |
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 非企业模式下禁止API密钥指定项目ID并校验权限【安全加强】 ([f50651e](https://github.com/certd/certd/commit/f50651ef91813b529b8498ddefe0f66b8b7946da))
|
||||
* **authority:** 修复权限校验时角色值错误的问题 ([5326d7d](https://github.com/certd/certd/commit/5326d7dff3967974d70090b45f8580a155c1a032))
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **docker:** 将构建和运行镜像的 Node.js 固定到 22.23.4 安全版本 ([#817](https://github.com/certd/certd/issues/817)) ([113c96b](https://github.com/certd/certd/commit/113c96b866e2ec5c85e37e42150445ed8b0eefbe))
|
||||
* **pipeline:** 修复定时触发器cron归一化截取位置错误导致日期字段被吃掉的问题 ([#813](https://github.com/certd/certd/issues/813)) ([7ac9101](https://github.com/certd/certd/commit/7ac9101266f2821fb13ff68ea6d36969c9485675))
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复修改密码时校验表单字段的错误 ([28e4f70](https://github.com/certd/certd/commit/28e4f70e494f7c56202a8ca4708718c836fff702))
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -3,6 +3,39 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 非企业模式下禁止API密钥指定项目ID并校验权限【安全加强】 ([f50651e](https://github.com/certd/certd/commit/f50651ef91813b529b8498ddefe0f66b8b7946da))
|
||||
* **authority:** 修复权限校验时角色值错误的问题 ([5326d7d](https://github.com/certd/certd/commit/5326d7dff3967974d70090b45f8580a155c1a032))
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **docker:** 将构建和运行镜像的 Node.js 固定到 22.23.4 安全版本 ([#817](https://github.com/certd/certd/issues/817)) ([113c96b](https://github.com/certd/certd/commit/113c96b866e2ec5c85e37e42150445ed8b0eefbe))
|
||||
* **pipeline:** 修复定时触发器cron归一化截取位置错误导致日期字段被吃掉的问题 ([#813](https://github.com/certd/certd/issues/813)) ([7ac9101](https://github.com/certd/certd/commit/7ac9101266f2821fb13ff68ea6d36969c9485675))
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复修改密码时校验表单字段的错误 ([28e4f70](https://github.com/certd/certd/commit/28e4f70e494f7c56202a8ca4708718c836fff702))
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复腾讯云CLB部署证书逻辑 ([a67d5bc](https://github.com/certd/certd/commit/a67d5bca2dd12e157e45ec1b8abff54efcbdfa84))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 为PEM输入组件添加文件拖拽上传功能 ([cfd3844](https://github.com/certd/certd/commit/cfd384485f212cdea0b08e4b35a3f19a1acfe026))
|
||||
* 新增更新金山云KCM SLB证书插件 ([62751be](https://github.com/certd/certd/commit/62751bee7a5e00245bb4dd840a5f4ea35565616a))
|
||||
* 支持ikuai部署证书 ([5f83693](https://github.com/certd/certd/commit/5f83693423ec5ccd08d7bb03e4fb8315dbb8b931))
|
||||
* **baota:** 宝塔站点全自动部署插件支持部署docker站点 ([61ef971](https://github.com/certd/certd/commit/61ef971518eeccbc31b09c06ec1b48589929d6bb))
|
||||
|
||||
## [1.45.1](https://github.com/certd/certd/compare/v1.45.0...v1.45.1) (2026-10-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.45.2"
|
||||
"version": "1.45.5"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/publishlab/node-acme-client/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.45.4](https://github.com/publishlab/node-acme-client/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.45.3](https://github.com/publishlab/node-acme-client/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.45.2](https://github.com/publishlab/node-acme-client/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"main": "./dist/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.9.0",
|
||||
@@ -77,5 +77,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1 +1 @@
|
||||
21:07
|
||||
15:24
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -54,5 +54,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/plus-core": "^1.45.2",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@certd/plus-core": "^1.45.5",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
@@ -51,5 +51,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -31,5 +31,5 @@
|
||||
"prettier": "3.3.3",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -37,5 +37,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -63,5 +63,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,7 +21,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -29,11 +29,11 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.45.2",
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/pipeline": "^1.45.2",
|
||||
"@certd/plugin-lib": "^1.45.2",
|
||||
"@certd/plus-core": "^1.45.2",
|
||||
"@certd/acme-client": "^1.45.5",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@certd/pipeline": "^1.45.5",
|
||||
"@certd/plugin-lib": "^1.45.5",
|
||||
"@certd/plus-core": "^1.45.5",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
"@midwayjs/core": "3.20.11",
|
||||
"@midwayjs/i18n": "3.20.13",
|
||||
@@ -69,5 +69,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -52,5 +52,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -20,7 +20,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plugin-lib": "^1.45.2"
|
||||
"@certd/plugin-lib": "^1.45.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.12",
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -17,9 +17,9 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.45.2",
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/pipeline": "^1.45.2",
|
||||
"@certd/acme-client": "^1.45.5",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@certd/pipeline": "^1.45.5",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "e9b9839d79532e4961dc0de5c097f81235e557f6"
|
||||
"gitHead": "5e3958f67a1249b372ebebf45540a655a12a4824"
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
ARG base_type=alpine
|
||||
|
||||
# 根据 base_type 参数选择基础镜像系列
|
||||
FROM --platform=linux/amd64 node:22-alpine AS base-amd64-alpine
|
||||
FROM --platform=linux/arm64 node:22-alpine AS base-arm64-alpine
|
||||
FROM --platform=linux/arm/v7 node:22-alpine AS base-arm-v7-alpine
|
||||
FROM --platform=linux/amd64 node:22.23.4-alpine AS base-amd64-alpine
|
||||
FROM --platform=linux/arm64 node:22.23.4-alpine AS base-arm64-alpine
|
||||
FROM --platform=linux/arm/v7 node:22.23.4-alpine AS base-arm-v7-alpine
|
||||
|
||||
FROM --platform=linux/amd64 node:22-trixie-slim AS base-amd64-slim
|
||||
FROM --platform=linux/arm64 node:22-trixie-slim AS base-arm64-slim
|
||||
FROM --platform=linux/arm/v7 node:22-alpine AS base-arm-v7-slim
|
||||
FROM --platform=linux/amd64 node:22.23.4-trixie-slim AS base-amd64-slim
|
||||
FROM --platform=linux/arm64 node:22.23.4-trixie-slim AS base-arm64-slim
|
||||
FROM --platform=linux/arm/v7 node:22.23.4-alpine AS base-arm-v7-slim
|
||||
|
||||
FROM base-${TARGETARCH}${TARGETVARIANT:+-}${TARGETVARIANT}-${base_type} AS builder
|
||||
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复修改密码时校验表单字段的错误 ([28e4f70](https://github.com/certd/certd/commit/28e4f70e494f7c56202a8ca4708718c836fff702))
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -104,8 +104,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.45.2",
|
||||
"@certd/pipeline": "^1.45.2",
|
||||
"@certd/lib-iframe": "^1.45.5",
|
||||
"@certd/pipeline": "^1.45.5",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -35,7 +35,7 @@ const validatePass1 = async (rule: any, value: any) => {
|
||||
}
|
||||
const formData = passwordFormRef.value.getFormData();
|
||||
if (formData.confirmNewPassword !== "") {
|
||||
passwordFormRef.value.formRef.formRef.validateFields(["confirmNewPassword"]);
|
||||
passwordFormRef.value.formRef.value.formRef.validateFields(["confirmNewPassword"]);
|
||||
}
|
||||
if (formData.password === formData.newPassword) {
|
||||
throw new Error(t("certd.auth.newPasswordNotSameOld"));
|
||||
|
||||
@@ -3,6 +3,23 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.45.5](https://github.com/certd/certd/compare/v1.45.4...v1.45.5) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 非企业模式下禁止API密钥指定项目ID并校验权限【安全加强】 ([f50651e](https://github.com/certd/certd/commit/f50651ef91813b529b8498ddefe0f66b8b7946da))
|
||||
* **authority:** 修复权限校验时角色值错误的问题 ([5326d7d](https://github.com/certd/certd/commit/5326d7dff3967974d70090b45f8580a155c1a032))
|
||||
|
||||
## [1.45.4](https://github.com/certd/certd/compare/v1.45.3...v1.45.4) (2026-10-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **pipeline:** 修复定时触发器cron归一化截取位置错误导致日期字段被吃掉的问题 ([#813](https://github.com/certd/certd/issues/813)) ([7ac9101](https://github.com/certd/certd/commit/7ac9101266f2821fb13ff68ea6d36969c9485675))
|
||||
|
||||
## [1.45.3](https://github.com/certd/certd/compare/v1.45.2...v1.45.3) (2026-10-19)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-server
|
||||
|
||||
## [1.45.2](https://github.com/certd/certd/compare/v1.45.1...v1.45.2) (2026-10-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.45.2",
|
||||
"version": "1.45.5",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -43,20 +43,20 @@
|
||||
"lint1": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.45.2",
|
||||
"@certd/basic": "^1.45.2",
|
||||
"@certd/commercial-core": "^1.45.2",
|
||||
"@certd/acme-client": "^1.45.5",
|
||||
"@certd/basic": "^1.45.5",
|
||||
"@certd/commercial-core": "^1.45.5",
|
||||
"@certd/cv4pve-api-javascript": "^8.4.2",
|
||||
"@certd/jdcloud": "^1.45.2",
|
||||
"@certd/lib-huawei": "^1.45.2",
|
||||
"@certd/lib-k8s": "^1.45.2",
|
||||
"@certd/lib-server": "^1.45.2",
|
||||
"@certd/midway-flyway-js": "^1.45.2",
|
||||
"@certd/pipeline": "^1.45.2",
|
||||
"@certd/plugin-cert": "^1.45.2",
|
||||
"@certd/plugin-lib": "^1.45.2",
|
||||
"@certd/plugin-plus": "^1.45.2",
|
||||
"@certd/plus-core": "^1.45.2",
|
||||
"@certd/jdcloud": "^1.45.5",
|
||||
"@certd/lib-huawei": "^1.45.5",
|
||||
"@certd/lib-k8s": "^1.45.5",
|
||||
"@certd/lib-server": "^1.45.5",
|
||||
"@certd/midway-flyway-js": "^1.45.5",
|
||||
"@certd/pipeline": "^1.45.5",
|
||||
"@certd/plugin-cert": "^1.45.5",
|
||||
"@certd/plugin-lib": "^1.45.5",
|
||||
"@certd/plugin-plus": "^1.45.5",
|
||||
"@certd/plus-core": "^1.45.5",
|
||||
"@koa/cors": "^5.0.0",
|
||||
"@midwayjs/bootstrap": "3.20.11",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
|
||||
@@ -62,8 +62,8 @@ export class RoleController extends CrudController<RoleService> {
|
||||
@Query("id")
|
||||
id: number
|
||||
) {
|
||||
if (id === 1) {
|
||||
throw new Error("不能删除默认的管理员角色");
|
||||
if (id <= 3) {
|
||||
throw new Error("不能删除系统默认角色");
|
||||
}
|
||||
const res = await super.delete(id);
|
||||
await this.auditLog({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import { Constants, CrudController } from "@certd/lib-server";
|
||||
import { Constants, CrudController, isEnterprise } from "@certd/lib-server";
|
||||
import { AuthService } from "../../../modules/sys/authority/service/auth-service.js";
|
||||
import { OpenKeyService } from "../../../modules/open/service/open-key-service.js";
|
||||
import { ApiTags } from "@midwayjs/swagger";
|
||||
@@ -60,6 +60,10 @@ export class OpenKeyController extends CrudController<OpenKeyService> {
|
||||
const { projectId, userId } = await this.getProjectUserIdRead();
|
||||
body.projectId = projectId;
|
||||
body.userId = userId;
|
||||
if (!isEnterprise()) {
|
||||
//如果是非企业模式,禁止指定projectId
|
||||
delete body.projectId;
|
||||
}
|
||||
const res = await this.service.add(body);
|
||||
this.auditLog({
|
||||
content: `新增了API密钥(ID:${res.id}, scope:${body.scope}, remark:${body.remark})`,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Init, Inject, MidwayWebRouterService, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { IMidwayKoaContext, IWebMiddleware, NextFunction } from "@midwayjs/koa";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Constants, SysPrivateSettings, SysSettingsService } from "@certd/lib-server";
|
||||
import { Constants, isEnterprise, SysPrivateSettings, SysSettingsService } from "@certd/lib-server";
|
||||
import { logger } from "@certd/basic";
|
||||
import { AuthService } from "../modules/sys/authority/service/auth-service.js";
|
||||
import { OpenKeyService } from "../modules/open/service/open-key-service.js";
|
||||
@@ -183,11 +183,18 @@ export class AuthorityMiddleware implements IWebMiddleware {
|
||||
if (!openKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//校验 openKey
|
||||
const openKeyRes = await this.openKeyService.verifyOpenKey(openKey);
|
||||
let roles = [1];
|
||||
if (!openKeyRes.projectId || openKeyRes.projectId <= 0) {
|
||||
let roles = []
|
||||
if (isEnterprise()) {
|
||||
if (!openKeyRes.projectId || openKeyRes.projectId <= 0) {
|
||||
throw new Error("projectId不能为空");
|
||||
}
|
||||
roles = [3]
|
||||
}else {
|
||||
if (openKeyRes.projectId !=null) {
|
||||
throw new Error("对不起,您无权进行此操作");
|
||||
}
|
||||
roles = await this.roleService.getRoleIdsByUserId(openKeyRes.userId);
|
||||
}
|
||||
ctx.user = { id: openKeyRes.userId, roles, projectId: openKeyRes.projectId };
|
||||
|
||||
@@ -83,4 +83,50 @@ describe("PipelineService", () => {
|
||||
};
|
||||
assert.doesNotThrow(() => (service as any).checkTriggers(pipeline));
|
||||
});
|
||||
|
||||
describe("registerCron normalizes every-minute cron like the client editor does", () => {
|
||||
function createService() {
|
||||
const service = new PipelineService();
|
||||
const registered: any[] = [];
|
||||
service.cron = {
|
||||
remove() {},
|
||||
register(req: any) {
|
||||
registered.push(req);
|
||||
},
|
||||
getTaskSize() {
|
||||
return registered.length;
|
||||
},
|
||||
} as any;
|
||||
return { service, registered };
|
||||
}
|
||||
|
||||
it('normalizes "* * 15 * *" to "0 0 15 * *" without eating the first digit of the day field', () => {
|
||||
//与客户端 cron-editor 的归一化结果保持一致:分钟与小时均为 * 时,置为 0 0,其余字段原样保留
|
||||
const { service, registered } = createService();
|
||||
service.registerCron(1, 1, { id: "t1", type: "timer", props: { cron: "* * 15 * *" } });
|
||||
assert.equal(registered.length, 1);
|
||||
assert.equal(registered[0].cron, "0 0 15 * *");
|
||||
});
|
||||
|
||||
it('keeps registration for "* * 1 * *" (single-digit day must not be dropped)', () => {
|
||||
const { service, registered } = createService();
|
||||
service.registerCron(1, 1, { id: "t1", type: "timer", props: { cron: "* * 1 * *" } });
|
||||
assert.equal(registered.length, 1);
|
||||
assert.equal(registered[0].cron, "0 0 1 * *");
|
||||
});
|
||||
|
||||
it('normalizes "* * * * *" to "0 0 * * *"', () => {
|
||||
const { service, registered } = createService();
|
||||
service.registerCron(1, 1, { id: "t1", type: "timer", props: { cron: "* * * * *" } });
|
||||
assert.equal(registered.length, 1);
|
||||
assert.equal(registered[0].cron, "0 0 * * *");
|
||||
});
|
||||
|
||||
it('keeps the existing correct normalization for "* 12 * * *"', () => {
|
||||
const { service, registered } = createService();
|
||||
service.registerCron(1, 1, { id: "t1", type: "timer", props: { cron: "* 12 * * *" } });
|
||||
assert.equal(registered.length, 1);
|
||||
assert.equal(registered[0].cron, "0 12 * * *");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -590,7 +590,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
}
|
||||
cron = cron.trim();
|
||||
if (cron.startsWith("* * ")) {
|
||||
cron = "0 0 " + cron.substring(5);
|
||||
// "* * " 为4个字符,需要跳过整个前缀,否则会吃掉第3个字段(日)的首字符
|
||||
cron = "0 0 " + cron.substring(4);
|
||||
}
|
||||
if (cron.startsWith("* ")) {
|
||||
cron = "0 " + cron.substring(2);
|
||||
|
||||
+544
@@ -0,0 +1,544 @@
|
||||
import "reflect-metadata";
|
||||
import assert from "node:assert/strict";
|
||||
import esmock from "esmock";
|
||||
import { AbstractTaskPlugin, ConcurrencyStrategy, Executor, pluginRegistry, ResultType, RunStrategy } from "@certd/pipeline";
|
||||
import { utils } from "@certd/basic";
|
||||
import { tmpdir } from "node:os";
|
||||
|
||||
const pluginName = "TencentDeleteExpiringCert";
|
||||
const originalNow = Date.now;
|
||||
const originalSleep = utils.sleep;
|
||||
let originalRegistration: any;
|
||||
|
||||
async function createFixture(statuses: Array<number | string | undefined> = [1]) {
|
||||
const certificates = statuses.map((status, index) => ({
|
||||
CertificateId: `cert-${index}`,
|
||||
CertEndTime: "2000-01-01 00:00:00",
|
||||
Alias: "测试证书",
|
||||
Domain: "example.invalid",
|
||||
}));
|
||||
const taskIds = certificates.map((cert, index) => ({ TaskId: `task-${index}` }));
|
||||
const results = statuses.map((status, index) => ({ TaskId: `task-${index}`, CertId: `cert-${index}`, Status: status }));
|
||||
const state: any = {
|
||||
now: originalNow(),
|
||||
certificates,
|
||||
deleteResponse: { CertTaskIds: taskIds },
|
||||
responses: [{ DeleteTaskResult: results }],
|
||||
pollCount: 0,
|
||||
failAction: "",
|
||||
requestError: new Error("模拟接口异常"),
|
||||
};
|
||||
const logs: string[] = [];
|
||||
const calls: Array<{ action: string; params: any }> = [];
|
||||
const sleeps: number[] = [];
|
||||
const controller = new AbortController();
|
||||
const recordLog = (...args: any[]) => {
|
||||
const parts = args.map(String);
|
||||
const line = parts.join(" ");
|
||||
logs.push(line);
|
||||
};
|
||||
const logger = { info: recordLog, error: recordLog, warn: recordLog, debug() {} };
|
||||
const sleep = async (ms: number) => {
|
||||
sleeps.push(ms);
|
||||
state.now += ms;
|
||||
};
|
||||
|
||||
class MockSslClient {
|
||||
async DescribeCertificates(params: any) {
|
||||
const copiedParams = structuredClone(params);
|
||||
calls.push({ action: "DescribeCertificates", params: copiedParams });
|
||||
if (state.failAction === "DescribeCertificates") {
|
||||
throw state.requestError;
|
||||
}
|
||||
return { Certificates: state.certificates };
|
||||
}
|
||||
async doRequest(action: string, params: any) {
|
||||
const copiedParams = structuredClone(params);
|
||||
calls.push({ action, params: copiedParams });
|
||||
if (state.failAction === action) {
|
||||
throw state.requestError;
|
||||
}
|
||||
if (action === "DeleteCertificates") {
|
||||
return state.deleteResponse;
|
||||
}
|
||||
assert.equal(action, "DescribeDeleteCertificatesTaskResult");
|
||||
state.now += 1000;
|
||||
const index = Math.min(state.pollCount, state.responses.length - 1);
|
||||
state.pollCount++;
|
||||
assert.ok(state.pollCount <= 100, "轮询必须有界");
|
||||
return structuredClone(state.responses[index]);
|
||||
}
|
||||
}
|
||||
|
||||
const loaded = await esmock("./index.js", {
|
||||
"@certd/plugin-plus": { AbstractPlusTaskPlugin: AbstractTaskPlugin },
|
||||
"../../../plugin-lib/tencent/index.js": { TencentSslClient: MockSslClient },
|
||||
});
|
||||
const Plugin = loaded.TencentDeleteExpiringCert;
|
||||
Plugin.prototype.getAccess = async () => ({});
|
||||
Date.now = () => state.now;
|
||||
utils.sleep = sleep;
|
||||
const plugin = new Plugin();
|
||||
Object.assign(plugin, { accessId: "mock-access", maxCount: 100, expiringDays: 18, checkTimeout: 1, logger });
|
||||
plugin.ctx = { logger, utils: { sleep }, signal: controller.signal };
|
||||
return { plugin, Plugin, state, logs, calls, sleeps, signal: controller, sleep };
|
||||
}
|
||||
|
||||
async function runPipelineFixture() {
|
||||
const sent: any[] = [];
|
||||
const finished: any[] = [];
|
||||
const writes: Array<{ key: string; value: string }> = [];
|
||||
const pipeline: any = {
|
||||
id: 1,
|
||||
title: "腾讯云清理回归",
|
||||
userId: 1,
|
||||
stages: [
|
||||
{
|
||||
id: "stage-1",
|
||||
title: "部署",
|
||||
concurrency: ConcurrencyStrategy.Serial,
|
||||
tasks: [
|
||||
{
|
||||
id: "task-1",
|
||||
title: "清理",
|
||||
steps: [
|
||||
{
|
||||
id: "step-1",
|
||||
title: "删除旧证书",
|
||||
type: pluginName,
|
||||
strategy: { runStrategy: RunStrategy.AlwaysRun },
|
||||
input: { accessId: "mock-access", maxCount: 100, expiringDays: 18, checkTimeout: 1 },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
notifications: [
|
||||
{ id: "error-notice", title: "失败通知", type: "other", when: ["error"], notificationId: 1 },
|
||||
{ id: "success-notice", title: "成功通知", type: "other", when: ["success"], notificationId: 2 },
|
||||
],
|
||||
};
|
||||
const executor = new Executor({
|
||||
pipeline,
|
||||
storage: {
|
||||
get: async () => null,
|
||||
set: async (_scope, _namespace, _version, key, value) => {
|
||||
writes.push({ key, value });
|
||||
},
|
||||
remove: async () => {},
|
||||
},
|
||||
onChanged: async () => {},
|
||||
onFinished: async history => {
|
||||
const snapshot = structuredClone(history.pipeline);
|
||||
finished.push(snapshot);
|
||||
},
|
||||
accessService: {} as any,
|
||||
emailService: {} as any,
|
||||
notificationService: {
|
||||
send: async request => {
|
||||
sent.push(request);
|
||||
},
|
||||
} as any,
|
||||
cnameProxyService: {} as any,
|
||||
pluginConfigService: { getPluginConfig: async () => ({ sysSetting: { input: {} } }) } as any,
|
||||
urlService: { getPipelineDetailUrl: async () => "https://example.invalid/pipeline/1" } as any,
|
||||
user: { id: 1, role: "user" },
|
||||
serviceGetter: {} as any,
|
||||
fileRootDir: tmpdir(),
|
||||
});
|
||||
const result = await executor.run(1, "manual");
|
||||
return { executor, result, sent, finished, writes };
|
||||
}
|
||||
|
||||
describe("TencentDeleteExpiringCert", () => {
|
||||
beforeEach(() => {
|
||||
const storage = pluginRegistry.getStorage();
|
||||
originalRegistration = storage[pluginName];
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Date.now = originalNow;
|
||||
utils.sleep = originalSleep;
|
||||
if (originalRegistration) {
|
||||
pluginRegistry.register(pluginName, originalRegistration);
|
||||
} else {
|
||||
pluginRegistry.unRegister(pluginName);
|
||||
}
|
||||
});
|
||||
|
||||
for (const [status, reason] of [
|
||||
[2, /失败/],
|
||||
[3, /SSL_QCSLinkedRoleInReplaceLoadCertificate/],
|
||||
[4, /未解绑/],
|
||||
[5, /查询关联.*超时/],
|
||||
[99, /未知状态.*99/],
|
||||
[undefined, /未知状态.*undefined/],
|
||||
["1", /未知状态.*1/],
|
||||
] as Array<[number | string | undefined, RegExp]>) {
|
||||
it(`状态 ${String(status)} 必须传播失败`, async () => {
|
||||
const fixture = await createFixture([status]);
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, reason);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
it("全部成功保持成功且删除参数不变", async () => {
|
||||
const fixture = await createFixture([1, 1]);
|
||||
await fixture.plugin.execute();
|
||||
const request = fixture.calls.find(call => call.action === "DeleteCertificates");
|
||||
assert.deepEqual(request?.params, { CertificateIds: ["cert-0", "cert-1"], IsSync: true });
|
||||
});
|
||||
|
||||
it("跨轮询保留失败而不是被后续成功覆盖", async () => {
|
||||
const fixture = await createFixture([4, 1]);
|
||||
fixture.state.responses = [
|
||||
{
|
||||
DeleteTaskResult: [
|
||||
{ TaskId: "task-0", CertId: "cert-0", Status: 4 },
|
||||
{ TaskId: "task-1", CertId: "cert-1", Status: 0 },
|
||||
],
|
||||
},
|
||||
{ DeleteTaskResult: [{ TaskId: "task-1", CertId: "cert-1", Status: 1 }] },
|
||||
];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /成功[::]\s*1/);
|
||||
assert.match(error.message, /失败[::]\s*1/);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /未解绑/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
assert.equal(fixture.state.pollCount, 2);
|
||||
});
|
||||
|
||||
for (const response of [{ DeleteTaskResult: [{ TaskId: "task-0", CertId: "cert-0", Status: 0 }] }, { DeleteTaskResult: [] }, {}]) {
|
||||
it("未完成或无有效查询结果必须超时失败", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.state.responses = [response];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /超时/);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /未完成[::]\s*1/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
it("混合成功、失败和进行中时超时摘要保留全部结果", async () => {
|
||||
const fixture = await createFixture([1, 4, 0]);
|
||||
fixture.state.responses.push({ DeleteTaskResult: [{ TaskId: "task-2", CertId: "cert-2", Status: 0 }] });
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
for (const pattern of [/超时/, /成功[::]\s*1/, /失败[::]\s*1/, /未完成[::]\s*1/, /task-1/, /未解绑/, /task-2/]) {
|
||||
assert.match(error.message, pattern);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("同批次部分成功不能掩盖失败", async () => {
|
||||
const fixture = await createFixture([1, 4]);
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /成功[::]\s*1/);
|
||||
assert.match(error.message, /失败[::]\s*1/);
|
||||
assert.match(error.message, /task-1/);
|
||||
assert.match(error.message, /未解绑/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
assert.equal(fixture.state.pollCount, 1);
|
||||
});
|
||||
|
||||
for (const status of [2, 3, 4, 5, 99]) {
|
||||
it(`状态 ${status} 通过真实执行链产生失败历史及失败通知`, async () => {
|
||||
await createFixture([status]);
|
||||
const run = await runPipelineFixture();
|
||||
assert.equal(run.result, ResultType.error);
|
||||
const pipeline = run.executor.pipeline;
|
||||
const stage = pipeline.stages[0];
|
||||
const task = stage.tasks[0];
|
||||
const step = task.steps[0];
|
||||
for (const runnable of [step, task, stage, pipeline]) {
|
||||
assert.equal(runnable.status?.status, ResultType.error);
|
||||
assert.equal(runnable.status?.result, ResultType.error);
|
||||
}
|
||||
assert.equal(run.finished.length, 1);
|
||||
assert.equal(run.finished[0].status.status, ResultType.error);
|
||||
const saved = run.writes.find(write => write.key === "lastRuntime");
|
||||
assert.ok(saved);
|
||||
const storedValue = JSON.parse(saved.value);
|
||||
const history = storedValue.value;
|
||||
assert.equal(history.pipeline.status.status, ResultType.error);
|
||||
const sentIds = run.sent.map(request => request.id);
|
||||
assert.deepEqual(sentIds, [1]);
|
||||
assert.match(run.sent[0].body.content, /task-0/);
|
||||
});
|
||||
}
|
||||
|
||||
it("成功对照通过真实执行链只发送成功通知", async () => {
|
||||
await createFixture([1]);
|
||||
const run = await runPipelineFixture();
|
||||
assert.equal(run.result, ResultType.success);
|
||||
const pipeline = run.executor.pipeline;
|
||||
const stage = pipeline.stages[0];
|
||||
const task = stage.tasks[0];
|
||||
for (const runnable of [task.steps[0], task, stage, pipeline]) {
|
||||
assert.equal(runnable.status?.status, ResultType.success);
|
||||
}
|
||||
const sentIds = run.sent.map(request => request.id);
|
||||
assert.deepEqual(sentIds, [2]);
|
||||
});
|
||||
|
||||
for (const response of [undefined, null, {}, { CertTaskIds: [] }, { CertTaskIds: {} }, { CertTaskIds: [{}] }, { CertTaskIds: [{ TaskId: " " }] }, { CertTaskIds: [{ TaskId: "task-0" }, {}] }]) {
|
||||
it("提交结果不完整时不允许误判成功或依赖偶然TypeError", async () => {
|
||||
const fixture = await createFixture([1]);
|
||||
fixture.state.deleteResponse = response;
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.notEqual(error.name, "TypeError");
|
||||
assert.match(error.message, /删除任务提交结果异常/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
const queries = fixture.calls.filter(call => call.action === "DescribeDeleteCertificatesTaskResult");
|
||||
assert.equal(queries.length, 0);
|
||||
});
|
||||
}
|
||||
|
||||
it("重复、无关和缺少TaskId的结果不污染计数", async () => {
|
||||
const fixture = await createFixture([1, 4]);
|
||||
fixture.state.responses = [
|
||||
{
|
||||
DeleteTaskResult: [
|
||||
{ TaskId: "task-0", CertId: "cert-0", Status: 1 },
|
||||
{ TaskId: "task-0", CertId: "cert-0", Status: 1 },
|
||||
{ TaskId: "other-task", CertId: "other-cert", Status: 4 },
|
||||
{ Status: 4 },
|
||||
{ TaskId: "task-1", CertId: "cert-1", Status: 0 },
|
||||
],
|
||||
},
|
||||
{
|
||||
DeleteTaskResult: [
|
||||
{ TaskId: "task-0", CertId: "cert-0", Status: 1 },
|
||||
{ TaskId: "task-1", CertId: "cert-1", Status: 4 },
|
||||
],
|
||||
},
|
||||
];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /成功[::]\s*1/);
|
||||
assert.match(error.message, /失败[::]\s*1/);
|
||||
assert.doesNotMatch(error.message, /other-task/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
assert.equal(fixture.state.pollCount, 2);
|
||||
const queries = fixture.calls.filter(call => call.action === "DescribeDeleteCertificatesTaskResult");
|
||||
assert.deepEqual(queries[1].params.TaskIds, ["task-1"]);
|
||||
});
|
||||
|
||||
it("重复的已提交任务ID仅处理一次", async () => {
|
||||
const fixture = await createFixture([1]);
|
||||
fixture.state.deleteResponse = { CertTaskIds: [{ TaskId: "task-0" }, { TaskId: "task-0" }] };
|
||||
await fixture.plugin.execute();
|
||||
const query = fixture.calls.find(call => call.action === "DescribeDeleteCertificatesTaskResult");
|
||||
assert.deepEqual(query?.params.TaskIds, ["task-0"]);
|
||||
});
|
||||
|
||||
for (const response of [{ DeleteTaskResult: [] }, {}]) {
|
||||
it("无有效查询结果时等待而不是忙等", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.state.responses = [response];
|
||||
await assert.rejects(() => fixture.plugin.execute(), /超时/);
|
||||
assert.ok(fixture.sleeps.length > 0);
|
||||
const allWaitsUseExistingInterval = fixture.sleeps.every(ms => ms === 10000);
|
||||
assert.ok(allWaitsUseExistingInterval);
|
||||
assert.ok(fixture.state.pollCount < 20);
|
||||
});
|
||||
}
|
||||
|
||||
for (const noCandidates of ["empty", "not-expiring"]) {
|
||||
it(`没有符合条件的证书时正常结束:${noCandidates}`, async () => {
|
||||
const fixture = await createFixture([1]);
|
||||
if (noCandidates === "empty") {
|
||||
fixture.state.certificates = [];
|
||||
} else {
|
||||
fixture.state.certificates[0].CertEndTime = "2999-01-01 00:00:00";
|
||||
}
|
||||
await fixture.plugin.execute();
|
||||
const deleteWasRequested = fixture.calls.some(call => call.action === "DeleteCertificates");
|
||||
assert.equal(deleteWasRequested, false);
|
||||
});
|
||||
}
|
||||
|
||||
for (const action of ["DescribeCertificates", "DeleteCertificates", "DescribeDeleteCertificatesTaskResult"]) {
|
||||
it(`接口异常原样传播:${action}`, async () => {
|
||||
const fixture = await createFixture([1]);
|
||||
fixture.state.failAction = action;
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
error => error === fixture.state.requestError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
it("取消信号不被转换为成功或普通超时", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.signal.abort();
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
// CancelError 未设置 this.name,依赖侧 .name 仍为 Error;用构造名确认取消语义
|
||||
assert.equal(error.constructor.name, "CancelError");
|
||||
assert.match(error.message, /取消/);
|
||||
assert.doesNotMatch(error.message, /超时/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("超时通过真实执行链产生失败历史及失败通知", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
const run = await runPipelineFixture();
|
||||
assert.equal(run.result, ResultType.error);
|
||||
const pipeline = run.executor.pipeline;
|
||||
const stage = pipeline.stages[0];
|
||||
const task = stage.tasks[0];
|
||||
for (const runnable of [task.steps[0], task, stage, pipeline]) {
|
||||
assert.equal(runnable.status?.status, ResultType.error);
|
||||
}
|
||||
assert.equal(run.finished[0].status.status, ResultType.error);
|
||||
const sentIds = run.sent.map(request => request.id);
|
||||
assert.deepEqual(sentIds, [1]);
|
||||
assert.match(run.sent[0].body.content, /超时/);
|
||||
assert.ok(fixture.sleeps.length > 0);
|
||||
});
|
||||
|
||||
it("提交响应Fail与任务成功并存时整批失败并保留失败证书明细", async () => {
|
||||
const fixture = await createFixture([1, 1]);
|
||||
fixture.state.deleteResponse = {
|
||||
Fail: [{ CertId: "cert-0", Msg: "证书仍被资源绑定" }],
|
||||
CertTaskIds: [{ CertId: "cert-1", TaskId: "task-1" }],
|
||||
};
|
||||
fixture.state.responses = [{ DeleteTaskResult: [{ TaskId: "task-1", CertId: "cert-1", Status: 1 }] }];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /删除证书任务失败/);
|
||||
assert.match(error.message, /成功[::]\s*1/);
|
||||
assert.match(error.message, /失败[::]\s*1/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
assert.match(error.message, /证书仍被资源绑定/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("CertTaskIds为空且Fail非空时抛删除证书任务失败并含Fail明细", async () => {
|
||||
const fixture = await createFixture([1]);
|
||||
fixture.state.deleteResponse = {
|
||||
Fail: [{ CertId: "cert-0", Msg: "证书不存在或已删除" }],
|
||||
CertTaskIds: [],
|
||||
};
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /删除证书任务失败/);
|
||||
assert.doesNotMatch(error.message, /删除任务提交结果异常/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
assert.match(error.message, /证书不存在或已删除/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
const queries = fixture.calls.filter(call => call.action === "DescribeDeleteCertificatesTaskResult");
|
||||
assert.equal(queries.length, 0);
|
||||
});
|
||||
|
||||
it("提交响应Fail通过真实执行链产生失败历史及失败通知", async () => {
|
||||
const fixture = await createFixture([1, 1]);
|
||||
fixture.state.deleteResponse = {
|
||||
Fail: [{ CertId: "cert-0", Msg: "证书仍被资源绑定" }],
|
||||
CertTaskIds: [{ CertId: "cert-1", TaskId: "task-1" }],
|
||||
};
|
||||
fixture.state.responses = [{ DeleteTaskResult: [{ TaskId: "task-1", CertId: "cert-1", Status: 1 }] }];
|
||||
const run = await runPipelineFixture();
|
||||
assert.equal(run.result, ResultType.error);
|
||||
const pipeline = run.executor.pipeline;
|
||||
const stage = pipeline.stages[0];
|
||||
const task = stage.tasks[0];
|
||||
for (const runnable of [task.steps[0], task, stage, pipeline]) {
|
||||
assert.equal(runnable.status?.status, ResultType.error);
|
||||
}
|
||||
const sentIds = run.sent.map(request => request.id);
|
||||
assert.deepEqual(sentIds, [1]);
|
||||
assert.match(run.sent[0].body.content, /cert-0/);
|
||||
assert.match(run.sent[0].body.content, /证书仍被资源绑定/);
|
||||
});
|
||||
|
||||
it("提交含CertId映射且查询持续为空时超时摘要保留CertId", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.state.deleteResponse = { CertTaskIds: [{ CertId: "cert-0", TaskId: "task-0" }] };
|
||||
fixture.state.responses = [{ DeleteTaskResult: [] }];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /超时/);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
assert.match(error.message, /未完成[::]\s*1/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("轮询结果丢失CertId时失败摘要保留此前已知CertId", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.state.deleteResponse = { CertTaskIds: [{ TaskId: "task-0" }] };
|
||||
fixture.state.responses = [{ DeleteTaskResult: [{ TaskId: "task-0", CertId: "cert-0", Status: 0 }] }, { DeleteTaskResult: [{ TaskId: "task-0", Status: 4 }] }];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /删除证书任务失败/);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
assert.match(error.message, /未解绑/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("提交映射有CertId且轮询全程不带CertId时摘要仍含CertId", async () => {
|
||||
const fixture = await createFixture([0]);
|
||||
fixture.state.deleteResponse = { CertTaskIds: [{ CertId: "cert-0", TaskId: "task-0" }] };
|
||||
fixture.state.responses = [{ DeleteTaskResult: [{ TaskId: "task-0", Status: 4 }] }];
|
||||
await assert.rejects(
|
||||
() => fixture.plugin.execute(),
|
||||
(error: Error) => {
|
||||
assert.match(error.message, /删除证书任务失败/);
|
||||
assert.match(error.message, /task-0/);
|
||||
assert.match(error.message, /cert-0/);
|
||||
assert.match(error.message, /未解绑/);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
+122
-33
@@ -127,15 +127,8 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
|
||||
IsSync: true,
|
||||
});
|
||||
this.logger.info("删除任务已提交: ", JSON.stringify(deleteRes));
|
||||
const ids = deleteRes?.CertTaskIds;
|
||||
if (!ids && !ids.length) {
|
||||
this.logger.error("没有找到任务ID");
|
||||
return;
|
||||
}
|
||||
const taskIds = ids.map((id: any) => id.TaskId);
|
||||
const startTime = Date.now();
|
||||
const results = {};
|
||||
|
||||
const results: Record<string, { certId?: string; status: unknown; reason: string }> = {};
|
||||
const statusCount = {
|
||||
success: 0,
|
||||
failed: 0,
|
||||
@@ -143,6 +136,67 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
|
||||
unbind: 0,
|
||||
timeout: 0,
|
||||
};
|
||||
|
||||
const failList = deleteRes?.Fail;
|
||||
if (failList != null && !Array.isArray(failList)) {
|
||||
throw new Error("删除证书任务失败;提交阶段失败明细格式异常");
|
||||
}
|
||||
if (Array.isArray(failList)) {
|
||||
for (let i = 0; i < failList.length; i++) {
|
||||
const failItem = failList[i];
|
||||
let failCertId = failItem?.CertId;
|
||||
if (typeof failCertId !== "string" || failCertId.trim().length === 0) {
|
||||
failCertId = `unknown-${i}`;
|
||||
}
|
||||
let failReason = failItem?.Msg;
|
||||
if (typeof failReason !== "string" || failReason.trim().length === 0) {
|
||||
failReason = "未知原因";
|
||||
}
|
||||
const failKey = `submit-fail:${failCertId}`;
|
||||
results[failKey] = {
|
||||
certId: failCertId,
|
||||
status: "submit-fail",
|
||||
reason: failReason,
|
||||
};
|
||||
statusCount.failed++;
|
||||
this.logger.error(`提交阶段删除失败 证书${failCertId}: ${failReason}`);
|
||||
}
|
||||
}
|
||||
const submitFailCount = Array.isArray(failList) ? failList.length : 0;
|
||||
|
||||
const ids = deleteRes?.CertTaskIds;
|
||||
if (!Array.isArray(ids) || ids.length === 0) {
|
||||
if (submitFailCount > 0) {
|
||||
const failSummary = `任务总数:0,成功:0,失败:${statusCount.failed},未完成:0,任务结果:${JSON.stringify(results)},未完成任务:`;
|
||||
throw new Error(`删除证书任务失败;${failSummary}`);
|
||||
}
|
||||
throw new Error("删除任务提交结果异常:没有有效任务ID");
|
||||
}
|
||||
const taskIds: string[] = [];
|
||||
const certIdByTaskId: Record<string, string> = {};
|
||||
for (const entry of ids) {
|
||||
const taskId = entry?.TaskId;
|
||||
if (typeof taskId !== "string" || taskId.trim().length === 0) {
|
||||
throw new Error("删除任务提交结果异常:存在无效任务ID");
|
||||
}
|
||||
if (!taskIds.includes(taskId)) {
|
||||
taskIds.push(taskId);
|
||||
}
|
||||
const submitCertId = entry?.CertId;
|
||||
if (typeof submitCertId === "string" && submitCertId.trim().length > 0) {
|
||||
certIdByTaskId[taskId] = submitCertId;
|
||||
if (!results[taskId]) {
|
||||
results[taskId] = {
|
||||
certId: submitCertId,
|
||||
status: undefined,
|
||||
reason: "待查询",
|
||||
};
|
||||
} else if (!results[taskId].certId) {
|
||||
results[taskId].certId = submitCertId;
|
||||
}
|
||||
}
|
||||
}
|
||||
const startTime = Date.now();
|
||||
const total = taskIds.length;
|
||||
|
||||
while (Date.now() < startTime + this.checkTimeout * 60 * 1000) {
|
||||
@@ -150,44 +204,61 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
|
||||
const taskResultRes = await sslClient.doRequest("DescribeDeleteCertificatesTaskResult", {
|
||||
TaskIds: taskIds,
|
||||
});
|
||||
const result = taskResultRes.DeleteTaskResult;
|
||||
if (!result || result.length === 0) {
|
||||
const result = taskResultRes?.DeleteTaskResult;
|
||||
if (!Array.isArray(result) || result.length === 0) {
|
||||
this.logger.info("暂未获取到有效的任务结果");
|
||||
await this.ctx.utils.sleep(10000);
|
||||
continue;
|
||||
}
|
||||
for (const item of result) {
|
||||
//遍历结果
|
||||
const status = item.Status;
|
||||
if (status !== 0) {
|
||||
remove(taskIds, id => id === item.TaskId);
|
||||
const taskId = item?.TaskId;
|
||||
if (!taskIds.includes(taskId)) {
|
||||
continue;
|
||||
}
|
||||
// Status : 0表示任务进行中、 1表示任务成功、 2表示任务失败、3表示未授权服务角色导致任务失败、4表示有未解绑的云资源导致任务失败、5表示查询关联云资源超时导致任务失败
|
||||
const status = item.Status;
|
||||
let reason = "";
|
||||
if (status === 0) {
|
||||
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 进行中`);
|
||||
reason = "进行中";
|
||||
} else if (status === 1) {
|
||||
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 成功`);
|
||||
results[item.TaskId] = "成功";
|
||||
reason = "成功";
|
||||
statusCount.success++;
|
||||
} else if (status === 2) {
|
||||
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 失败`);
|
||||
results[item.TaskId] = "失败";
|
||||
reason = "失败";
|
||||
statusCount.failed++;
|
||||
} else if (status === 3) {
|
||||
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 未授权服务角色导致任务失败`);
|
||||
results[item.TaskId] = "未授权服务角色导致任务失败";
|
||||
reason = "未授权服务角色导致任务失败";
|
||||
statusCount.unauthorized++;
|
||||
} else if (status === 4) {
|
||||
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 有未解绑的云资源导致任务失败`);
|
||||
results[item.TaskId] = "有未解绑的云资源导致任务失败";
|
||||
reason = "有未解绑的云资源导致任务失败";
|
||||
statusCount.unbind++;
|
||||
} else if (status === 5) {
|
||||
this.logger.error(`任务${item.TaskId}<${item.CertId}>: 查询关联云资源超时导致任务失败`);
|
||||
results[item.TaskId] = "查询关联云资源超时导致任务失败";
|
||||
reason = "查询关联云资源超时导致任务失败";
|
||||
statusCount.timeout++;
|
||||
} else {
|
||||
this.logger.info(`任务${item.TaskId}<${item.CertId}>: 未知状态:${status}`);
|
||||
reason = `未知状态:${String(status)}`;
|
||||
statusCount.failed++;
|
||||
}
|
||||
let certId = item.CertId;
|
||||
const hasPollCertId = typeof certId === "string" && certId.trim().length > 0;
|
||||
if (!hasPollCertId) {
|
||||
const previousCertId = results[taskId]?.certId;
|
||||
if (previousCertId) {
|
||||
certId = previousCertId;
|
||||
} else {
|
||||
certId = certIdByTaskId[taskId];
|
||||
}
|
||||
}
|
||||
results[taskId] = { certId, status, reason };
|
||||
const message = `任务${taskId}<${certId}>: ${reason}`;
|
||||
if (status === 0 || status === 1) {
|
||||
this.logger.info(message);
|
||||
} else {
|
||||
this.logger.error(message);
|
||||
}
|
||||
if (status !== 0) {
|
||||
remove(taskIds, id => id === taskId);
|
||||
}
|
||||
}
|
||||
this.logger.info(
|
||||
// eslint-disable-next-line max-len
|
||||
@@ -195,16 +266,34 @@ export class TencentDeleteExpiringCert extends AbstractPlusTaskPlugin {
|
||||
);
|
||||
if (taskIds.length === 0) {
|
||||
this.logger.info("任务已全部完成");
|
||||
|
||||
if (statusCount.unauthorized > 0) {
|
||||
throw new Error("有未授权服务角色导致任务失败,需给Access授权服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate");
|
||||
}
|
||||
|
||||
return;
|
||||
break;
|
||||
}
|
||||
await this.ctx.utils.sleep(10000);
|
||||
}
|
||||
this.logger.error("检查任务结果超时", JSON.stringify(results));
|
||||
|
||||
const failedCount = statusCount.failed + statusCount.unauthorized + statusCount.unbind + statusCount.timeout;
|
||||
const resultDetails = JSON.stringify(results);
|
||||
const pendingParts: string[] = [];
|
||||
for (const pendingTaskId of taskIds) {
|
||||
const pendingCertId = results[pendingTaskId]?.certId ?? certIdByTaskId[pendingTaskId];
|
||||
if (pendingCertId) {
|
||||
pendingParts.push(`${pendingTaskId}<${pendingCertId}>`);
|
||||
} else {
|
||||
pendingParts.push(pendingTaskId);
|
||||
}
|
||||
}
|
||||
const pendingTaskDetails = pendingParts.join(",");
|
||||
let summary = `任务总数:${total},成功:${statusCount.success},失败:${failedCount},未完成:${taskIds.length},任务结果:${resultDetails},未完成任务:${pendingTaskDetails}`;
|
||||
if (statusCount.unauthorized > 0) {
|
||||
summary += ";有未授权服务角色导致任务失败,需给Access授权服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate";
|
||||
}
|
||||
if (taskIds.length > 0) {
|
||||
throw new Error(`检查任务结果超时;${summary}`);
|
||||
}
|
||||
if (failedCount > 0) {
|
||||
throw new Error(`删除证书任务失败;${summary}`);
|
||||
}
|
||||
this.logger.info(`删除证书任务全部成功;${summary}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
22:55
|
||||
15:43
|
||||
|
||||
@@ -1 +1 @@
|
||||
23:23
|
||||
15:37
|
||||
|
||||
Reference in New Issue
Block a user