mirror of
https://github.com/certd/certd.git
synced 2026-04-06 16:00:54 +08:00
Compare commits
251 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c4756da81 | ||
|
|
f4fe03c790 | ||
|
|
a748bb9352 | ||
|
|
9339b78f80 | ||
|
|
8449f8580d | ||
|
|
0948c5bc69 | ||
|
|
857589b365 | ||
|
|
c39b1bf823 | ||
|
|
298006a4b9 | ||
|
|
903a4131ab | ||
|
|
a0ec0ddb14 | ||
|
|
46eb876f9b | ||
|
|
8374c3941a | ||
|
|
8cec14c2ff | ||
|
|
c716f105bd | ||
|
|
737be1f571 | ||
|
|
6f17c700b8 | ||
|
|
04d79f9117 | ||
|
|
8145808c43 | ||
|
|
86d5626d92 | ||
|
|
70760e4ede | ||
|
|
8a32fd36ad | ||
|
|
2e30fff221 | ||
|
|
667ffa5dff | ||
|
|
d271120c24 | ||
|
|
a03ae5a216 | ||
|
|
0e73fa40bc | ||
|
|
5d6f0d8546 | ||
|
|
41e23fb6a8 | ||
|
|
4e15556e5e | ||
|
|
bf30b7afae | ||
|
|
8801afa586 | ||
|
|
47804353f9 | ||
|
|
be58e3084b | ||
|
|
71d5ab21ed | ||
|
|
993bc7432f | ||
|
|
99ff879d93 | ||
|
|
caa15b4735 | ||
|
|
cc8da0cf13 | ||
|
|
0b6618ff70 | ||
|
|
6f180f534c | ||
|
|
4220ef2a5b | ||
|
|
2acaa66635 | ||
|
|
ee5eecbec1 | ||
|
|
687bb8a237 | ||
|
|
e51123a951 | ||
|
|
92bb12e2e3 | ||
|
|
fd0536bd4b | ||
|
|
57389a79a1 | ||
|
|
6cd7bddc37 | ||
|
|
c3c5006daa | ||
|
|
27a8a57cf5 | ||
|
|
3bded6fdcc | ||
|
|
c7f31337ce | ||
|
|
fd507f2692 | ||
|
|
96a39ef9c3 | ||
|
|
81a8d6c3bf | ||
|
|
d4719208f0 | ||
|
|
c36dce6464 | ||
|
|
2da4474bb1 | ||
|
|
cab11202c7 | ||
|
|
21d7d35bb1 | ||
|
|
0725c663c4 | ||
|
|
ce82239c8b | ||
|
|
2523008cb6 | ||
|
|
69212b9ad1 | ||
|
|
636cb3399b | ||
|
|
86ca35ce33 | ||
|
|
675ab31305 | ||
|
|
83c2d743bc | ||
|
|
2c87b3d906 | ||
|
|
05b6159802 | ||
|
|
c56f48c1e3 | ||
|
|
e18e399ce6 | ||
|
|
d66ade4e47 | ||
|
|
90b045af6d | ||
|
|
5cccb21175 | ||
|
|
1a71969403 | ||
|
|
389a1fbd04 | ||
|
|
ca02ae6183 | ||
|
|
92446cb048 | ||
|
|
954ce4533f | ||
|
|
f7b88f9e3b | ||
|
|
736fe038eb | ||
|
|
abcd257db0 | ||
|
|
c38b5f3cdc | ||
|
|
b649617e04 | ||
|
|
a4e2287101 | ||
|
|
fbb66f3c43 | ||
|
|
fedf90ea78 | ||
|
|
d558d50102 | ||
|
|
656cb89fe8 | ||
|
|
1e6ddd250e | ||
|
|
1de8eee6ea | ||
|
|
425bba67c5 | ||
|
|
8b0daf7200 | ||
|
|
589a373142 | ||
|
|
0cfc71e4bf | ||
|
|
92dabe6276 | ||
|
|
d1b61b6bf9 | ||
|
|
873f2b618b | ||
|
|
4453070060 | ||
|
|
de40be430b | ||
|
|
29a6a992f0 | ||
|
|
0a7d2d6264 | ||
|
|
e09f92f9ee | ||
|
|
9be1ecc8aa | ||
|
|
729b19c8da | ||
|
|
a9fffa5180 | ||
|
|
0069c0e399 | ||
|
|
b6fd38e293 | ||
|
|
36aa7f82b0 | ||
|
|
d01004d530 | ||
|
|
d85a02feeb | ||
|
|
b82e1dcd62 | ||
|
|
74c6a2266f | ||
|
|
9754223f31 | ||
|
|
cfbbac9796 | ||
|
|
fece8955cf | ||
|
|
170b2afb0e | ||
|
|
ee8af18d0a | ||
|
|
27386ea04d | ||
|
|
0d71a8ee50 | ||
|
|
82a72e0b49 | ||
|
|
5035c123f0 | ||
|
|
474b3372d8 | ||
|
|
be87124ada | ||
|
|
aa3032db35 | ||
|
|
a4ead79888 | ||
|
|
98445afd3e | ||
|
|
3eb9671640 | ||
|
|
95fb4e3e8b | ||
|
|
818015d24a | ||
|
|
e11bd3e813 | ||
|
|
2a4d64af95 | ||
|
|
d73cb4be2b | ||
|
|
82752040f8 | ||
|
|
1bde6d8b9c | ||
|
|
be55d36f67 | ||
|
|
f07724372d | ||
|
|
5b8d5dd975 | ||
|
|
e36aa065e9 | ||
|
|
45486ef399 | ||
|
|
4fedf6f452 | ||
|
|
702b80ef75 | ||
|
|
a5c7789dbc | ||
|
|
bddef199ff | ||
|
|
fa6fc07009 | ||
|
|
8d9b44528b | ||
|
|
1d108d775c | ||
|
|
7af111ac57 | ||
|
|
6451f00639 | ||
|
|
31718d1a4a | ||
|
|
832b74b66b | ||
|
|
082802e119 | ||
|
|
efa9c748c5 | ||
|
|
fc8bef5aae | ||
|
|
441b15ed2f | ||
|
|
11d1f6e141 | ||
|
|
0f5b9564c6 | ||
|
|
0c8a84656a | ||
|
|
330f91e15b | ||
|
|
490141a920 | ||
|
|
1e288b14d0 | ||
|
|
81df96bf45 | ||
|
|
d1ab5f74a6 | ||
|
|
e43dd03132 | ||
|
|
2c6d64976f | ||
|
|
065713cdb6 | ||
|
|
746d3c97c3 | ||
|
|
9557fc799e | ||
|
|
8fcabc5e9f | ||
|
|
2b4b15f558 | ||
|
|
057b0b4565 | ||
|
|
70a2402521 | ||
|
|
de34db3394 | ||
|
|
0c2ae792ec | ||
|
|
a4c0b92777 | ||
|
|
b9d78135e0 | ||
|
|
5641c19502 | ||
|
|
0110dfdb70 | ||
|
|
140606744b | ||
|
|
335d175d57 | ||
|
|
779db9da70 | ||
|
|
5d29a08ab7 | ||
|
|
1fe3365e10 | ||
|
|
f0584c88e8 | ||
|
|
c7620dfc48 | ||
|
|
5d6a945763 | ||
|
|
4fe5939d0b | ||
|
|
bcaf54d4cb | ||
|
|
44d43f45cb | ||
|
|
de26ee9383 | ||
|
|
d442462952 | ||
|
|
558fc9f306 | ||
|
|
9f0ee219d0 | ||
|
|
5164116bde | ||
|
|
02404bc97e | ||
|
|
0ebdb037b5 | ||
|
|
a8b60c32b3 | ||
|
|
416621d503 | ||
|
|
b917eb447c | ||
|
|
2ce3c71b88 | ||
|
|
ca13bfa5f8 | ||
|
|
d8812196f3 | ||
|
|
4e750bdbe1 | ||
|
|
f59a37b77c | ||
|
|
ea3db93db9 | ||
|
|
26f2c9fea2 | ||
|
|
290cc0d1bb | ||
|
|
78044c062e | ||
|
|
3a2f653229 | ||
|
|
bbe22e6f36 | ||
|
|
d4474ff0fb | ||
|
|
c7979f1be5 | ||
|
|
ada0b7106e | ||
|
|
c3a5542935 | ||
|
|
2eebb3388a | ||
|
|
287c3688fd | ||
|
|
3948b3993f | ||
|
|
fe4367c580 | ||
|
|
e70732c9ac | ||
|
|
42ad04cabd | ||
|
|
7f5e89d489 | ||
|
|
c504f33b1f | ||
|
|
ed6a18dae7 | ||
|
|
844c4bf983 | ||
|
|
43961c1c18 | ||
|
|
7b42d7252e | ||
|
|
4aa136189a | ||
|
|
c66802af2d | ||
|
|
49e65c611f | ||
|
|
abf29bc164 | ||
|
|
08854e0ab9 | ||
|
|
575416a16d | ||
|
|
3dd0783510 | ||
|
|
fadb1d35b3 | ||
|
|
27a9fc32a6 | ||
|
|
7008a408ca | ||
|
|
b928bb46c7 | ||
|
|
18c9c4a166 | ||
|
|
49fa01f209 | ||
|
|
fe9d443100 | ||
|
|
3dec43d8d4 | ||
|
|
5ab2943c3a | ||
|
|
6e8b0eeca9 | ||
|
|
d0c4dfca97 | ||
|
|
f4a11ed328 | ||
|
|
b2971cf5fb | ||
|
|
f97827ec76 | ||
|
|
f230a2a94d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -21,7 +21,7 @@ gen
|
||||
/packages/ui/*/.idea
|
||||
/packages/ui/*/node_modules
|
||||
/packages/*/node_modules
|
||||
/pnpm-lock.yaml
|
||||
#/pnpm-lock.yaml
|
||||
|
||||
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
183
CHANGELOG.md
183
CHANGELOG.md
@@ -3,6 +3,189 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 创建cname记录移除域名两端的空格 ([903a413](https://github.com/certd/certd/commit/903a4131ab5f42c8286cd2150ed1032d486fda2f))
|
||||
* 修复从本地dns获取记录报错的bug ([c39b1bf](https://github.com/certd/certd/commit/c39b1bf823ddc6216bed2049e4c87e6107def08a))
|
||||
|
||||
### Features
|
||||
|
||||
* 优化证书申请速度,修复某些情况下letsencrypt 校验失败的问题 ([857589b](https://github.com/certd/certd/commit/857589b365c6f709e0ae67914d2f50ce182e6dd6))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化华为dns解析记录创建和删除问题 ([0948c5b](https://github.com/certd/certd/commit/0948c5bc691d2ee6eb47c72a85da1b7453361878))
|
||||
* 又拍云支持云存储 ([9339b78](https://github.com/certd/certd/commit/9339b78f801d193472c0af25749e8e7a27ffb7af))
|
||||
* 又拍云支持云存储 ([8449f85](https://github.com/certd/certd/commit/8449f8580da90c1f6b5d02d07c3236ebaf6cf161))
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复ssh支持键盘事件登录 ([8145808](https://github.com/certd/certd/commit/8145808c4370364377b4ffe3ae88ff465b49f20b))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到京东云cdn ([6f17c70](https://github.com/certd/certd/commit/6f17c700b84965baa01b40fe2abaa0a91bcbaffd))
|
||||
* 支持京东云dns申请证书 ([04d79f9](https://github.com/certd/certd/commit/04d79f9117670be504960b018fd49ae3bf7c1c11))
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* tab增加图标显示 ([a03ae5a](https://github.com/certd/certd/commit/a03ae5a216a1df2c1d3da12ae18dcd0f089a92d3))
|
||||
* 升级lego版本到4.22.2 ([4e15556](https://github.com/certd/certd/commit/4e15556e5e8100719497edb1729570d5a29668e1))
|
||||
* 优化华为dns接口报错信息输出 ([bf30b7a](https://github.com/certd/certd/commit/bf30b7afaef623dd8126570344f1fcc2c06f1215))
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复华为云dns接口请求出错的bug ([caa15b4](https://github.com/certd/certd/commit/caa15b47355363cbb8847f415ff12363cd53eeda))
|
||||
* 修复某些情况下站点证书监控报undefined.includes的错误 ([0b6618f](https://github.com/certd/certd/commit/0b6618ff709322a0eeba78953c8c6e9d073d083a))
|
||||
* 修复网站证书监控https port设置无效的bug ([cc8da0c](https://github.com/certd/certd/commit/cc8da0cf130f0c469371b59ac5bd04567f4a4414))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 站点监控保存时异步检查 ([993bc74](https://github.com/certd/certd/commit/993bc7432fce2d954e9897ed85b54f22150bfc7e))
|
||||
* dns支持火山引擎 ([99ff879](https://github.com/certd/certd/commit/99ff879d93658c29ea493a4bde7e9e3f85996d64))
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复编辑通知勾选默认,导致出现多个默认通知的bug ([6cd7bdd](https://github.com/certd/certd/commit/6cd7bddc37da8b0d7b9860fd9a26ddfe84c869a7))
|
||||
* 修复网站监控无法设置端口的bug ([27a8a57](https://github.com/certd/certd/commit/27a8a57cf52b4bf83d628aa3049be1efaa74f29c))
|
||||
* 修复lego模式无法创建流水线的bug ([687bb8a](https://github.com/certd/certd/commit/687bb8a2376d0de7b72739a174e4a9560581f866))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化通知格式 ([c3c5006](https://github.com/certd/certd/commit/c3c5006daa39c20624cb58864f2b92b230a38a7a))
|
||||
* 优化scp上传 ([e51123a](https://github.com/certd/certd/commit/e51123a95131cc76d655937488caf08956a67020))
|
||||
* 优化txt本地校验效率 ([fd507f2](https://github.com/certd/certd/commit/fd507f269253607e68c5c099c99e0de11636f229))
|
||||
* 支持又拍云cdn ([fd0536b](https://github.com/certd/certd/commit/fd0536bd4b41f15b6b5d42e0b447f0dcbf73b8a8))
|
||||
* 支持又拍云cdn ([57389a7](https://github.com/certd/certd/commit/57389a79a1a61c45d081712562f8b33c9633158e))
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 增加服务器时间警告 ([d66ade4](https://github.com/certd/certd/commit/d66ade4e4783850b6c7625c6f164a5a0fc0aa509))
|
||||
* 支持部署到lucky ([e18e399](https://github.com/certd/certd/commit/e18e399ce6529e8c7e36b56c5f674cfdbbd3d3d1))
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复dns.la无法申请证书的bug ([90b045a](https://github.com/certd/certd/commit/90b045af6d1a4f46986e4b118885c1f050df067c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到主机支持scp方式 ([05b6159](https://github.com/certd/certd/commit/05b6159802b9e85b6a410361b60b5c28875b48e7))
|
||||
* 优化图标 ([c56f48c](https://github.com/certd/certd/commit/c56f48c1e3c54c4e203fafb380d9091d75681b7e))
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复通知选择器无法选择的bug ([f7b88f9](https://github.com/certd/certd/commit/f7b88f9e3b7d9d9122e4fd2003a20c555bd50c7d))
|
||||
* 修复证书流水线创建失败的bug ([736fe03](https://github.com/certd/certd/commit/736fe038ebda56648bcc4c12884a700341d2c049))
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复站点监控通知通过webhook发送失败的bug ([9be1ecc](https://github.com/certd/certd/commit/9be1ecc8aab3ea23dd0dc2dab3688f4edb90ef2c))
|
||||
* 修复dns.la域名申请失败的bug ([1de8eee](https://github.com/certd/certd/commit/1de8eee6ea8307f3c11626af75303d3cc104bb95))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔支持doker站点证书部署 ([589a373](https://github.com/certd/certd/commit/589a373142ef7f50d64d3aa767a90b1f4b64da93))
|
||||
* 保存调整后的列宽 ([873f2b6](https://github.com/certd/certd/commit/873f2b618b9d7320045baf69d6da83afe48a780f))
|
||||
* 创建证书流水线时,支持更多参数展开 ([36aa7f8](https://github.com/certd/certd/commit/36aa7f82b078a053a102331b3c6f132fb9d492f9))
|
||||
* 流水线页面可以鼠标按住左右拖动 ([d85a02f](https://github.com/certd/certd/commit/d85a02feeb3183c5abd6c1ea790d5923a32d7271))
|
||||
* 流水线增加上传证书快捷方式 ([425bba6](https://github.com/certd/certd/commit/425bba67c539b734e2a85a83a4f9ecc9b2434fb4))
|
||||
* 手动上传证书部署流水线 ([fbb66f3](https://github.com/certd/certd/commit/fbb66f3c4389489aa8a43b194d82bc8cf391607b))
|
||||
* 优化选择任务时手机版展示效果 ([d01004d](https://github.com/certd/certd/commit/d01004d53071a75ac91ee21cc96bde9369f77ff3))
|
||||
* 站点监控,手动测试也发通知 ([729b19c](https://github.com/certd/certd/commit/729b19c8da60d5efb5baef7cf8df0518e7f6b471))
|
||||
* 站点证书监控支持模糊查询 ([0069c0e](https://github.com/certd/certd/commit/0069c0e3992946a8dd6410f299d4fc974ef0e76b))
|
||||
* 支持飞书通知 ([b82e1dc](https://github.com/certd/certd/commit/b82e1dcd6217b09a7d7e21cd648bb31de320cadf))
|
||||
* 支持手动上传证书并部署 ([a9fffa5](https://github.com/certd/certd/commit/a9fffa5180c83da27b35886aa2e858a92a2c5f94))
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复阿里云fc获取不到列表的bug ([474b337](https://github.com/certd/certd/commit/474b3372d8ce98e6d45900bf8046bc0b3f220686))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 1panel支持 apikey方式授权 ([170b2af](https://github.com/certd/certd/commit/170b2afb0e3b125e4ed057f633fe895b5ac3ac22))
|
||||
* 套餐支持3天7天等选项 ([0d71a8e](https://github.com/certd/certd/commit/0d71a8ee501a0e5bb69decf07e8729026e9d85bf))
|
||||
* 证书仓库增加有效期显示 ([be87124](https://github.com/certd/certd/commit/be87124ada7a093f281ca29a45c86b4ea4644ead))
|
||||
* 支持部署到天翼云CDN ([82a72e0](https://github.com/certd/certd/commit/82a72e0b497efa043d342ad0e33c083a2de79a05))
|
||||
* 支持dns.la ([ee8af18](https://github.com/certd/certd/commit/ee8af18d0ac0af82544d6dda1e4b4c678b733041))
|
||||
* cf授权支持配置http代理 ([27386ea](https://github.com/certd/certd/commit/27386ea04d3c1a5aebe3cfdd7ac48185eaa76629))
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复cname记录查找bug ([95fb4e3](https://github.com/certd/certd/commit/95fb4e3e8be6ca13cc43b451f6141d62190ba453))
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 一些手机端适配优化 ([5b8d5dd](https://github.com/certd/certd/commit/5b8d5dd97536456a9d5d1384216eac1093b2dc3d))
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复CDN插件我爱云因更换接口导致部署失败的问题 ([5641c19](https://github.com/certd/certd/commit/5641c19502970f67af19709bddf8c781b1a25bdc))
|
||||
* 修复CDN插件我爱云因更换接口导致部署失败的问题 ([0110dfd](https://github.com/certd/certd/commit/0110dfdb70b12dfb0a7a067717f3773ed75aae7c))
|
||||
* 修复webhook headers value中带等号是解析错误的bug ([1fe3365](https://github.com/certd/certd/commit/1fe3365e10c464c4c60c82f424cf74fe35b883e0))
|
||||
* ProxmoxUploadCert 增加强制部署证书 ([441b15e](https://github.com/certd/certd/commit/441b15ed2fe5a143a5bd5508613b3816ddbff596))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 历史记录查看详情,可以切换到对应的历史记录日志上去 ([082802e](https://github.com/certd/certd/commit/082802e1197156837800f814728ee0f6b300b18c))
|
||||
* 流水线同一个阶段任务优化为并行执行 ([efa9c74](https://github.com/certd/certd/commit/efa9c748c5c07fc950af3db742ef9310f1ac9a4b))
|
||||
* 升级midwayjs版本 ([057b0b4](https://github.com/certd/certd/commit/057b0b4565e19bb93195633f767b2942e8e40e59))
|
||||
* 是否允许爬虫爬取增加ui设置选项 ([779db9d](https://github.com/certd/certd/commit/779db9da705d2dfef36fec21f52bd38af9fc5f2e))
|
||||
* 通知支持钉钉群聊机器人 ([fc8bef5](https://github.com/certd/certd/commit/fc8bef5aae522d75d408d8c3aa74543269da5398))
|
||||
* 易支付支持固定支付方式,适合没有收银台版本使用 ([81df96b](https://github.com/certd/certd/commit/81df96bf4542ce8d8ef4a428a4460dd554e4719a))
|
||||
* 支持易盾RCDN部署 ([065713c](https://github.com/certd/certd/commit/065713cdb6953d16df08585c316c1a7a8eaec437))
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 禁止爬虫爬取本网站 ([5164116](https://github.com/certd/certd/commit/5164116bde60dabac774cdf94f5317ff386e95ca))
|
||||
* 上传到阿里云证书名称后缀增加毫秒时间戳 ([9f0ee21](https://github.com/certd/certd/commit/9f0ee219d02907ffe128a5cf10173397d934ccd7))
|
||||
* 支持部署到阿里云FC3.0 ([bcaf54d](https://github.com/certd/certd/commit/bcaf54d4cb7bc469486aae6cdb127ae017eb3abb))
|
||||
* 支持新版本LeCDN ([44d43f4](https://github.com/certd/certd/commit/44d43f45cb9094619df7494c2a64a51ba77ad116))
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package root
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 适配最新版1panel密码编码方式 ([78044c0](https://github.com/certd/certd/commit/78044c062e20cdd04f08baef9fb6745bf25eddcf))
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复腾讯云CLB多域名同证书部署报错的bug ([c3a5542](https://github.com/certd/certd/commit/c3a55429357e78f4b78c9592d3e5897db2d4d549))
|
||||
* 修复新版本1panel密码需要加密,无法登录的问题 ([ada0b71](https://github.com/certd/certd/commit/ada0b7106e97e551783829e4e719f76793a7123d))
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
20
README.md
20
README.md
@@ -9,14 +9,13 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
|
||||
* 全自动申请证书(支持所有注册商注册的域名)
|
||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等,目前已支持40+部署插件)
|
||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等,目前已支持60+部署插件)
|
||||
* 支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||
* 邮件通知、webhook通知
|
||||
* 私有化部署,数据保存本地,授权信息加密存储,镜像由Github Actions构建,过程公开透明
|
||||
* 支持SQLite,PostgreSQL、MySQL数据库
|
||||
|
||||
|
||||
>
|
||||
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||
>
|
||||
@@ -200,14 +199,15 @@ https://afdian.com/a/greper
|
||||
|
||||
专业版特权对比
|
||||
|
||||
| 功能 | 基础版 | 专业版 |
|
||||
|------|-----------------|-------------------|
|
||||
| 免费证书申请 | 免费无限制 | 无限制 |
|
||||
| 域名数量 | 免费无限制 | 无限制 |
|
||||
| 证书流水线条数 | 免费无限制 | 无限制 |
|
||||
| 站点证书监控 | 1条 | 无限制 |
|
||||
| 自动部署插件 | 阿里云、腾讯云、七牛云、SSH | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 通知 | 邮件、webhook | server酱、企微、anpush等 |
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|--------------------|-----------------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 域名数量 | 无限制 | 无限制 |
|
||||
| 证书流水线条数 | 无限制 | 无限制 |
|
||||
| 站点证书监控 | 限制1条 | 无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、飞书、anpush、server酱等 |
|
||||
|
||||
|
||||
************************
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
23:39
|
||||
00:33
|
||||
|
||||
@@ -7,9 +7,10 @@ services:
|
||||
restart: unless-stopped # 自动重启
|
||||
volumes:
|
||||
# ↓↓↓↓↓ -------------------------------------------------------- 数据库以及证书存储路径,默认存在宿主机的/data/certd/目录下,【您需要定时备份此目录,以保障数据容灾】
|
||||
# 只要修改冒号前面的,冒号后面的/app/data不要动
|
||||
- /data/certd:/app/data
|
||||
ports: # 端口映射
|
||||
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号
|
||||
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号,第二个7001不要动
|
||||
- "7001:7001"
|
||||
# ↓↓↓↓ ---------------------------------------------------------- https端口,可以根据实际情况,是否暴露该端口
|
||||
- "7002:7002"
|
||||
@@ -26,6 +27,8 @@ services:
|
||||
# extra_hosts:
|
||||
# # ↓↓↓↓ -------------------------------------------------------- 这里可以配置自定义hosts,外网域名可以指向本地局域网ip地址
|
||||
# - "localdomain.com:192.168.1.3"
|
||||
# # ↓↓↓↓ ------------------------------------------------ 直接使用主机的网络,如果网络问题实在找不到原因,可以尝试打开此参数
|
||||
# network_mode: host
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
# ↓↓↓↓ -------------------------------------------------------------- 启用ipv6网络,还需要把下面networks的注释放开
|
||||
|
||||
@@ -5,6 +5,7 @@ import lightbox from "vitepress-plugin-lightbox";
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
title: "Certd",
|
||||
titleTemplate: "开源SSL证书管理工具,证书自动化申请部署,让你的网站证书永不过期",
|
||||
description: "Certd帮助文档,Certd是一款开源免费的全自动SSL证书管理工具;证书自动化申请部署流水线;自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔。",
|
||||
markdown: {
|
||||
config: (md) => {
|
||||
@@ -12,6 +13,9 @@ export default defineConfig({
|
||||
md.use(lightbox, {});
|
||||
}
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://certd.docmirror.cn'
|
||||
},
|
||||
head: [
|
||||
// [
|
||||
// 'meta',
|
||||
@@ -25,9 +29,9 @@ export default defineConfig({
|
||||
name: "keywords",
|
||||
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"}],
|
||||
// ["meta", {name: "baidu-site-verification",content: "codeva-MiWN8Y07Ua"}],
|
||||
["link", { rel: "icon", href: "/static/logo/logo.svg" }]
|
||||
],
|
||||
themeConfig: {
|
||||
@@ -78,15 +82,16 @@ export default defineConfig({
|
||||
]
|
||||
},
|
||||
{ text: "演示教程", link: "/guide/tutorial.md" },
|
||||
{ text: "版本升级", link: "/guide/install/upgrade.md" },
|
||||
{ text: "切换数据库", link: "/guide/install/database.md" }
|
||||
{ text: "版本升级", link: "/guide/install/upgrade.md" }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "特性",
|
||||
items: [
|
||||
{ text: "CNAME代理校验", link: "/guide/feature/cname/index.md" },
|
||||
{ text: "插件列表", link: "/guide/plugins.md" }
|
||||
{ text: "插件列表", link: "/guide/plugins.md" },
|
||||
{ text: "多数据库支持", link: "/guide/install/database.md" },
|
||||
{ text: "开放接口", link: "/guide/open/index.md" }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,6 +124,14 @@ export default defineConfig({
|
||||
]
|
||||
}
|
||||
],
|
||||
"/deploy/":[
|
||||
{
|
||||
text: "部署任务",
|
||||
items: [
|
||||
{ text: "部署到ESXi", link: "/deploy/ESXi/index.md" },
|
||||
]
|
||||
}
|
||||
],
|
||||
"/comm/": [
|
||||
{
|
||||
text: "商业版",
|
||||
|
||||
BIN
docs/deploy/ESXi/images/ssh.png
Normal file
BIN
docs/deploy/ESXi/images/ssh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
17
docs/deploy/ESXi/index.md
Normal file
17
docs/deploy/ESXi/index.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 部署证书到ESXi
|
||||
|
||||
使用`部署证书到主机插件`即可
|
||||
|
||||
|
||||
## 开启ssh
|
||||
登陆ESXi Web后台,点击 主机 -> 操作 -> 服务 -> 启用 Secure Shell(SSH)打开SSH
|
||||
|
||||
## 添加部署到主机任务
|
||||
|
||||

|
||||
|
||||
## 配置重启脚本
|
||||
```bash
|
||||
/etc/init.d/hostd restart
|
||||
/etc/init.d/vpxa restart
|
||||
```
|
||||
@@ -3,6 +3,183 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复ssh支持键盘事件登录 ([8145808](https://github.com/certd/certd/commit/8145808c4370364377b4ffe3ae88ff465b49f20b))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到京东云cdn ([6f17c70](https://github.com/certd/certd/commit/6f17c700b84965baa01b40fe2abaa0a91bcbaffd))
|
||||
* 支持京东云dns申请证书 ([04d79f9](https://github.com/certd/certd/commit/04d79f9117670be504960b018fd49ae3bf7c1c11))
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* tab增加图标显示 ([a03ae5a](https://github.com/certd/certd/commit/a03ae5a216a1df2c1d3da12ae18dcd0f089a92d3))
|
||||
* 升级lego版本到4.22.2 ([4e15556](https://github.com/certd/certd/commit/4e15556e5e8100719497edb1729570d5a29668e1))
|
||||
* 优化华为dns接口报错信息输出 ([bf30b7a](https://github.com/certd/certd/commit/bf30b7afaef623dd8126570344f1fcc2c06f1215))
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复华为云dns接口请求出错的bug ([caa15b4](https://github.com/certd/certd/commit/caa15b47355363cbb8847f415ff12363cd53eeda))
|
||||
* 修复某些情况下站点证书监控报undefined.includes的错误 ([0b6618f](https://github.com/certd/certd/commit/0b6618ff709322a0eeba78953c8c6e9d073d083a))
|
||||
* 修复网站证书监控https port设置无效的bug ([cc8da0c](https://github.com/certd/certd/commit/cc8da0cf130f0c469371b59ac5bd04567f4a4414))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 站点监控保存时异步检查 ([993bc74](https://github.com/certd/certd/commit/993bc7432fce2d954e9897ed85b54f22150bfc7e))
|
||||
* dns支持火山引擎 ([99ff879](https://github.com/certd/certd/commit/99ff879d93658c29ea493a4bde7e9e3f85996d64))
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复编辑通知勾选默认,导致出现多个默认通知的bug ([6cd7bdd](https://github.com/certd/certd/commit/6cd7bddc37da8b0d7b9860fd9a26ddfe84c869a7))
|
||||
* 修复网站监控无法设置端口的bug ([27a8a57](https://github.com/certd/certd/commit/27a8a57cf52b4bf83d628aa3049be1efaa74f29c))
|
||||
* 修复lego模式无法创建流水线的bug ([687bb8a](https://github.com/certd/certd/commit/687bb8a2376d0de7b72739a174e4a9560581f866))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化通知格式 ([c3c5006](https://github.com/certd/certd/commit/c3c5006daa39c20624cb58864f2b92b230a38a7a))
|
||||
* 优化scp上传 ([e51123a](https://github.com/certd/certd/commit/e51123a95131cc76d655937488caf08956a67020))
|
||||
* 优化txt本地校验效率 ([fd507f2](https://github.com/certd/certd/commit/fd507f269253607e68c5c099c99e0de11636f229))
|
||||
* 支持又拍云cdn ([fd0536b](https://github.com/certd/certd/commit/fd0536bd4b41f15b6b5d42e0b447f0dcbf73b8a8))
|
||||
* 支持又拍云cdn ([57389a7](https://github.com/certd/certd/commit/57389a79a1a61c45d081712562f8b33c9633158e))
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 增加服务器时间警告 ([d66ade4](https://github.com/certd/certd/commit/d66ade4e4783850b6c7625c6f164a5a0fc0aa509))
|
||||
* 支持部署到lucky ([e18e399](https://github.com/certd/certd/commit/e18e399ce6529e8c7e36b56c5f674cfdbbd3d3d1))
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复dns.la无法申请证书的bug ([90b045a](https://github.com/certd/certd/commit/90b045af6d1a4f46986e4b118885c1f050df067c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到主机支持scp方式 ([05b6159](https://github.com/certd/certd/commit/05b6159802b9e85b6a410361b60b5c28875b48e7))
|
||||
* 优化图标 ([c56f48c](https://github.com/certd/certd/commit/c56f48c1e3c54c4e203fafb380d9091d75681b7e))
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复通知选择器无法选择的bug ([f7b88f9](https://github.com/certd/certd/commit/f7b88f9e3b7d9d9122e4fd2003a20c555bd50c7d))
|
||||
* 修复证书流水线创建失败的bug ([736fe03](https://github.com/certd/certd/commit/736fe038ebda56648bcc4c12884a700341d2c049))
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复站点监控通知通过webhook发送失败的bug ([9be1ecc](https://github.com/certd/certd/commit/9be1ecc8aab3ea23dd0dc2dab3688f4edb90ef2c))
|
||||
* 修复dns.la域名申请失败的bug ([1de8eee](https://github.com/certd/certd/commit/1de8eee6ea8307f3c11626af75303d3cc104bb95))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔支持doker站点证书部署 ([589a373](https://github.com/certd/certd/commit/589a373142ef7f50d64d3aa767a90b1f4b64da93))
|
||||
* 保存调整后的列宽 ([873f2b6](https://github.com/certd/certd/commit/873f2b618b9d7320045baf69d6da83afe48a780f))
|
||||
* 创建证书流水线时,支持更多参数展开 ([36aa7f8](https://github.com/certd/certd/commit/36aa7f82b078a053a102331b3c6f132fb9d492f9))
|
||||
* 流水线页面可以鼠标按住左右拖动 ([d85a02f](https://github.com/certd/certd/commit/d85a02feeb3183c5abd6c1ea790d5923a32d7271))
|
||||
* 流水线增加上传证书快捷方式 ([425bba6](https://github.com/certd/certd/commit/425bba67c539b734e2a85a83a4f9ecc9b2434fb4))
|
||||
* 手动上传证书部署流水线 ([fbb66f3](https://github.com/certd/certd/commit/fbb66f3c4389489aa8a43b194d82bc8cf391607b))
|
||||
* 优化选择任务时手机版展示效果 ([d01004d](https://github.com/certd/certd/commit/d01004d53071a75ac91ee21cc96bde9369f77ff3))
|
||||
* 站点监控,手动测试也发通知 ([729b19c](https://github.com/certd/certd/commit/729b19c8da60d5efb5baef7cf8df0518e7f6b471))
|
||||
* 站点证书监控支持模糊查询 ([0069c0e](https://github.com/certd/certd/commit/0069c0e3992946a8dd6410f299d4fc974ef0e76b))
|
||||
* 支持飞书通知 ([b82e1dc](https://github.com/certd/certd/commit/b82e1dcd6217b09a7d7e21cd648bb31de320cadf))
|
||||
* 支持手动上传证书并部署 ([a9fffa5](https://github.com/certd/certd/commit/a9fffa5180c83da27b35886aa2e858a92a2c5f94))
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复阿里云fc获取不到列表的bug ([474b337](https://github.com/certd/certd/commit/474b3372d8ce98e6d45900bf8046bc0b3f220686))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 1panel支持 apikey方式授权 ([170b2af](https://github.com/certd/certd/commit/170b2afb0e3b125e4ed057f633fe895b5ac3ac22))
|
||||
* 套餐支持3天7天等选项 ([0d71a8e](https://github.com/certd/certd/commit/0d71a8ee501a0e5bb69decf07e8729026e9d85bf))
|
||||
* 证书仓库增加有效期显示 ([be87124](https://github.com/certd/certd/commit/be87124ada7a093f281ca29a45c86b4ea4644ead))
|
||||
* 支持部署到天翼云CDN ([82a72e0](https://github.com/certd/certd/commit/82a72e0b497efa043d342ad0e33c083a2de79a05))
|
||||
* 支持dns.la ([ee8af18](https://github.com/certd/certd/commit/ee8af18d0ac0af82544d6dda1e4b4c678b733041))
|
||||
* cf授权支持配置http代理 ([27386ea](https://github.com/certd/certd/commit/27386ea04d3c1a5aebe3cfdd7ac48185eaa76629))
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复cname记录查找bug ([95fb4e3](https://github.com/certd/certd/commit/95fb4e3e8be6ca13cc43b451f6141d62190ba453))
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 一些手机端适配优化 ([5b8d5dd](https://github.com/certd/certd/commit/5b8d5dd97536456a9d5d1384216eac1093b2dc3d))
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复CDN插件我爱云因更换接口导致部署失败的问题 ([5641c19](https://github.com/certd/certd/commit/5641c19502970f67af19709bddf8c781b1a25bdc))
|
||||
* 修复CDN插件我爱云因更换接口导致部署失败的问题 ([0110dfd](https://github.com/certd/certd/commit/0110dfdb70b12dfb0a7a067717f3773ed75aae7c))
|
||||
* 修复webhook headers value中带等号是解析错误的bug ([1fe3365](https://github.com/certd/certd/commit/1fe3365e10c464c4c60c82f424cf74fe35b883e0))
|
||||
* ProxmoxUploadCert 增加强制部署证书 ([441b15e](https://github.com/certd/certd/commit/441b15ed2fe5a143a5bd5508613b3816ddbff596))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 历史记录查看详情,可以切换到对应的历史记录日志上去 ([082802e](https://github.com/certd/certd/commit/082802e1197156837800f814728ee0f6b300b18c))
|
||||
* 流水线同一个阶段任务优化为并行执行 ([efa9c74](https://github.com/certd/certd/commit/efa9c748c5c07fc950af3db742ef9310f1ac9a4b))
|
||||
* 升级midwayjs版本 ([057b0b4](https://github.com/certd/certd/commit/057b0b4565e19bb93195633f767b2942e8e40e59))
|
||||
* 是否允许爬虫爬取增加ui设置选项 ([779db9d](https://github.com/certd/certd/commit/779db9da705d2dfef36fec21f52bd38af9fc5f2e))
|
||||
* 通知支持钉钉群聊机器人 ([fc8bef5](https://github.com/certd/certd/commit/fc8bef5aae522d75d408d8c3aa74543269da5398))
|
||||
* 易支付支持固定支付方式,适合没有收银台版本使用 ([81df96b](https://github.com/certd/certd/commit/81df96bf4542ce8d8ef4a428a4460dd554e4719a))
|
||||
* 支持易盾RCDN部署 ([065713c](https://github.com/certd/certd/commit/065713cdb6953d16df08585c316c1a7a8eaec437))
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 禁止爬虫爬取本网站 ([5164116](https://github.com/certd/certd/commit/5164116bde60dabac774cdf94f5317ff386e95ca))
|
||||
* 上传到阿里云证书名称后缀增加毫秒时间戳 ([9f0ee21](https://github.com/certd/certd/commit/9f0ee219d02907ffe128a5cf10173397d934ccd7))
|
||||
* 支持部署到阿里云FC3.0 ([bcaf54d](https://github.com/certd/certd/commit/bcaf54d4cb7bc469486aae6cdb127ae017eb3abb))
|
||||
* 支持新版本LeCDN ([44d43f4](https://github.com/certd/certd/commit/44d43f45cb9094619df7494c2a64a51ba77ad116))
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package root
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 适配最新版1panel密码编码方式 ([78044c0](https://github.com/certd/certd/commit/78044c062e20cdd04f08baef9fb6745bf25eddcf))
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复腾讯云CLB多域名同证书部署报错的bug ([c3a5542](https://github.com/certd/certd/commit/c3a55429357e78f4b78c9592d3e5897db2d4d549))
|
||||
* 修复新版本1panel密码需要加密,无法登录的问题 ([ada0b71](https://github.com/certd/certd/commit/ada0b7106e97e551783829e4e719f76793a7123d))
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 当前置任务被删除时进行校验 ([c89686a](https://github.com/certd/certd/commit/c89686a2fda251484930f0ae715417b618c21690))
|
||||
* 修复cloudflare删除解析记录报错的bug ([00c2da4](https://github.com/certd/certd/commit/00c2da444f84adb89f3f1226d03294d7c6e3e4f1))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传自定义证书 ([75a38d9](https://github.com/certd/certd/commit/75a38d95f305b4271d9106babe7cffc1c89ae8f3))
|
||||
|
||||
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -28,7 +28,7 @@ packages:
|
||||
### 安装依赖和初始化:
|
||||
```shell
|
||||
# 安装pnpm,如果提示npm命令不存在,就需要先安装nodejs
|
||||
npm install -g pnpm@8.15.7 --registry=https://registry.npmmirror.com
|
||||
npm install -g pnpm--registry=https://registry.npmmirror.com
|
||||
|
||||
# 使用国内镜像源,如果有代理,就不需要
|
||||
pnpm config set registry https://registry.npmmirror.com
|
||||
@@ -36,19 +36,19 @@ pnpm config set registry https://registry.npmmirror.com
|
||||
pnpm install
|
||||
|
||||
# 初始化构建
|
||||
npm run init
|
||||
pnpm init
|
||||
```
|
||||
|
||||
### 启动 server:
|
||||
```shell
|
||||
cd packages/ui/certd-server
|
||||
npm run dev
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### 启动 client:
|
||||
```shell
|
||||
cd packages/ui/certd-client
|
||||
npm run dev
|
||||
pnpm dev
|
||||
|
||||
# 会自动打开浏览器,确认正常运行
|
||||
|
||||
|
||||
BIN
docs/guide/donate/images/plus.png
Normal file
BIN
docs/guide/donate/images/plus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
@@ -7,16 +7,22 @@ https://afdian.com/a/greper
|
||||
1. 可加入发电专属群,可以获得作者一对一技术支持
|
||||
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
||||
3. 一年期专业版激活码
|
||||
4. 赠送国外免费服务器部署方案(0成本使用Certd,可能需要翻墙,不过现在性能越来越差了)
|
||||
|
||||
|
||||
## 专业版特权对比
|
||||
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|------------------------|-----------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 发邮件功能 | 需要配置 | 免配置 |
|
||||
| 证书流水线条数 | 10条 | 无限制 |
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|------------------------|-----------------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 证书流水线条数 | 无限制 | 无限制 |
|
||||
| 站点证书监控 | 限制1条 | 无限制 |
|
||||
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、飞书、anpush、server酱等 |
|
||||
|
||||
|
||||
## 专业版激活方式
|
||||
|
||||

|
||||
|
||||
发电后,在私信中获取激活码
|
||||
************************
|
||||
|
||||
@@ -10,7 +10,7 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
|
||||
* 全自动申请证书(支持所有注册商注册的域名)
|
||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持60+部署插件)
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||
* 邮件通知
|
||||
* 私有化部署,保障数据安全
|
||||
|
||||
@@ -20,7 +20,7 @@ https://1panel.cn/docs/installation/online_installation/
|
||||

|
||||
|
||||
> 默认使用sqlite数据库,数据保存在`/data/certd`目录下,您可以手动备份该目录
|
||||
> certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
|
||||
> certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||
|
||||
3. 访问测试
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
点击确定,等待启动完成
|
||||

|
||||
|
||||
> certd默认使用sqlite数据库,另外支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
|
||||
> certd默认使用sqlite数据库,另外支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||
|
||||
|
||||
## 二、访问应用
|
||||
|
||||
@@ -42,7 +42,7 @@ docker compose up -d
|
||||
> 如果提示 没有docker compose命令,请安装docker-compose
|
||||
> https://docs.docker.com/compose/install/linux/
|
||||
|
||||
> certd默认使用sqlite数据库,另外还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../../database/)
|
||||
> certd默认使用sqlite数据库,另外还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||
|
||||
|
||||
### 3. 访问测试
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 源码部署
|
||||
不推荐
|
||||
如果没有`git`和`nodejs`基础,则不推荐
|
||||
## 一、源码安装
|
||||
|
||||
### 环境要求
|
||||
@@ -7,7 +7,7 @@
|
||||
### 源码启动
|
||||
```shell
|
||||
# 克隆代码
|
||||
git clone https://github.com/certd/certd
|
||||
git clone https://github.com/certd/certd --depth=1
|
||||
# git checkout v1.x.x # 当v2主干分支代码无法正常启动时,可以尝试此命令,1.x.x换成最新版本号
|
||||
cd certd
|
||||
# 启动服务
|
||||
|
||||
BIN
docs/guide/open/images/1.png
Normal file
BIN
docs/guide/open/images/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
21
docs/guide/open/index.md
Normal file
21
docs/guide/open/index.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 开放接口
|
||||
被动方式对第三方提供证书, 支持根据域名或证书id获取证书。
|
||||
|
||||
## 获取keyId和KeySecret
|
||||
|
||||

|
||||
|
||||
## 接口文档
|
||||
|
||||
https://apifox.com/apidoc/shared-2e76f8c4-7c58-413b-a32d-a1316529af44/254949529e0
|
||||
|
||||
## Token生成方法
|
||||
|
||||
header中传入x-certd-token即可调用开放接口
|
||||
1、首先从OpenKey页面生成keyId,keySecret;
|
||||
2、准备一个content( json字符串): content={"keyId":keyId, t:时间戳秒数, encrypt:false, signType:"md5"} `// encrypt返回结果是否加密`
|
||||
3、将content加上keySecret进行签名: sign = md5(content + keySecret)
|
||||
4、然后将content和sign分别base64后用.号连接: x-certd-token = base64(content) +"."+base64(sign)
|
||||
|
||||
## SDK
|
||||
待开发
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
## 2. 使用示例
|
||||
```js
|
||||
|
||||
// 如果需要引用第三方库,必须使用import语法
|
||||
// const thirdSdk = await import("third-sdk-name")
|
||||
|
||||
const certPem = ctx.self.cert.crt
|
||||
const certKey = ctx.self.cert.key
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 51 KiB |
@@ -24,7 +24,7 @@ features:
|
||||
- title: 全自动申请证书
|
||||
details: 支持所有注册商注册的域名
|
||||
- title: 全自动部署证书
|
||||
details: 支持部署到主机、阿里云、腾讯云等,目前已支持30+部署插件
|
||||
details: 支持部署到主机、阿里云、腾讯云等,目前已支持60+部署插件
|
||||
- title: 多域名、泛域名打到一个证书上
|
||||
details: 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||
- title: 多证书格式支持
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.30.2"
|
||||
"version": "1.32.0"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"@lerna-lite/run": "^3.9.3",
|
||||
"@lerna-lite/version": "^3.9.3",
|
||||
"medium-zoom": "^1.1.0",
|
||||
"vitepress": "^1.4.1",
|
||||
"vitepress": "^2.0.0-alpha.4",
|
||||
"vitepress-plugin-lightbox": "^1.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -41,5 +41,8 @@
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/**"
|
||||
]
|
||||
],
|
||||
"pnpm": {
|
||||
"neverBuiltDependencies": []
|
||||
}
|
||||
}
|
||||
|
||||
7
packages/core/acme-client/.prettierrc
Normal file
7
packages/core/acme-client/.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -3,6 +3,88 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/publishlab/node-acme-client/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复从本地dns获取记录报错的bug ([c39b1bf](https://github.com/publishlab/node-acme-client/commit/c39b1bf823ddc6216bed2049e4c87e6107def08a))
|
||||
|
||||
### Features
|
||||
|
||||
* 优化证书申请速度,修复某些情况下letsencrypt 校验失败的问题 ([857589b](https://github.com/publishlab/node-acme-client/commit/857589b365c6f709e0ae67914d2f50ce182e6dd6))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化华为dns解析记录创建和删除问题 ([0948c5b](https://github.com/publishlab/node-acme-client/commit/0948c5bc691d2ee6eb47c72a85da1b7453361878))
|
||||
|
||||
## [1.31.11](https://github.com/publishlab/node-acme-client/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.10](https://github.com/publishlab/node-acme-client/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.9](https://github.com/publishlab/node-acme-client/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* dns支持火山引擎 ([99ff879](https://github.com/publishlab/node-acme-client/commit/99ff879d93658c29ea493a4bde7e9e3f85996d64))
|
||||
|
||||
## [1.31.8](https://github.com/publishlab/node-acme-client/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化txt本地校验效率 ([fd507f2](https://github.com/publishlab/node-acme-client/commit/fd507f269253607e68c5c099c99e0de11636f229))
|
||||
|
||||
## [1.31.7](https://github.com/publishlab/node-acme-client/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.6](https://github.com/publishlab/node-acme-client/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.5](https://github.com/publishlab/node-acme-client/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.4](https://github.com/publishlab/node-acme-client/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.3](https://github.com/publishlab/node-acme-client/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.2](https://github.com/publishlab/node-acme-client/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.31.1](https://github.com/publishlab/node-acme-client/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
# [1.31.0](https://github.com/publishlab/node-acme-client/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.30.6](https://github.com/publishlab/node-acme-client/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.30.5](https://github.com/publishlab/node-acme-client/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.30.4](https://github.com/publishlab/node-acme-client/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.30.3](https://github.com/publishlab/node-acme-client/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.30.2](https://github.com/publishlab/node-acme-client/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
**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.30.2",
|
||||
"version": "1.32.0",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.30.2",
|
||||
"@certd/basic": "^1.32.0",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
@@ -30,6 +30,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.10",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"chai": "^4.4.1",
|
||||
"chai-as-promised": "^7.1.2",
|
||||
"eslint": "^8.57.0",
|
||||
@@ -65,5 +67,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "089825d3602440188392f7018d0eb9038617c1d6"
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* ACME auto helper
|
||||
*/
|
||||
import { readCsrDomains } from './crypto/index.js';
|
||||
import { log } from './logger.js';
|
||||
import { wait } from './wait.js';
|
||||
import { CancelError } from './error.js';
|
||||
import { readCsrDomains } from "./crypto/index.js";
|
||||
import { log } from "./logger.js";
|
||||
import { wait } from "./wait.js";
|
||||
import { CancelError } from "./error.js";
|
||||
|
||||
|
||||
const defaultOpts = {
|
||||
@@ -13,13 +13,13 @@ const defaultOpts = {
|
||||
preferredChain: null,
|
||||
termsOfServiceAgreed: false,
|
||||
skipChallengeVerification: false,
|
||||
challengePriority: ['http-01', 'dns-01'],
|
||||
challengePriority: ["http-01", "dns-01"],
|
||||
challengeCreateFn: async () => {
|
||||
throw new Error('Missing challengeCreateFn()');
|
||||
throw new Error("Missing challengeCreateFn()");
|
||||
},
|
||||
challengeRemoveFn: async () => {
|
||||
throw new Error('Missing challengeRemoveFn()');
|
||||
},
|
||||
throw new Error("Missing challengeRemoveFn()");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ const defaultOpts = {
|
||||
* @returns {Promise<buffer>} Certificate
|
||||
*/
|
||||
|
||||
export default async (client, userOpts) => {
|
||||
export default async (client, userOpts) => {
|
||||
const opts = { ...defaultOpts, ...userOpts };
|
||||
const accountPayload = { termsOfServiceAgreed: opts.termsOfServiceAgreed };
|
||||
|
||||
@@ -49,14 +49,13 @@ export default async (client, userOpts) => {
|
||||
* Register account
|
||||
*/
|
||||
|
||||
log('[auto] Checking account');
|
||||
log("[auto] Checking account");
|
||||
|
||||
try {
|
||||
client.getAccountUrl();
|
||||
log('[auto] Account URL already exists, skipping account registration');
|
||||
}
|
||||
catch (e) {
|
||||
log('[auto] Registering account');
|
||||
log("[auto] Account URL already exists, skipping account registration( 证书申请账户已存在,跳过注册 )");
|
||||
} catch (e) {
|
||||
log("[auto] Registering account (注册证书申请账户)");
|
||||
await client.createAccount(accountPayload);
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ export default async (client, userOpts) => {
|
||||
* Parse domains from CSR
|
||||
*/
|
||||
|
||||
log('[auto] Parsing domains from Certificate Signing Request');
|
||||
log("[auto] Parsing domains from Certificate Signing Request ");
|
||||
const { commonName, altNames } = readCsrDomains(opts.csr);
|
||||
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
|
||||
|
||||
@@ -74,8 +73,8 @@ export default async (client, userOpts) => {
|
||||
* Place order
|
||||
*/
|
||||
|
||||
log('[auto] Placing new certificate order with ACME provider');
|
||||
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: 'dns', value: d })) };
|
||||
log("[auto] Placing new certificate order with ACME provider");
|
||||
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
|
||||
const order = await client.createOrder(orderPayload);
|
||||
const authorizations = await client.getAuthorizations(order);
|
||||
|
||||
@@ -85,82 +84,81 @@ export default async (client, userOpts) => {
|
||||
* Resolve and satisfy challenges
|
||||
*/
|
||||
|
||||
log('[auto] Resolving and satisfying authorization challenges');
|
||||
log("[auto] Resolving and satisfying authorization challenges");
|
||||
|
||||
const clearTasks = [];
|
||||
const localVerifyTasks = [];
|
||||
const completeChallengeTasks = [];
|
||||
|
||||
const challengeFunc = async (authz) => {
|
||||
const d = authz.identifier.value;
|
||||
let challengeCompleted = false;
|
||||
|
||||
/* Skip authz that already has valid status */
|
||||
if (authz.status === 'valid') {
|
||||
if (authz.status === "valid") {
|
||||
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
||||
return;
|
||||
}
|
||||
|
||||
const keyAuthorizationGetter = async (challenge) => {
|
||||
return await client.getChallengeKeyAuthorization(challenge);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
log(`[auto] [${d}] Trigger challengeCreateFn()`);
|
||||
async function deactivateAuth(e) {
|
||||
log(`[auto] [${d}] Unable to complete challenge: ${e.message}`);
|
||||
try {
|
||||
const { recordReq, recordRes, dnsProvider,challenge ,keyAuthorization} = await opts.challengeCreateFn(authz, keyAuthorizationGetter);
|
||||
clearTasks.push(async () => {
|
||||
/* Trigger challengeRemoveFn(), suppress errors */
|
||||
log(`[auto] [${d}] Trigger challengeRemoveFn()`);
|
||||
try {
|
||||
await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider);
|
||||
}
|
||||
catch (e) {
|
||||
log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
|
||||
}
|
||||
});
|
||||
// throw new Error('测试异常');
|
||||
/* Challenge verification */
|
||||
if (opts.skipChallengeVerification === true) {
|
||||
log(`[auto] [${d}] Skipping challenge verification since skipChallengeVerification=true,wait 60s`);
|
||||
await wait(60 * 1000);
|
||||
}
|
||||
else {
|
||||
log(`[auto] [${d}] Running challenge verification, type = ${challenge.type}`);
|
||||
try {
|
||||
await client.verifyChallenge(authz, challenge);
|
||||
}
|
||||
catch (e) {
|
||||
log(`[auto] [${d}] challenge verification threw error: ${e.message}`);
|
||||
}
|
||||
}
|
||||
/* Complete challenge and wait for valid status */
|
||||
log(`[auto] [${d}] Completing challenge with ACME provider and waiting for valid status`);
|
||||
await client.completeChallenge(challenge);
|
||||
challengeCompleted = true;
|
||||
|
||||
await client.waitForValidStatus(challenge);
|
||||
}
|
||||
catch (e) {
|
||||
log(`[auto] [${d}] challengeCreateFn threw error: ${e.message}`);
|
||||
throw e;
|
||||
log(`[auto] [${d}] Deactivating failed authorization`);
|
||||
await client.deactivateAuthorization(authz);
|
||||
} catch (f) {
|
||||
/* Suppress deactivateAuthorization() errors */
|
||||
log(`[auto] [${d}] Authorization deactivation threw error: ${f.message}`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
/* Deactivate pending authz when unable to complete challenge */
|
||||
if (!challengeCompleted) {
|
||||
log(`[auto] [${d}] Unable to complete challenge: ${e.message}`);
|
||||
|
||||
log(`[auto] [${d}] Trigger challengeCreateFn()`);
|
||||
try {
|
||||
const { recordReq, recordRes, dnsProvider, challenge, keyAuthorization } = await opts.challengeCreateFn(authz, keyAuthorizationGetter);
|
||||
clearTasks.push(async () => {
|
||||
/* Trigger challengeRemoveFn(), suppress errors */
|
||||
log(`[auto] [${d}] Trigger challengeRemoveFn()`);
|
||||
try {
|
||||
log(`[auto] [${d}] Deactivating failed authorization`);
|
||||
await client.deactivateAuthorization(authz);
|
||||
await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider);
|
||||
} catch (e) {
|
||||
log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
|
||||
}
|
||||
catch (f) {
|
||||
/* Suppress deactivateAuthorization() errors */
|
||||
log(`[auto] [${d}] Authorization deactivation threw error: ${f.message}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
localVerifyTasks.push(async () => {
|
||||
/* Challenge verification */
|
||||
log(`[auto] [${d}] 开始本地验证, type = ${challenge.type}`);
|
||||
try {
|
||||
await client.verifyChallenge(authz, challenge);
|
||||
} catch (e) {
|
||||
log(`[auto] [${d}] 本地验证失败,尝试请求ACME提供商获取状态: ${e.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
completeChallengeTasks.push(async () => {
|
||||
/* Complete challenge and wait for valid status */
|
||||
log(`[auto] [${d}] 请求ACME提供商完成验证`);
|
||||
try{
|
||||
await client.completeChallenge(challenge);
|
||||
}catch (e) {
|
||||
await deactivateAuth(e);
|
||||
throw e;
|
||||
}
|
||||
challengeCompleted = true;
|
||||
log(`[auto] [${d}] 等待返回valid状态`);
|
||||
await client.waitForValidStatus(challenge,d);
|
||||
});
|
||||
|
||||
|
||||
} catch (e) {
|
||||
log(`[auto] [${d}] challengeCreateFn threw error: ${e.message}`);
|
||||
await deactivateAuth(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
};
|
||||
const domainSets = [];
|
||||
|
||||
@@ -168,7 +166,7 @@ export default async (client, userOpts) => {
|
||||
const d = authz.identifier.value;
|
||||
log(`authorization:domain = ${d}, value = ${JSON.stringify(authz)}`);
|
||||
|
||||
if (authz.status === 'valid') {
|
||||
if (authz.status === "valid") {
|
||||
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
||||
return;
|
||||
}
|
||||
@@ -192,8 +190,9 @@ export default async (client, userOpts) => {
|
||||
|
||||
const allChallengePromises = [];
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const challengePromises = [];
|
||||
allChallengePromises.push(challengePromises);
|
||||
for (const domainSet of domainSets) {
|
||||
const challengePromises = [];
|
||||
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
||||
for (const domain in domainSet) {
|
||||
const authz = domainSet[domain];
|
||||
@@ -202,12 +201,11 @@ export default async (client, userOpts) => {
|
||||
await challengeFunc(authz);
|
||||
});
|
||||
}
|
||||
allChallengePromises.push(challengePromises);
|
||||
}
|
||||
|
||||
log(`[auto] challengeGroups:${allChallengePromises.length}`);
|
||||
|
||||
function runAllPromise(tasks) {
|
||||
async function runAllPromise(tasks) {
|
||||
let promise = Promise.resolve();
|
||||
tasks.forEach((task) => {
|
||||
promise = promise.then(task);
|
||||
@@ -215,73 +213,60 @@ export default async (client, userOpts) => {
|
||||
return promise;
|
||||
}
|
||||
|
||||
async function runPromisePa(tasks) {
|
||||
async function runPromisePa(tasks, waitTime = 5000) {
|
||||
const results = [];
|
||||
// eslint-disable-next-line no-await-in-loop,no-restricted-syntax
|
||||
for (const task of tasks) {
|
||||
results.push(task());
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await wait(10000);
|
||||
await wait(waitTime);
|
||||
}
|
||||
return Promise.all(results);
|
||||
}
|
||||
|
||||
try {
|
||||
log(`开始challenge,共${allChallengePromises.length}组`);
|
||||
let i = 0;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const challengePromises of allChallengePromises) {
|
||||
i += 1;
|
||||
log(`开始第${i}组`);
|
||||
if (opts.signal && opts.signal.aborted) {
|
||||
throw new CancelError('用户取消');
|
||||
log(`开始challenge,共${allChallengePromises.length}组`);
|
||||
let i = 0;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const challengePromises of allChallengePromises) {
|
||||
i += 1;
|
||||
log(`开始第${i}组`);
|
||||
if (opts.signal && opts.signal.aborted) {
|
||||
throw new CancelError("用户取消");
|
||||
}
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runPromisePa(challengePromises);
|
||||
if (opts.skipChallengeVerification === true) {
|
||||
log(`跳过本地验证(skipChallengeVerification=true),等待 60s`);
|
||||
await wait(60 * 1000);
|
||||
} else {
|
||||
await runPromisePa(localVerifyTasks, 1000);
|
||||
log("本地校验完成,等待30s")
|
||||
await wait(30 * 1000)
|
||||
}
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runPromisePa(challengePromises);
|
||||
}
|
||||
catch (e) {
|
||||
log(`证书申请失败${e.message}`);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if (client.opts.sslProvider !== 'google') {
|
||||
// letsencrypt 如果同时检出两个TXT记录,会以第一个为准,就会校验失败,所以需要提前删除
|
||||
// zerossl 此方式测试无问题
|
||||
log(`清理challenge痕迹,length:${clearTasks.length}`);
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runAllPromise(clearTasks);
|
||||
}
|
||||
catch (e) {
|
||||
log('清理challenge失败');
|
||||
log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (client.opts.sslProvider === 'google') {
|
||||
// google 相同的域名txt记录是一样的,不能提前删除,否则校验失败,报错如下
|
||||
// Error: The TXT record retrieved from _acme-challenge.bbc.handsfree.work.
|
||||
// at the time the challenge was validated did not contain JshHVu7dt_DT6uYILWhokHefFVad2Q6Mw1L-fNZFcq8
|
||||
// (the base64url-encoded SHA-256 digest of RlJZNBR0LWnxNK_xd2zqtYVvCiNJOKJ3J1NmCjU_9BjaUJgL3k-qSpIhQ-uF4FBS.NRyqT8fRiq6THzzrvkgzgR5Xai2LsA2SyGLAq_wT3qc).
|
||||
// See https://tools.ietf.org/html/rfc8555#section-8.4 for more information.
|
||||
log("开始向提供商请求挑战验证");
|
||||
await runPromisePa(completeChallengeTasks, 1000);
|
||||
} catch (e) {
|
||||
log(`证书申请失败${e.message}`);
|
||||
throw e;
|
||||
} finally {
|
||||
// letsencrypt 如果同时检出两个TXT记录,会以第一个为准,就会校验失败,所以需要提前删除
|
||||
// zerossl 此方式测试无问题
|
||||
log(`清理challenge痕迹,length:${clearTasks.length}`);
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runAllPromise(clearTasks);
|
||||
}
|
||||
catch (e) {
|
||||
log('清理challenge失败');
|
||||
} catch (e) {
|
||||
log("清理challenge失败");
|
||||
log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log('challenge结束');
|
||||
|
||||
log("challenge结束");
|
||||
|
||||
// log('[auto] Waiting for challenge valid status');
|
||||
// await Promise.all(challengePromises);
|
||||
@@ -289,7 +274,7 @@ export default async (client, userOpts) => {
|
||||
* Finalize order and download certificate
|
||||
*/
|
||||
|
||||
log('[auto] Finalizing order and downloading certificate');
|
||||
log("[auto] Finalizing order and downloading certificate");
|
||||
const finalized = await client.finalizeOrder(order, opts.csr);
|
||||
const res = await client.getCertificate(finalized, opts.preferredChain);
|
||||
return res;
|
||||
|
||||
@@ -500,7 +500,7 @@ class AcmeClient {
|
||||
await verify[challenge.type](authz, challenge, keyAuthorization);
|
||||
};
|
||||
|
||||
log('Waiting for ACME challenge verification', this.backoffOpts);
|
||||
log('Waiting for ACME challenge verification(等待ACME挑战验证)', this.backoffOpts);
|
||||
return util.retry(verifyFn, this.backoffOpts);
|
||||
}
|
||||
|
||||
@@ -554,9 +554,9 @@ class AcmeClient {
|
||||
* ```
|
||||
*/
|
||||
|
||||
async waitForValidStatus(item) {
|
||||
async waitForValidStatus(item,d) {
|
||||
if (!item.url) {
|
||||
throw new Error('Unable to verify status of item, URL not found');
|
||||
throw new Error(`[${d}] Unable to verify status of item, URL not found`);
|
||||
}
|
||||
|
||||
const verifyFn = async (abort) => {
|
||||
@@ -568,23 +568,23 @@ class AcmeClient {
|
||||
const resp = await this.api.apiRequest(item.url, null, [200]);
|
||||
|
||||
/* Verify status */
|
||||
log(`Item has status: ${resp.data.status}`);
|
||||
log(`[${d}] Item has status(挑战状态): ${resp.data.status}`);
|
||||
|
||||
if (invalidStates.includes(resp.data.status)) {
|
||||
abort();
|
||||
throw new Error(util.formatResponseError(resp));
|
||||
}
|
||||
else if (pendingStates.includes(resp.data.status)) {
|
||||
throw new Error('Operation is pending or processing');
|
||||
throw new Error(`[${d}] Operation is pending or processing(当前仍然在等待状态)`);
|
||||
}
|
||||
else if (validStates.includes(resp.data.status)) {
|
||||
return resp.data;
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected item status: ${resp.data.status}`);
|
||||
throw new Error(`[${d}] Unexpected item status: ${resp.data.status}`);
|
||||
};
|
||||
|
||||
log(`Waiting for valid status from: ${item.url}`, this.backoffOpts);
|
||||
log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, this.backoffOpts);
|
||||
return util.retry(verifyFn, this.backoffOpts);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +60,9 @@ async function retryPromise(fn, attempts, backoff) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
log(`Promise rejected: ${e.message}`);
|
||||
const duration = backoff.duration();
|
||||
log(`Promise rejected attempt #${backoff.attempts}, retrying in ${duration}ms: ${e.message}`);
|
||||
log(`Promise rejected attempt #${backoff.attempts}, ${duration}ms 后重试: ${e.message}`);
|
||||
|
||||
await new Promise((resolve) => { setTimeout(resolve, duration); });
|
||||
return retryPromise(fn, attempts, backoff);
|
||||
@@ -218,15 +219,15 @@ function formatResponseError(resp) {
|
||||
async function resolveDomainBySoaRecord(recordName) {
|
||||
try {
|
||||
await dns.resolveSoa(recordName);
|
||||
log(`Found SOA record, considering domain to be: ${recordName}`);
|
||||
log(`找到${recordName}的SOA记录`);
|
||||
return recordName;
|
||||
}
|
||||
catch (e) {
|
||||
log(`Unable to locate SOA record for name: ${recordName}`);
|
||||
log(`找不到${recordName}的SOA记录,继续往主域名查找`);
|
||||
const parentRecordName = recordName.split('.').slice(1).join('.');
|
||||
|
||||
if (!parentRecordName.includes('.')) {
|
||||
throw new Error('Unable to resolve domain by SOA record');
|
||||
throw new Error('SOA record查找失败');
|
||||
}
|
||||
|
||||
return resolveDomainBySoaRecord(parentRecordName);
|
||||
@@ -241,7 +242,7 @@ async function resolveDomainBySoaRecord(recordName) {
|
||||
*/
|
||||
|
||||
async function getAuthoritativeDnsResolver(recordName) {
|
||||
log(`Locating authoritative NS records for name: ${recordName}`);
|
||||
log(`获取域名${recordName}的权威NS服务器: `);
|
||||
const resolver = new dns.Resolver();
|
||||
|
||||
try {
|
||||
@@ -249,13 +250,14 @@ async function getAuthoritativeDnsResolver(recordName) {
|
||||
const domain = await resolveDomainBySoaRecord(recordName);
|
||||
|
||||
/* Resolve authoritative NS addresses */
|
||||
log(`Looking up authoritative NS records for domain: ${domain}`);
|
||||
log(`获取到权威NS服务器name: ${domain}`);
|
||||
const nsRecords = await dns.resolveNs(domain);
|
||||
log(`域名权威NS服务器:${nsRecords}`);
|
||||
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));
|
||||
const nsAddresses = [].concat(...nsAddrArray).filter((a) => a);
|
||||
|
||||
if (!nsAddresses.length) {
|
||||
throw new Error(`Unable to locate any valid authoritative NS addresses for domain: ${domain}`);
|
||||
throw new Error(`Unable to locate any valid authoritative NS addresses for domain(获取权威服务器IP失败): ${domain}`);
|
||||
}
|
||||
|
||||
/* Authoritative NS success */
|
||||
@@ -263,12 +265,12 @@ async function getAuthoritativeDnsResolver(recordName) {
|
||||
resolver.setServers(nsAddresses);
|
||||
}
|
||||
catch (e) {
|
||||
log(`Authoritative NS lookup error: ${e.message}`);
|
||||
log(`Authoritative NS lookup error(获取权威NS服务器地址失败): ${e.message}`);
|
||||
}
|
||||
|
||||
/* Return resolver */
|
||||
const addresses = resolver.getServers();
|
||||
log(`DNS resolver addresses: ${addresses.join(', ')}`);
|
||||
log(`DNS resolver addresses(域名的权威NS服务器地址): ${addresses.join(', ')}`);
|
||||
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@@ -48,55 +48,85 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix =
|
||||
* Walk DNS until TXT records are found
|
||||
*/
|
||||
|
||||
async function walkDnsChallengeRecord(recordName, resolver = dns) {
|
||||
/* Resolve CNAME record first */
|
||||
// try {
|
||||
// log(`Checking name for CNAME records: ${recordName}`);
|
||||
// const cnameRecords = await resolver.resolveCname(recordName);
|
||||
//
|
||||
// if (cnameRecords.length) {
|
||||
// log(`CNAME record found at ${recordName}, new challenge record name: ${cnameRecords[0]}`);
|
||||
// return walkDnsChallengeRecord(cnameRecords[0]);
|
||||
// }
|
||||
// }
|
||||
// catch (e) {
|
||||
// log(`No CNAME records found for name: ${recordName}`);
|
||||
// }
|
||||
async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) {
|
||||
|
||||
let records = [];
|
||||
|
||||
/* Resolve TXT records */
|
||||
try {
|
||||
log(`Checking name for TXT records: ${recordName}`);
|
||||
log(`检查域名 ${recordName} 的TXT记录`);
|
||||
const txtRecords = await resolver.resolveTxt(recordName);
|
||||
|
||||
if (txtRecords && txtRecords.length) {
|
||||
log(`Found ${txtRecords.length} TXT records at ${recordName}`);
|
||||
log(`找到 ${txtRecords.length} 条 TXT记录( ${recordName})`);
|
||||
log(`TXT records: ${JSON.stringify(txtRecords)}`);
|
||||
return [].concat(...txtRecords);
|
||||
records = records.concat(...txtRecords);
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
log(`解析 TXT 记录出错, ${recordName} :${e.message}`);
|
||||
}
|
||||
catch (e) {
|
||||
log(`Resolve TXT records error, ${recordName} :${e.message}`);
|
||||
throw e;
|
||||
|
||||
/* Resolve CNAME record first */
|
||||
try {
|
||||
log(`检查是否存在CNAME映射: ${recordName}`);
|
||||
const cnameRecords = await resolver.resolveCname(recordName);
|
||||
|
||||
if (cnameRecords.length) {
|
||||
const cnameRecord = cnameRecords[0];
|
||||
log(`已找到${recordName}的CNAME记录,将检查: ${cnameRecord}`);
|
||||
let res= await walkTxtRecord(cnameRecord,deep+1);
|
||||
if (res && res.length) {
|
||||
log(`从CNAME中找到TXT记录: ${JSON.stringify(res)}`);
|
||||
records = records.concat(...res);
|
||||
}
|
||||
}else{
|
||||
log(`没有CNAME映射(${recordName})`);
|
||||
}
|
||||
} catch (e) {
|
||||
log(`检查CNAME出错(${recordName}) :${e.message}`);
|
||||
}
|
||||
return records
|
||||
}
|
||||
|
||||
export async function walkTxtRecord(recordName) {
|
||||
export async function walkTxtRecord(recordName,deep = 0) {
|
||||
if(deep >5){
|
||||
log(`walkTxtRecord too deep (#${deep}) , skip walk`)
|
||||
return []
|
||||
}
|
||||
|
||||
const txtRecords = []
|
||||
try {
|
||||
/* Default DNS resolver first */
|
||||
log('Attempting to resolve TXT with default DNS resolver first');
|
||||
const res = await walkDnsChallengeRecord(recordName);
|
||||
log('从本地DNS服务器获取TXT解析记录');
|
||||
const res = await walkDnsChallengeRecord(recordName,dns,deep);
|
||||
if (res && res.length > 0) {
|
||||
return res;
|
||||
for (const item of res) {
|
||||
txtRecords.push(item)
|
||||
}
|
||||
}
|
||||
throw new Error('No TXT records found');
|
||||
|
||||
} catch (e) {
|
||||
log(`本地获取TXT解析记录失败:${e.message}`)
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
try{
|
||||
/* Authoritative DNS resolver */
|
||||
log(`Error using default resolver, attempting to resolve TXT with authoritative NS: ${e.message}`);
|
||||
log(`从域名权威服务器获取TXT解析记录`);
|
||||
const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName);
|
||||
return await walkDnsChallengeRecord(recordName, authoritativeResolver);
|
||||
const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep);
|
||||
if (res && res.length > 0) {
|
||||
for (const item of res) {
|
||||
txtRecords.push(item)
|
||||
}
|
||||
}
|
||||
}catch (e) {
|
||||
log(`权威服务器获取TXT解析记录失败:${e.message}`)
|
||||
}
|
||||
|
||||
if (txtRecords.length === 0) {
|
||||
throw new Error(`没有找到TXT解析记录(${recordName})`);
|
||||
}
|
||||
return txtRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,14 +143,16 @@ export async function walkTxtRecord(recordName) {
|
||||
|
||||
async function verifyDnsChallenge(authz, challenge, keyAuthorization, prefix = '_acme-challenge.') {
|
||||
const recordName = `${prefix}${authz.identifier.value}`;
|
||||
log(`Resolving DNS TXT from record: ${recordName}`);
|
||||
const recordValues = await walkTxtRecord(recordName);
|
||||
log(`DNS query finished successfully, found ${recordValues.length} TXT records`);
|
||||
log(`本地校验TXT记录): ${recordName}`);
|
||||
let recordValues = await walkTxtRecord(recordName);
|
||||
//去重
|
||||
recordValues = [...new Set(recordValues)];
|
||||
log(`DNS查询成功, 找到 ${recordValues.length} 条TXT记录:${recordValues}`);
|
||||
if (!recordValues.length || !recordValues.includes(keyAuthorization)) {
|
||||
throw new Error(`Authorization not found in DNS TXT record: ${recordName},need:${keyAuthorization},found:${recordValues}`);
|
||||
throw new Error(`没有找到需要的DNS TXT记录: ${recordName},期望:${keyAuthorization},结果:${recordValues}`);
|
||||
}
|
||||
|
||||
log(`Key authorization match for ${challenge.type}/${recordName}, ACME challenge verified`);
|
||||
log(`关键授权匹配成功(${challenge.type}/${recordName}):${keyAuthorization},校验成功, ACME challenge verified`);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
||||
7
packages/core/basic/.prettierrc
Normal file
7
packages/core/basic/.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -3,6 +3,83 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持又拍云cdn ([fd0536b](https://github.com/certd/certd/commit/fd0536bd4b41f15b6b5d42e0b447f0dcbf73b8a8))
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到天翼云CDN ([82a72e0](https://github.com/certd/certd/commit/82a72e0b497efa043d342ad0e33c083a2de79a05))
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 流水线同一个阶段任务优化为并行执行 ([efa9c74](https://github.com/certd/certd/commit/efa9c748c5c07fc950af3db742ef9310f1ac9a4b))
|
||||
* 支持易盾RCDN部署 ([065713c](https://github.com/certd/certd/commit/065713cdb6953d16df08585c316c1a7a8eaec437))
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持新版本LeCDN ([44d43f4](https://github.com/certd/certd/commit/44d43f45cb9094619df7494c2a64a51ba77ad116))
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
16:07
|
||||
01:33
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.30.2",
|
||||
"version": "1.32.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -33,8 +33,8 @@
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/node-forge": "^1.3.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
||||
"@typescript-eslint/parser": "^5.59.7",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"chai": "4.3.10",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
@@ -44,5 +44,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "089825d3602440188392f7018d0eb9038617c1d6"
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import { nanoid } from 'nanoid';
|
||||
import * as id from './util.id.js';
|
||||
import { locker } from './util.lock.js';
|
||||
import { mitter } from './util.mitter.js';
|
||||
|
||||
import * as request from './util.request.js';
|
||||
export const utils = {
|
||||
sleep,
|
||||
http,
|
||||
@@ -52,4 +54,5 @@ export const utils = {
|
||||
locker,
|
||||
mitter,
|
||||
amount: amountUtils,
|
||||
request,
|
||||
};
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
import crypto from 'crypto';
|
||||
import crypto, { BinaryToTextEncoding } from 'crypto';
|
||||
|
||||
function md5(data: string) {
|
||||
return crypto.createHash('md5').update(data).digest('hex');
|
||||
function md5(data: string, digest: BinaryToTextEncoding = 'hex') {
|
||||
return crypto.createHash('md5').update(data).digest(digest);
|
||||
}
|
||||
function sha256(data: string) {
|
||||
return crypto.createHash('sha256').update(data).digest('hex');
|
||||
function sha256(data: string, digest: BinaryToTextEncoding = 'hex') {
|
||||
return crypto.createHash('sha256').update(data).digest(digest);
|
||||
}
|
||||
|
||||
function hmacSha256(data: string, digest: BinaryToTextEncoding = 'base64') {
|
||||
return crypto.createHmac('sha256', data).update(Buffer.alloc(0)).digest(digest);
|
||||
}
|
||||
|
||||
function base64(data: string) {
|
||||
return Buffer.from(data).toString('base64');
|
||||
}
|
||||
export const hashUtils = {
|
||||
md5,
|
||||
sha256,
|
||||
base64,
|
||||
hmacSha256,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import { customAlphabet } from "nanoid";
|
||||
|
||||
export const randomNumber = customAlphabet('1234567890', 4);
|
||||
export const simpleNanoId = customAlphabet('1234567890abcdefghijklmopqrstuvwxyz', 12);
|
||||
export const randomNumber = customAlphabet("1234567890", 4);
|
||||
export const simpleNanoId = customAlphabet("1234567890abcdefghijklmopqrstuvwxyz", 12);
|
||||
|
||||
@@ -310,3 +310,14 @@ export async function download(req: { http: HttpClient; config: HttpRequestConfi
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getCookie(response: any, name: string) {
|
||||
const cookies = response.headers['set-cookie'];
|
||||
//根据name 返回对应的cookie
|
||||
const found = cookies.find((cookie: any) => cookie.includes(name));
|
||||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
const cookie = found.split(';')[0];
|
||||
return cookie.substring(cookie.indexOf('=') + 1);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/core/pipeline/.gitignore
vendored
1
packages/core/pipeline/.gitignore
vendored
@@ -26,3 +26,4 @@ dist-ssr
|
||||
test/user.secret.*
|
||||
test/**/*.js
|
||||
src/**/*.spec.ts
|
||||
.test.mjs
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -3,6 +3,92 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到京东云cdn ([6f17c70](https://github.com/certd/certd/commit/6f17c700b84965baa01b40fe2abaa0a91bcbaffd))
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* tab增加图标显示 ([a03ae5a](https://github.com/certd/certd/commit/a03ae5a216a1df2c1d3da12ae18dcd0f089a92d3))
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* dns支持火山引擎 ([99ff879](https://github.com/certd/certd/commit/99ff879d93658c29ea493a4bde7e9e3f85996d64))
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复站点监控通知通过webhook发送失败的bug ([9be1ecc](https://github.com/certd/certd/commit/9be1ecc8aab3ea23dd0dc2dab3688f4edb90ef2c))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 流水线增加上传证书快捷方式 ([425bba6](https://github.com/certd/certd/commit/425bba67c539b734e2a85a83a4f9ecc9b2434fb4))
|
||||
* 支持飞书通知 ([b82e1dc](https://github.com/certd/certd/commit/b82e1dcd6217b09a7d7e21cd648bb31de320cadf))
|
||||
* 支持手动上传证书并部署 ([a9fffa5](https://github.com/certd/certd/commit/a9fffa5180c83da27b35886aa2e858a92a2c5f94))
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 流水线同一个阶段任务优化为并行执行 ([efa9c74](https://github.com/certd/certd/commit/efa9c748c5c07fc950af3db742ef9310f1ac9a4b))
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到阿里云证书名称后缀增加毫秒时间戳 ([9f0ee21](https://github.com/certd/certd/commit/9f0ee219d02907ffe128a5cf10173397d934ccd7))
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.30.2",
|
||||
"version": "1.32.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -16,8 +16,8 @@
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.30.2",
|
||||
"@certd/plus-core": "^1.30.2",
|
||||
"@certd/basic": "^1.32.0",
|
||||
"@certd/plus-core": "^1.32.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -31,8 +31,8 @@
|
||||
"@types/chai": "^4.3.10",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
||||
"@typescript-eslint/parser": "^5.59.7",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"chai": "4.3.10",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
@@ -43,5 +43,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "089825d3602440188392f7018d0eb9038617c1d6"
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import type { ResultError } from "../dt/index.js";
|
||||
|
||||
export class CancelError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export class RunnableError extends Error {
|
||||
errors: ResultError[];
|
||||
constructor(message: string, errors: ResultError[]) {
|
||||
super(message);
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
|
||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task, ResultError } from "../dt/index.js";
|
||||
import { RunHistory, RunnableCollection } from "./run-history.js";
|
||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
||||
import { ContextFactory, IContext } from "./context.js";
|
||||
@@ -7,11 +7,12 @@ import { createAxiosService, hashUtils, HttpRequestConfig, ILogger, logger, util
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { RegistryItem } from "../registry/index.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import { ICnameProxyService, IEmailService, IPluginConfigService, IUrlService } from "../service/index.js";
|
||||
import { ICnameProxyService, IEmailService, IPluginConfigService, IServiceGetter, IUrlService } from "../service/index.js";
|
||||
import { FileStore } from "./file-store.js";
|
||||
import { cloneDeep, forEach, merge } from "lodash-es";
|
||||
import { INotificationService } from "../notification/index.js";
|
||||
import { taskEmitterCreate } from "../service/emit.js";
|
||||
import { RunnableError } from "./exceptions.js";
|
||||
|
||||
export type SysInfo = {
|
||||
//系统标题
|
||||
@@ -32,6 +33,7 @@ export type ExecutorOptions = {
|
||||
user: UserInfo;
|
||||
baseURL?: string;
|
||||
sysInfo?: SysInfo;
|
||||
serviceGetter: IServiceGetter;
|
||||
};
|
||||
|
||||
export class Executor {
|
||||
@@ -192,6 +194,8 @@ export class Executor {
|
||||
}
|
||||
|
||||
let resList: ResultType[] = [];
|
||||
const errorList: ResultError[] = [];
|
||||
let errorMessage = "";
|
||||
if (stage.concurrency === ConcurrencyStrategy.Parallel) {
|
||||
//并行
|
||||
const pList = [];
|
||||
@@ -200,10 +204,25 @@ export class Executor {
|
||||
}
|
||||
resList = await Promise.all(pList);
|
||||
} else {
|
||||
//串行
|
||||
//串行且报错继续
|
||||
for (let i = 0; i < runnerList.length; i++) {
|
||||
const runner = runnerList[i];
|
||||
resList[i] = await runner();
|
||||
try {
|
||||
resList[i] = await runner();
|
||||
} catch (e: any) {
|
||||
const t = stage.tasks[i];
|
||||
this.logger.error(`任务 ${t.title} 执行异常:`, e.message);
|
||||
resList[i] = ResultType.error;
|
||||
errorList.push({
|
||||
e,
|
||||
returnType: ResultType.error,
|
||||
runnable: t,
|
||||
});
|
||||
errorMessage += `任务${t.title}执行失败,错误详情:${e.message};`;
|
||||
}
|
||||
}
|
||||
if (errorList.length > 0) {
|
||||
throw new RunnableError(errorMessage, errorList);
|
||||
}
|
||||
}
|
||||
return this.compositionResultType(resList);
|
||||
@@ -347,6 +366,7 @@ export class Executor {
|
||||
step,
|
||||
pipeline: this.pipeline,
|
||||
}),
|
||||
serviceGetter: this.options.serviceGetter,
|
||||
};
|
||||
instance.setCtx(taskCtx);
|
||||
|
||||
@@ -402,7 +422,16 @@ export class Executor {
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
||||
} else if (when === "error") {
|
||||
subject = `执行失败,${this.pipeline.title}【${this.pipeline.id}】`;
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n\n${this.currentStatusMap?.currentStep?.title} 执行失败\n\n错误详情:${error.message}`;
|
||||
|
||||
if (error instanceof RunnableError) {
|
||||
const runnableError = error as RunnableError;
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n\n`;
|
||||
for (const re of runnableError.errors) {
|
||||
content += ` - ${re.runnable.title} 执行失败\n 错误详情:${re.e.message}\n\n`;
|
||||
}
|
||||
} else {
|
||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n\n${this.currentStatusMap?.currentStep?.title} 执行失败\n\n错误详情:${error.message}`;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,11 +11,13 @@ function attachProperty(target: any, propertyKey: string | symbol) {
|
||||
}
|
||||
|
||||
function getClassProperties(target: any) {
|
||||
//获取父类
|
||||
//获取父类, 向上追溯三层
|
||||
const parent = Object.getPrototypeOf(target);
|
||||
const pParent = Object.getPrototypeOf(parent);
|
||||
const pParentMap = propertyMap[pParent] || {};
|
||||
const parentMap = propertyMap[parent] || {};
|
||||
const current = propertyMap[target] || {};
|
||||
return _.merge({}, parentMap, current);
|
||||
return _.merge({}, pParentMap, parentMap, current);
|
||||
}
|
||||
|
||||
function target(target: any, propertyKey?: string | symbol) {
|
||||
|
||||
@@ -107,6 +107,12 @@ export type Log = {
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type ResultError = {
|
||||
e: any;
|
||||
returnType: ResultType;
|
||||
runnable: Runnable;
|
||||
};
|
||||
|
||||
export enum ResultType {
|
||||
start = "start",
|
||||
success = "success",
|
||||
|
||||
@@ -119,10 +119,12 @@ export abstract class BaseNotification implements INotification {
|
||||
}
|
||||
|
||||
async onTestRequest() {
|
||||
await this.doSend({
|
||||
return await this.doSend({
|
||||
userId: 0,
|
||||
title: "【Certd】测试通知【*.foo.com】,标题长度测试、测试、测试",
|
||||
content: "测试通知,*.foo.com",
|
||||
content: `测试通知,*.foo.com
|
||||
换行测试
|
||||
`,
|
||||
pipeline: {
|
||||
id: 1,
|
||||
title: "证书申请成功【测试流水线】",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Registrable } from "../registry/index.js";
|
||||
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../dt/index.js";
|
||||
import { FileStore } from "../core/file-store.js";
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { ICnameProxyService, IEmailService, IUrlService } from "../service/index.js";
|
||||
import { ICnameProxyService, IEmailService, IServiceGetter, IUrlService } from "../service/index.js";
|
||||
import { CancelError, IContext, RunHistory, RunnableCollection } from "../core/index.js";
|
||||
import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
|
||||
import { HttpClient } from "@certd/basic";
|
||||
@@ -55,6 +55,14 @@ export type PluginDefine = Registrable & {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
shortcut?: {
|
||||
[key: string]: {
|
||||
title: string;
|
||||
icon: string;
|
||||
action: string;
|
||||
form: any;
|
||||
};
|
||||
};
|
||||
needPlus?: boolean;
|
||||
};
|
||||
|
||||
@@ -114,6 +122,9 @@ export type TaskInstanceContext = {
|
||||
user: UserInfo;
|
||||
|
||||
emitter: TaskEmitter;
|
||||
|
||||
//service 容器
|
||||
serviceGetter?: IServiceGetter;
|
||||
};
|
||||
|
||||
export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
@@ -193,7 +204,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
if (name == null) {
|
||||
name = "certd";
|
||||
}
|
||||
return name + "_" + dayjs().format("YYYYMMDDHHmmss");
|
||||
return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS");
|
||||
}
|
||||
|
||||
async onRequest(req: PluginRequestHandleReq<any>) {
|
||||
@@ -221,7 +232,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
|
||||
getStepFromPipeline(stepId: string) {
|
||||
let found: any = null;
|
||||
RunnableCollection.each(this.ctx.pipeline.stages, (step) => {
|
||||
RunnableCollection.each(this.ctx.pipeline.stages, step => {
|
||||
if (step.id === stepId) {
|
||||
found = step;
|
||||
return;
|
||||
|
||||
@@ -6,24 +6,28 @@ export class PluginGroup {
|
||||
desc?: string;
|
||||
order: number;
|
||||
plugins: PluginDefine[];
|
||||
constructor(key: string, title: string, order = 0, desc = "") {
|
||||
icon?: string;
|
||||
|
||||
constructor(key: string, title: string, order = 0, icon = "") {
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
this.order = order;
|
||||
this.desc = desc;
|
||||
this.icon = icon;
|
||||
this.plugins = [];
|
||||
}
|
||||
}
|
||||
|
||||
export const pluginGroups = {
|
||||
cert: new PluginGroup("cert", "证书申请", 1),
|
||||
aliyun: new PluginGroup("aliyun", "阿里云", 2),
|
||||
huawei: new PluginGroup("huawei", "华为云", 3),
|
||||
tencent: new PluginGroup("tencent", "腾讯云", 4),
|
||||
qiniu: new PluginGroup("qiniu", "七牛云", 5),
|
||||
aws: new PluginGroup("aws", "亚马逊云", 6),
|
||||
host: new PluginGroup("host", "主机", 7),
|
||||
cdn: new PluginGroup("cdn", "CDN", 8),
|
||||
panel: new PluginGroup("panel", "面板", 9),
|
||||
other: new PluginGroup("other", "其他", 10),
|
||||
cert: new PluginGroup("cert", "证书申请", 1, "ph:certificate"),
|
||||
host: new PluginGroup("host", "主机", 2, "clarity:host-line"),
|
||||
cdn: new PluginGroup("cdn", "CDN", 2, "svg:icon-cdn"),
|
||||
panel: new PluginGroup("panel", "面板", 2, "fluent:panel-left-header-32-filled"),
|
||||
aliyun: new PluginGroup("aliyun", "阿里云", 2, "svg:icon-aliyun"),
|
||||
huawei: new PluginGroup("huawei", "华为云", 3, "svg:icon-huawei"),
|
||||
tencent: new PluginGroup("tencent", "腾讯云", 4, "svg:icon-tencentcloud"),
|
||||
volcengine: new PluginGroup("volcengine", "火山引擎", 4, "svg:icon-volcengine"),
|
||||
jdcloud: new PluginGroup("jdcloud", "京东云", 4, "svg:icon-jdcloud"),
|
||||
qiniu: new PluginGroup("qiniu", "七牛云", 5, "svg:icon-qiniuyun"),
|
||||
aws: new PluginGroup("aws", "亚马逊云", 6, "svg:icon-aws"),
|
||||
other: new PluginGroup("other", "其他", 10, "clarity:plugin-line"),
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ export type Registrable = {
|
||||
desc?: string;
|
||||
group?: string;
|
||||
deprecated?: string;
|
||||
order?: number;
|
||||
};
|
||||
|
||||
export type RegistryItem<T> = {
|
||||
|
||||
@@ -3,3 +3,6 @@ export * from "./cname.js";
|
||||
export * from "./config.js";
|
||||
export * from "./url.js";
|
||||
export * from "./emit.js";
|
||||
export type IServiceGetter = {
|
||||
get: (name: string) => Promise<any>;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@@ -3,6 +3,80 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持京东云dns申请证书 ([04d79f9](https://github.com/certd/certd/commit/04d79f9117670be504960b018fd49ae3bf7c1c11))
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化华为dns接口报错信息输出 ([bf30b7a](https://github.com/certd/certd/commit/bf30b7afaef623dd8126570344f1fcc2c06f1215))
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复华为云dns接口请求出错的bug ([caa15b4](https://github.com/certd/certd/commit/caa15b47355363cbb8847f415ff12363cd53eeda))
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.30.2",
|
||||
"version": "1.32.0",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -18,8 +18,10 @@
|
||||
"rollup": "^3.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "089825d3602440188392f7018d0eb9038617c1d6"
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = {
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
json(),
|
||||
terser(),
|
||||
// terser(),
|
||||
],
|
||||
external: ["vue", "lodash-es", "dayjs", "log4js", "@midwayjs/core", "@certd/pipeline", "axios"],
|
||||
};
|
||||
|
||||
@@ -2,8 +2,10 @@ import { Signer, SigHttpRequest } from "./signer.js";
|
||||
import axios from "axios";
|
||||
export class HuaweiYunClient {
|
||||
access;
|
||||
logger;
|
||||
constructor(access, logger) {
|
||||
this.access = access;
|
||||
this.logger = logger
|
||||
}
|
||||
async request(options) {
|
||||
const sig = new Signer(this.access.accessKeyId, this.access.accessKeySecret);
|
||||
@@ -32,7 +34,7 @@ export class HuaweiYunClient {
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
this.logger.error("华为云接口请求出错:", e?.response?.data);
|
||||
const error = new Error(e?.response?.data.message);
|
||||
const error = new Error(JSON.stringify(e?.response?.data));
|
||||
error.code = e?.response?.code;
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"printWidth": 160,
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,74 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.30.2",
|
||||
"version": "1.32.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -20,8 +20,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
||||
"@typescript-eslint/parser": "^5.38.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
@@ -30,5 +30,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "089825d3602440188392f7018d0eb9038617c1d6"
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
|
||||
22
packages/libs/lib-jdcloud/.eslintrc
Normal file
22
packages/libs/lib-jdcloud/.eslintrc
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
28
packages/libs/lib-jdcloud/.gitignore
vendored
Normal file
28
packages/libs/lib-jdcloud/.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
test/user.secret.ts
|
||||
|
||||
.rollup.cache
|
||||
3
packages/libs/lib-jdcloud/.npmignore
Normal file
3
packages/libs/lib-jdcloud/.npmignore
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
src
|
||||
.rollup.cache
|
||||
1
packages/libs/lib-jdcloud/.travis.yml
Normal file
1
packages/libs/lib-jdcloud/.travis.yml
Normal file
@@ -0,0 +1 @@
|
||||
language: node_js
|
||||
15
packages/libs/lib-jdcloud/CHANGELOG.md
Normal file
15
packages/libs/lib-jdcloud/CHANGELOG.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持部署到京东云cdn ([6f17c70](https://github.com/certd/certd/commit/6f17c700b84965baa01b40fe2abaa0a91bcbaffd))
|
||||
* 支持京东云dns申请证书 ([04d79f9](https://github.com/certd/certd/commit/04d79f9117670be504960b018fd49ae3bf7c1c11))
|
||||
201
packages/libs/lib-jdcloud/LICENSE
Normal file
201
packages/libs/lib-jdcloud/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
177
packages/libs/lib-jdcloud/README.md
Normal file
177
packages/libs/lib-jdcloud/README.md
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
[](https://standardjs.com)
|
||||
|
||||
# 简介 #
|
||||
欢迎使用京东云开发者Node.js工具套件(Node.js SDK)。使用京东云Node.js SDK,您无需复杂编程就可以访问京东云提供的各种服务。
|
||||
|
||||
为了方便您理解SDK中的一些概念和参数的含义,使用SDK前建议您先查看[京东云OpenAPI使用入门](http://www.jdcloud.com/help/detail/355/isCatalog/0)。要了解每个API的具体参数和含义,请参考程序注释或参考OpenAPI&SDK下具体产品线的API文档。
|
||||
|
||||
|
||||
|
||||
# 环境准备 #
|
||||
1.京东云Node.js SDK适用于Node.js 8.6.0及以上,npm 5.6.0及以上。
|
||||
|
||||
2.在开始调用京东云open API之前,需提前在京东云用户中心账户管理下的[AccessKey管理页面](https://uc.jdcloud.com/accesskey/index)申请accesskey和secretKey密钥对(简称AK/SK)。AK/SK信息请妥善保管,如果遗失可能会造成非法用户使用此信息操作您在云上的资源,给你造成数据和财产损失。
|
||||
|
||||
|
||||
|
||||
# SDK使用方法 #
|
||||
建议使用npm安装京东云Node.js SDK,如下所示:
|
||||
|
||||
npm install jdcloud-sdk-js
|
||||
|
||||
|
||||
|
||||
您还可以下载sdk源代码自行使用,[源代码地址](https://github.com/jdcloud-api/jdcloud-sdk-nodejs)。
|
||||
|
||||
|
||||
|
||||
SDK使用中的任何问题,欢迎您在[SDK使用问题反馈页面](https://github.com/jdcloud-api/jdcloud-sdk-nodejs/issues)交流。
|
||||
|
||||
|
||||
|
||||
注意:京东云并没有提供其他下载方式,请务必使用上述官方下载方式!
|
||||
|
||||
|
||||
|
||||
# 调用SDK #
|
||||
|
||||
## 两种引用方式 ##
|
||||
var JDCloud = require('jdcloud-sdk-js');
|
||||
|
||||
这种引用方式会加载所有的可用的services
|
||||
|
||||
|
||||
|
||||
var NC = require('jdcloud-sdk-js/services/nativecontainer');
|
||||
|
||||
这种引用方式只会加载用到的service,此时仍然可以使用var JDCloud = require('jdcloud-sdk-js/global')来引用JDCloud对象
|
||||
|
||||
## 配置方法 ##
|
||||
|
||||
对JDCloud的配置为通用配置,所有services共享配置:
|
||||
|
||||
JDCloud.config.update({//*配置项/*/});
|
||||
|
||||
对某个service的配置会覆盖通用配置:
|
||||
|
||||
var NC = require('jdcloud-sdk-js/services/nativecontainer');
|
||||
var nc = new NATIVECONTAINER({//*配置项/*/});
|
||||
|
||||
|
||||
## 配置项 ##
|
||||
|
||||
let config = {
|
||||
credentials: {
|
||||
accessKeyId: global.accessKeyId, secretAccessKey: global.secretAccessKey
|
||||
},
|
||||
regionId: 'cn-north-1' //地域信息,某个api调用可以单独传参regionId,如果不传则会使用此配置中的regionId
|
||||
}
|
||||
|
||||
|
||||
## 调用示例 ##
|
||||
|
||||
以下是查询单个云主机实例详情的调用示例
|
||||
|
||||
|
||||
### 引用和配置 ###
|
||||
|
||||
var VM = require('jdcloud-sdk-js/services/vm')
|
||||
var vm = new VM({
|
||||
credentials: {
|
||||
accessKeyId: global.accessKeyId,
|
||||
secretAccessKey: global.secretAccessKey
|
||||
},
|
||||
regionId: 'cn-north-1'
|
||||
})
|
||||
|
||||
|
||||
|
||||
### Promise方式调用 ####
|
||||
|
||||
vm.createInstances({
|
||||
instanceSpec: {
|
||||
instanceType: 'g.s1.micro',
|
||||
az: 'cn-north-1a',
|
||||
imageId: '98d44a0f-88c1-451a-8971-f1f769073b6c',
|
||||
name: 'node-sdk-test',
|
||||
elasticIp: {
|
||||
bandwidthMbps: 2, provider: 'BGP'
|
||||
},
|
||||
primaryNetworkInterface: {
|
||||
networkInterface: {
|
||||
subnetId: 'subnet-3dm13k30gh',
|
||||
az: 'cn-north-1a'
|
||||
}
|
||||
},
|
||||
systemDisk: {
|
||||
diskCategory: 'local'
|
||||
},
|
||||
description: 'sdk'
|
||||
},
|
||||
maxCount: 1
|
||||
},'cn-north-1').then(function(data){ // 返回数据处理 data
|
||||
},
|
||||
function(e){ // 调用API失败,错误处理
|
||||
})
|
||||
|
||||
|
||||
|
||||
### callback方式调用 ###
|
||||
|
||||
vm.createInstances({
|
||||
instanceSpec: {
|
||||
instanceType: 'g.s1.micro',
|
||||
az: 'cn-north-1a',
|
||||
imageId: '98d44a0f-88c1-451a-8971-f1f769073b6c',
|
||||
name: 'node-sdk-test',
|
||||
elasticIp: {
|
||||
bandwidthMbps: 2,
|
||||
provider: 'BGP'
|
||||
},
|
||||
primaryNetworkInterface: {
|
||||
networkInterface: {
|
||||
subnetId: 'subnet-3dm13k30gh',
|
||||
az: 'cn-north-1a'
|
||||
}
|
||||
},
|
||||
systemDisk: {
|
||||
diskCategory: 'local'
|
||||
},
|
||||
description: 'sdk'
|
||||
},
|
||||
maxCount: 1
|
||||
},'cn-north-1',
|
||||
function(err, data){
|
||||
if(err){ // 调用API失败,错误处理
|
||||
}
|
||||
else { // 返回数据处理 data
|
||||
}
|
||||
})
|
||||
|
||||
如果需要设置访问点,配置超时,额外请求头等,请参考如下更复杂的例子:
|
||||
|
||||
```
|
||||
var nc = new NATIVECONTAINER({
|
||||
credentials: {
|
||||
accessKeyId: global.accessKeyId,
|
||||
secretAccessKey: global.secretAccessKey
|
||||
},
|
||||
endpoint: {
|
||||
host: 'nativecontainer.internal.cn-north-1.jdcloud-api.com', //指定非默认Endpoint
|
||||
protocol: 'http' //设置使用HTTP而不是HTTPS,vpc专用域名不支持HTTPS
|
||||
},
|
||||
'x-extra-header': { //指定额外header
|
||||
"x-jdcloud-security-token" : "xxx", //要调用开启了MFA操作保护的接口需要传递
|
||||
"x-jdcloud-content-sha256" : "xxx", //body过大,希望用此value替代对body进行哈希的过程
|
||||
"MyOwn" : "xxx"
|
||||
},
|
||||
version: {
|
||||
nativecontainer: 'v1'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
更多调用示例参考 [SDK使用Demo](https://github.com/jdcloud-api/jdcloud-sdk-nodejs/tree/master/test)
|
||||
|
||||
64
packages/libs/lib-jdcloud/package.json
Normal file
64
packages/libs/lib-jdcloud/package.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.32.0",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "cross-env NODE_CONFIG_DIR=./test/config mocha --recursive --require babel-register",
|
||||
"dev": "babel src --out-dir babel -w",
|
||||
"build": "rollup -c ",
|
||||
"dev-build": "npm run build"
|
||||
},
|
||||
"author": "",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"babel-register": "^6.26.0",
|
||||
"buffer": "^5.0.8",
|
||||
"create-hash": "^1.1.3",
|
||||
"create-hmac": "^1.1.6",
|
||||
"debug": "^3.1.0",
|
||||
"node-fetch": "^2.1.2",
|
||||
"querystring": "^0.2.0",
|
||||
"rollup": "^3.7.4",
|
||||
"url": "^0.11.0",
|
||||
"uuid": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"chai": "^4.1.2",
|
||||
"config": "^1.30.0",
|
||||
"cross-env": "^5.1.4",
|
||||
"js-yaml": "^3.11.0",
|
||||
"mocha": "^5.0.0",
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.6.0",
|
||||
"npm": ">= 5.6.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 9"
|
||||
],
|
||||
"standard": {
|
||||
"env": [
|
||||
"node",
|
||||
"mocha",
|
||||
"browser"
|
||||
],
|
||||
"globals": [
|
||||
"Request",
|
||||
"Headers",
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "8374c3941a9d1398989b8f38fd4bfa2a2f29937b"
|
||||
}
|
||||
36
packages/libs/lib-jdcloud/rollup.config.js
Normal file
36
packages/libs/lib-jdcloud/rollup.config.js
Normal file
@@ -0,0 +1,36 @@
|
||||
const resolve = require("@rollup/plugin-node-resolve");
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
//const Typescript = require("rollup-plugin-typescript2");
|
||||
const Typescript = require("@rollup/plugin-typescript");
|
||||
const json = require("@rollup/plugin-json");
|
||||
const terser = require("@rollup/plugin-terser");
|
||||
module.exports = {
|
||||
input: "src/index.ts",
|
||||
output: {
|
||||
file: "dist/bundle.js",
|
||||
format: "cjs",
|
||||
},
|
||||
plugins: [
|
||||
// 解析第三方依赖
|
||||
resolve(),
|
||||
// 识别 commonjs 模式第三方依赖
|
||||
commonjs({
|
||||
// dynamicRequireRoot: "../../../../",
|
||||
// dynamicRequireTargets: [
|
||||
// // include using a glob pattern (either a string or an array of strings)
|
||||
// "../../../../**/shelljs/src/*",
|
||||
// ],
|
||||
}),
|
||||
Typescript({
|
||||
target: "esnext",
|
||||
rootDir: "src",
|
||||
declaration: true,
|
||||
declarationDir: "dist/d",
|
||||
exclude: ["./node_modules/**", "./src/**/*.vue", "./src/**/*.spec.ts"],
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
json(),
|
||||
// terser(),
|
||||
],
|
||||
external: ["vue", "lodash-es", "dayjs", "log4js", "@midwayjs/core", "@certd/pipeline", "axios"],
|
||||
};
|
||||
2
packages/libs/lib-jdcloud/src/global.js
Normal file
2
packages/libs/lib-jdcloud/src/global.js
Normal file
@@ -0,0 +1,2 @@
|
||||
require('./lib/node_loader')
|
||||
module.exports = require('./lib/core')
|
||||
11
packages/libs/lib-jdcloud/src/index.ts
Normal file
11
packages/libs/lib-jdcloud/src/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import jdCloud from "./lib/core.js";
|
||||
import jdService from './lib/service.js'
|
||||
|
||||
import domainService from './repo/domainservice/v2/domainservice.js'
|
||||
import cdnService from './repo/cdn/v1/cdn.js'
|
||||
import sslService from './repo/ssl/v1/ssl.js'
|
||||
export const JDCloud = jdCloud;
|
||||
export const JDService = jdService;
|
||||
export const JDDomainService = domainService;
|
||||
export const JDCdnService = cdnService;
|
||||
export const JDSslService = sslService;
|
||||
1
packages/libs/lib-jdcloud/src/jdcloud.js
Normal file
1
packages/libs/lib-jdcloud/src/jdcloud.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib/jc')
|
||||
5
packages/libs/lib-jdcloud/src/lib/browser.js
Normal file
5
packages/libs/lib-jdcloud/src/lib/browser.js
Normal file
@@ -0,0 +1,5 @@
|
||||
require('babel-polyfill')
|
||||
require('./browser_loader')
|
||||
var JC = require('./core')
|
||||
require('../services/all')
|
||||
module.exports = JC
|
||||
13
packages/libs/lib-jdcloud/src/lib/browser_loader.js
Normal file
13
packages/libs/lib-jdcloud/src/lib/browser_loader.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var util = require('./util')
|
||||
util.crypto.lib = {
|
||||
createHash: require('create-hash'),
|
||||
createHmac: require('create-hmac')
|
||||
}
|
||||
util.Buffer = require('buffer/').Buffer
|
||||
util.url = require('url/')
|
||||
util.querystring = require('querystring/')
|
||||
util.environment = 'js'
|
||||
|
||||
var JC = require('./core')
|
||||
|
||||
module.exports = JC
|
||||
6
packages/libs/lib-jdcloud/src/lib/common.js
Normal file
6
packages/libs/lib-jdcloud/src/lib/common.js
Normal file
@@ -0,0 +1,6 @@
|
||||
require('./core')
|
||||
|
||||
require('./config')
|
||||
require('./request')
|
||||
require('./service')
|
||||
require('./credentials')
|
||||
78
packages/libs/lib-jdcloud/src/lib/config.js
Normal file
78
packages/libs/lib-jdcloud/src/lib/config.js
Normal file
@@ -0,0 +1,78 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
let defaultValues = {
|
||||
credentials: null,
|
||||
regionId: null,
|
||||
apiVersions: null,
|
||||
endpoint: {},
|
||||
version: {},
|
||||
logger: function (string, level = 'INFO') {
|
||||
// level: INFO / DEBUG / ERROR / WARN
|
||||
console.log(string)
|
||||
}
|
||||
}
|
||||
JDCloud.Config = class Config {
|
||||
constructor (options = {}) {
|
||||
options = this.extractCredentials(options)
|
||||
|
||||
JDCloud.util.each.call(this, defaultValues, function (key, value) {
|
||||
if (options[key] === undefined) {
|
||||
this[key] = value
|
||||
} else {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
JDCloud.util.each.call(this, JDCloud.Service._services, function (
|
||||
key,
|
||||
value
|
||||
) {
|
||||
if (options[key] !== undefined) {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
extractCredentials (options) {
|
||||
if (options.accessKeyId && options.secretAccessKey) {
|
||||
options = Object.assign({}, options)
|
||||
options.credentials = new JDCloud.Credentials(options)
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
getCredentials () {
|
||||
var p = new Promise((resolve, reject) => {
|
||||
if (this.credentials) {
|
||||
if (typeof this.credentials.get === 'function') {
|
||||
} else if (
|
||||
this.credentials.accessKeyId &&
|
||||
this.credentials.secretAccessKey
|
||||
) {
|
||||
resolve()
|
||||
} else {
|
||||
reject(new Error('missing credentials'))
|
||||
}
|
||||
} else if (this.credentialProvider) {
|
||||
} else {
|
||||
reject(new Error('get credentials failed'))
|
||||
}
|
||||
})
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
update (options, allowUnknownKeys = false) {
|
||||
options = this.extractCredentials(options)
|
||||
JDCloud.util.each.call(this, options, function (key, value) {
|
||||
if (
|
||||
allowUnknownKeys ||
|
||||
defaultValues.hasOwnProperty(key) ||
|
||||
JDCloud.Service.hasService(key)
|
||||
) {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
JDCloud.config = new JDCloud.Config()
|
||||
13
packages/libs/lib-jdcloud/src/lib/core.js
Normal file
13
packages/libs/lib-jdcloud/src/lib/core.js
Normal file
@@ -0,0 +1,13 @@
|
||||
require('node-fetch')
|
||||
|
||||
var JDCloud = {
|
||||
util: require('./util'),
|
||||
// todo swaggerVar
|
||||
VERSION: ''
|
||||
}
|
||||
|
||||
module.exports = JDCloud
|
||||
|
||||
require('./service')
|
||||
require('./config')
|
||||
require('./request')
|
||||
21
packages/libs/lib-jdcloud/src/lib/credentials.js
Normal file
21
packages/libs/lib-jdcloud/src/lib/credentials.js
Normal file
@@ -0,0 +1,21 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
JDCloud.Credentials = class Credentials {
|
||||
constructor () {
|
||||
this.expired = false
|
||||
this.expireTime = null
|
||||
|
||||
if (arguments.length === 1 && typeof arguments[0] === 'object') {
|
||||
var creds = arguments[0].credentials || arguments[0]
|
||||
this.accessKeyId = creds.accessKeyId
|
||||
this.secretAccessKey = creds.secretAccessKey
|
||||
this.sessionToken = creds.sessionToken
|
||||
} else {
|
||||
this.accessKeyId = arguments[0]
|
||||
this.secretAccessKey = arguments[1]
|
||||
this.sessionToken = arguments[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JDCloud.Credentials
|
||||
4
packages/libs/lib-jdcloud/src/lib/jc.js
Normal file
4
packages/libs/lib-jdcloud/src/lib/jc.js
Normal file
@@ -0,0 +1,4 @@
|
||||
require('./node_loader')
|
||||
var JDCloud = require('./core')
|
||||
require('../services/all')
|
||||
module.exports = JDCloud
|
||||
12
packages/libs/lib-jdcloud/src/lib/node_loader.js
Normal file
12
packages/libs/lib-jdcloud/src/lib/node_loader.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var util = require('./util')
|
||||
|
||||
util.crypto.lib = require('crypto')
|
||||
util.Buffer = require('buffer').Buffer
|
||||
util.url = require('url')
|
||||
util.querystring = require('querystring')
|
||||
util.environment = 'nodejs'
|
||||
let JDCloud = require('./core')
|
||||
JDCloud.fetch = require('node-fetch')
|
||||
module.exports = JDCloud
|
||||
|
||||
require('./credentials')
|
||||
159
packages/libs/lib-jdcloud/src/lib/request.js
Normal file
159
packages/libs/lib-jdcloud/src/lib/request.js
Normal file
@@ -0,0 +1,159 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
let util = JDCloud.util
|
||||
JDCloud.JCRequest = class JCRequest {
|
||||
constructor (
|
||||
service,
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType
|
||||
) {
|
||||
this.service = service
|
||||
|
||||
var endpoint = service.config.endpoint
|
||||
pathParams.regionId = pathParams.regionId || service.config.regionId
|
||||
this.regionId = pathParams.regionId
|
||||
|
||||
this.path = this.buildPath(path, pathParams)
|
||||
this.path = util.uriEscapePath(this.path)
|
||||
|
||||
var queryString = this.buildQuery(queryParams)
|
||||
|
||||
var url = this.path
|
||||
if (queryString) {
|
||||
url = this.path + '?' + queryString
|
||||
}
|
||||
|
||||
var contentType = this.jsonPreferredMime(contentTypes) || 'application/json'
|
||||
headerParams['content-type'] = contentType
|
||||
var requestHeaders = this.buildHeaders(headerParams)
|
||||
|
||||
var requestInit = {
|
||||
method: httpMethod || 'GET',
|
||||
headers: requestHeaders
|
||||
}
|
||||
|
||||
if (contentType === 'application/x-www-form-urlencoded') {
|
||||
} else if (contentType === 'multipart/form-data') {
|
||||
} else if (postBody) {
|
||||
requestInit.body = JSON.stringify(postBody)
|
||||
}
|
||||
var fetchUrl = endpoint.protocol + '://' + endpoint.host + url
|
||||
JDCloud.config.logger(
|
||||
`make request where url is :${fetchUrl} \nwith fetch config:${JSON.stringify(
|
||||
requestInit
|
||||
)}`
|
||||
)
|
||||
this.request = new JDCloud.fetch.Request(fetchUrl, requestInit)
|
||||
}
|
||||
|
||||
buildPath (path, pathParams) {
|
||||
var uri = (this.service.config.basePath || '') + path
|
||||
uri = uri.replace(/\{([\w-]+)\}/g, (fullMatch, key) => {
|
||||
var value
|
||||
if (pathParams.hasOwnProperty(key)) {
|
||||
value = pathParams[key]
|
||||
} else {
|
||||
value = fullMatch
|
||||
}
|
||||
return value
|
||||
})
|
||||
return uri
|
||||
}
|
||||
|
||||
buildQuery (queryParams) {
|
||||
var queryParamsWithoutEmptyItem = {}
|
||||
var keys = Object.keys(queryParams)
|
||||
for (let key of keys) {
|
||||
if (queryParams[key] !== undefined) {
|
||||
queryParamsWithoutEmptyItem[key] = queryParams[key]
|
||||
}
|
||||
}
|
||||
return JDCloud.util.querystring.stringify(queryParamsWithoutEmptyItem)
|
||||
}
|
||||
|
||||
search () {
|
||||
var query = this.request.url.split('?', 2)[1]
|
||||
if (query) {
|
||||
query = JDCloud.util.querystring.parse(query)
|
||||
return JDCloud.util.queryParamsToString(query)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
digitizationArray (key, obj) {
|
||||
var result = key
|
||||
if (Array.isArray(obj)) {
|
||||
JDCloud.util.arrayEach(obj, (arrayValue, index) => {
|
||||
result += this.digitizationArray(`.${index + 1}`, arrayValue)
|
||||
})
|
||||
} else if (typeof obj === 'object' && obj != null) {
|
||||
JDCloud.util.each(obj, (key, ObjValue) => {
|
||||
result += `.name=${key}&${result}.values` + this.digitizationArray()
|
||||
result +=
|
||||
key +
|
||||
'.name=' +
|
||||
ObjValue +
|
||||
'&' +
|
||||
this.digitizationArray(key + '.values', ObjValue)
|
||||
})
|
||||
} else {
|
||||
result += key + '=' + encodeURI(obj)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildHeaders (headerParams) {
|
||||
var headers = new JDCloud.fetch.Headers({
|
||||
accept: 'application/json'
|
||||
})
|
||||
|
||||
util.each.call(this, headerParams, function (key) {
|
||||
if (headerParams[key] !== undefined && headerParams[key] != null) {
|
||||
headers.append(key, headerParams[key])
|
||||
}
|
||||
})
|
||||
return headers
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given content type represents JSON.<br>
|
||||
* JSON content type examples:<br>
|
||||
* <ul>
|
||||
* <li>application/json</li>
|
||||
* <li>application/json; charset=UTF8</li>
|
||||
* <li>APPLICATION/JSON</li>
|
||||
* </ul>
|
||||
* @param {String} contentType The MIME content type to check.
|
||||
* @returns {Boolean} <code>true</code> if <code>contentType</code> represents JSON, otherwise <code>false</code>.
|
||||
*/
|
||||
isJsonMime (contentType) {
|
||||
return Boolean(
|
||||
contentType != null && contentType.match(/^application\/json(;.*)?$/i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first.
|
||||
* @param {Array.<String>} contentTypes
|
||||
* @returns {String} The chosen content type, preferring JSON.
|
||||
*/
|
||||
jsonPreferredMime (contentTypes) {
|
||||
for (var i = 0; i < contentTypes.length; i++) {
|
||||
if (this.isJsonMime(contentTypes[i])) {
|
||||
return contentTypes[i]
|
||||
}
|
||||
}
|
||||
|
||||
return contentTypes[0]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JDCloud.JCRequest
|
||||
231
packages/libs/lib-jdcloud/src/lib/service.js
Normal file
231
packages/libs/lib-jdcloud/src/lib/service.js
Normal file
@@ -0,0 +1,231 @@
|
||||
var JDCloud = require('./core')
|
||||
var SignerV2 = require('./signers/v2')
|
||||
|
||||
JDCloud.Service = class Service {
|
||||
constructor (serviceId, config = {}) {
|
||||
this.serviceId = serviceId
|
||||
this.init(config)
|
||||
}
|
||||
|
||||
init (config) {
|
||||
// 某个服务类型的全局配置
|
||||
var serviceConfig = JDCloud.config[this.serviceId]
|
||||
// 全局配置
|
||||
this.config = new JDCloud.Config(JDCloud.config)
|
||||
if (serviceConfig) {
|
||||
this.config.update(serviceConfig, true)
|
||||
}
|
||||
if (config) {
|
||||
if (!this.config.endpoint.host && !config.endpoint) {
|
||||
config.endpoint = config._defaultEndpoint
|
||||
}
|
||||
delete config._defaultEndpoint
|
||||
this.config.update(config, true)
|
||||
}
|
||||
}
|
||||
|
||||
makeRequest (
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
) {
|
||||
var request = new JDCloud.JCRequest(
|
||||
this,
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType
|
||||
)
|
||||
|
||||
var signer = new SignerV2(request, this.serviceId)
|
||||
|
||||
return this.config.getCredentials().then(() => {
|
||||
signer.addAuthorization(this.config.credentials)
|
||||
return JDCloud.fetch(signer.request.request).then(response => {
|
||||
return response.json().then(
|
||||
result => {
|
||||
result.responseObj = response
|
||||
if (response.ok) {
|
||||
return result
|
||||
}
|
||||
return Promise.reject(result)
|
||||
},
|
||||
error => {
|
||||
error.responseObj = response
|
||||
if (error.type === 'invalid-json') {
|
||||
// oss没有返回json
|
||||
if (response.ok) {
|
||||
return Promise.resolve({
|
||||
requestId: response.headers.get('x-jdcloud-request-id') || ''
|
||||
})
|
||||
} else {
|
||||
/* eslint-disable */
|
||||
return Promise.reject({
|
||||
requestId: response.headers.get('x-jdcloud-request-id') || ''
|
||||
})
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
throw error
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
buildCollectionParam (param, collectionFormat) {
|
||||
if (param === null || param === undefined) {
|
||||
return param
|
||||
}
|
||||
switch (collectionFormat) {
|
||||
case 'csv':
|
||||
return param.map(this.paramToString).join(',')
|
||||
case 'ssv':
|
||||
return param.map(this.paramToString).join(' ')
|
||||
case 'tsv':
|
||||
return param.map(this.paramToString).join('\t')
|
||||
case 'pipes':
|
||||
return param.map(this.paramToString).join('|')
|
||||
case 'multi':
|
||||
// return the array directly as SuperAgent will handle it as expected
|
||||
return param.map(this.paramToString)
|
||||
default:
|
||||
throw new Error('Unknown collection format: ' + collectionFormat)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter is a special type of array
|
||||
* only contains:
|
||||
* [
|
||||
* { name: someString , values:[ someString, someString ] ,operator: someString}
|
||||
* ]
|
||||
*
|
||||
*/
|
||||
buildFilterParam (param, key) {
|
||||
var result = {}
|
||||
if (Array.isArray(param)) {
|
||||
let index = 0
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
// 兼容空字符串
|
||||
if (obj.values !== '' && !Array.isArray(obj.values)) {
|
||||
throw new Error('The type of filters.values should be Array!')
|
||||
}
|
||||
if (obj.name && obj.values) {
|
||||
if (!obj.values.length) continue
|
||||
result[`${key}.${index + 1}.name`] = obj.name
|
||||
for (var j = 0; j < obj.values.length; j++) {
|
||||
var someString = obj.values[j]
|
||||
result[`${key}.${index + 1}.values.${j + 1}`] = someString
|
||||
}
|
||||
if (obj.operator) {
|
||||
result[`${key}.${index + 1}.operator`] = obj.operator
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildTagFilterParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
if (obj.values && !Array.isArray(obj.values)) {
|
||||
throw new Error(
|
||||
`The type of param 'param[${i}].values' should be Array or NULL!`
|
||||
)
|
||||
}
|
||||
|
||||
if (obj.key) {
|
||||
result[`${key}.${i + 1}.key`] = obj.key
|
||||
|
||||
if (obj.values) {
|
||||
for (var j = 0; j < obj.values.length; j++) {
|
||||
var someString = obj.values[j]
|
||||
result[`${key}.${i + 1}.values.${j + 1}`] = someString
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildSortParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
if (obj.name && obj.direction) {
|
||||
index++
|
||||
result[`${key}.${index}.name`] = obj.name
|
||||
result[`${key}.${index}.direction`] = obj.direction
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// arr=[a,b,c] => arr={arr1:a, arr2:b, arr3:c}
|
||||
buildArrayParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var value = param[i]
|
||||
result[`${key}.${i + 1}`] = value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation for an actual parameter.
|
||||
* @param param The actual parameter.
|
||||
* @returns {String} The string representation of <code>param</code>.
|
||||
*/
|
||||
paramToString (param) {
|
||||
if (param === undefined || param === null) {
|
||||
return ''
|
||||
}
|
||||
if (param instanceof Date) {
|
||||
return param.toJSON()
|
||||
}
|
||||
|
||||
return param.toString()
|
||||
}
|
||||
|
||||
static hasService (id) {
|
||||
return JDCloud.Service._services.hasOwnProperty(id)
|
||||
}
|
||||
}
|
||||
JDCloud.Service._services = {}
|
||||
|
||||
module.exports = JDCloud.Service
|
||||
13
packages/libs/lib-jdcloud/src/lib/signers/request_signer.js
Normal file
13
packages/libs/lib-jdcloud/src/lib/signers/request_signer.js
Normal file
@@ -0,0 +1,13 @@
|
||||
module.exports = class RequestSigner {
|
||||
constructor (request) {
|
||||
this.request = request
|
||||
}
|
||||
|
||||
setServiceClientId (id) {
|
||||
this.serviceClientId = id
|
||||
}
|
||||
|
||||
getServiceClientId () {
|
||||
return this.serviceClientId
|
||||
}
|
||||
}
|
||||
190
packages/libs/lib-jdcloud/src/lib/signers/v2.js
Normal file
190
packages/libs/lib-jdcloud/src/lib/signers/v2.js
Normal file
@@ -0,0 +1,190 @@
|
||||
// Copyright 2018 JDCLOUD.COM
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
// This signer is modified from AWS V4 signer algorithm.
|
||||
|
||||
var util = require('../util')
|
||||
var RequestSigner = require('./request_signer')
|
||||
var v2Credentials = require('./v2_credentials')
|
||||
var uuid = require('uuid')
|
||||
var JDCloud = require('../core')
|
||||
|
||||
module.exports = class SignerV2 extends RequestSigner {
|
||||
constructor (request, serviceName, options = {}) {
|
||||
super(request)
|
||||
this.signatureCache = true
|
||||
this.algorithm = 'JDCLOUD2-HMAC-SHA256'
|
||||
this.unsignableHeaders = ['authorization', 'user-agent']
|
||||
this.serviceName = serviceName
|
||||
// this.signatureCache = typeof options.signatureCache === 'boolean' ? options.signatureCache : true;
|
||||
}
|
||||
|
||||
// 签名流程见 https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
|
||||
|
||||
addAuthorization (credentials, date) {
|
||||
// var datetime = '20180119T070300Z';
|
||||
var datetime = util.date.iso8601(date).replace(/[:-]|\.\d{3}/g, '')
|
||||
this.addHeaders(credentials, datetime)
|
||||
this.request.request.headers.set(
|
||||
'Authorization',
|
||||
this.authorization(credentials, datetime)
|
||||
)
|
||||
}
|
||||
|
||||
addHeaders (credentials, datetime) {
|
||||
this.request.request.headers.set('x-jdcloud-date', datetime)
|
||||
this.request.request.headers.set('x-jdcloud-nonce', uuid.v4())
|
||||
this.request.request.headers.set(
|
||||
'host',
|
||||
this.request.service.config.endpoint.host
|
||||
)
|
||||
}
|
||||
|
||||
signedHeaders () {
|
||||
var keys = []
|
||||
this.request.request.headers.forEach((value, key) => {
|
||||
key = key.toLowerCase()
|
||||
if (this.isSignableHeader(key)) {
|
||||
keys.push(key)
|
||||
}
|
||||
})
|
||||
/* util.each.call(this, this.request.headers, function (key) {
|
||||
|
||||
}); */
|
||||
return keys.sort().join(';')
|
||||
}
|
||||
|
||||
credentialString (datetime) {
|
||||
return v2Credentials.createScope(
|
||||
datetime.substr(0, 8),
|
||||
this.request.regionId,
|
||||
this.serviceName
|
||||
)
|
||||
}
|
||||
|
||||
signature (credentials, datetime) {
|
||||
var signingKey = v2Credentials.getSigningKey(
|
||||
credentials,
|
||||
datetime.substr(0, 8),
|
||||
this.request.regionId,
|
||||
this.serviceName,
|
||||
this.signatureCache
|
||||
)
|
||||
return util.crypto.hmac(signingKey, this.stringToSign(datetime), 'hex')
|
||||
}
|
||||
|
||||
stringToSign (datetime) {
|
||||
var parts = []
|
||||
parts.push(this.algorithm)
|
||||
parts.push(datetime)
|
||||
parts.push(this.credentialString(datetime))
|
||||
parts.push(this.hexEncodedHash(this.canonicalString()))
|
||||
JDCloud.config.logger('StringToSign is \n' + JSON.stringify(parts), 'DEBUG')
|
||||
return parts.join('\n')
|
||||
}
|
||||
|
||||
// 构建标准签名字符串
|
||||
canonicalString () {
|
||||
var parts = []
|
||||
var pathname = this.request.path
|
||||
// if (this.serviceName !== 'jfs') {
|
||||
// pathname = util.uriEscapePath(pathname)
|
||||
// }
|
||||
|
||||
parts.push(this.request.request.method)
|
||||
parts.push(pathname)
|
||||
parts.push(this.request.search())
|
||||
parts.push(this.canonicalHeaders() + '\n')
|
||||
parts.push(this.signedHeaders())
|
||||
parts.push(this.hexEncodedBodyHash())
|
||||
JDCloud.config.logger(
|
||||
'canonicalString is \n' + JSON.stringify(parts),
|
||||
'DEBUG'
|
||||
)
|
||||
return parts.join('\n')
|
||||
}
|
||||
|
||||
canonicalHeaders () {
|
||||
var headers = []
|
||||
this.request.request.headers.forEach((value, key) => {
|
||||
headers.push([key, value])
|
||||
})
|
||||
headers.sort(function (a, b) {
|
||||
return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : 1
|
||||
})
|
||||
var parts = []
|
||||
util.arrayEach.call(this, headers, function (item) {
|
||||
var key = item[0].toLowerCase()
|
||||
if (this.isSignableHeader(key)) {
|
||||
var value = item[1]
|
||||
if (
|
||||
typeof value === 'undefined' ||
|
||||
value === null ||
|
||||
typeof value.toString !== 'function'
|
||||
) {
|
||||
throw util.error(
|
||||
new Error('Header ' + key + ' contains invalid value'),
|
||||
{
|
||||
code: 'InvalidHeader'
|
||||
}
|
||||
)
|
||||
}
|
||||
parts.push(key + ':' + this.canonicalHeaderValues(value.toString()))
|
||||
}
|
||||
})
|
||||
return parts.join('\n')
|
||||
}
|
||||
|
||||
canonicalHeaderValues (values) {
|
||||
return values.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
authorization (credentials, datetime) {
|
||||
var parts = []
|
||||
var credString = this.credentialString(datetime)
|
||||
parts.push(
|
||||
this.algorithm +
|
||||
' Credential=' +
|
||||
credentials.accessKeyId +
|
||||
'/' +
|
||||
credString
|
||||
)
|
||||
parts.push('SignedHeaders=' + this.signedHeaders())
|
||||
parts.push('Signature=' + this.signature(credentials, datetime))
|
||||
JDCloud.config.logger('Signature is \n' + JSON.stringify(parts), 'DEBUG')
|
||||
return parts.join(', ')
|
||||
}
|
||||
|
||||
hexEncodedHash (string) {
|
||||
return util.crypto.sha256(string, 'hex')
|
||||
}
|
||||
|
||||
hexEncodedBodyHash () {
|
||||
return this.hexEncodedHash(this.request.request.body || '')
|
||||
/* var request = this.request;
|
||||
if (this.isPresigned() && this.serviceName === 's3' && !request.body) {
|
||||
return 'UNSIGNED-PAYLOAD';
|
||||
} else if (request.headers['X-Amz-Content-Sha256']) {
|
||||
return request.headers['X-Amz-Content-Sha256'];
|
||||
} else {
|
||||
return this.hexEncodedHash(this.request.body || '');
|
||||
} */
|
||||
}
|
||||
|
||||
isSignableHeader (key) {
|
||||
if (key.toLowerCase().includes('x-jdcloud-')) {
|
||||
return true
|
||||
}
|
||||
return !this.unsignableHeaders.includes(key.toLowerCase())
|
||||
}
|
||||
}
|
||||
80
packages/libs/lib-jdcloud/src/lib/signers/v2_credentials.js
Normal file
80
packages/libs/lib-jdcloud/src/lib/signers/v2_credentials.js
Normal file
@@ -0,0 +1,80 @@
|
||||
var cachedSecret = {}
|
||||
var cacheQueue = []
|
||||
var maxCacheEntries = 50
|
||||
var v2Identifier = 'jdcloud2_request'
|
||||
|
||||
var util = require('../util')
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* @param date [String]
|
||||
* @param region [String]
|
||||
* @param serviceName [String]
|
||||
* @return [String]
|
||||
*/
|
||||
createScope: function createScope (date, region, serviceName) {
|
||||
return [date.substr(0, 8), region, serviceName, v2Identifier].join('/')
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* @param credentials [Credentials]
|
||||
* @param date [String]
|
||||
* @param region [String]
|
||||
* @param service [String]
|
||||
* @param shouldCache [Boolean]
|
||||
* @return [String]
|
||||
*/
|
||||
getSigningKey: function getSigningKey (
|
||||
credentials,
|
||||
date,
|
||||
region,
|
||||
service,
|
||||
shouldCache
|
||||
) {
|
||||
var credsIdentifier = util.crypto.hmac(
|
||||
credentials.secretAccessKey,
|
||||
credentials.accessKeyId,
|
||||
'base64'
|
||||
)
|
||||
var cacheKey = [credsIdentifier, date, region, service].join('_')
|
||||
shouldCache = shouldCache !== false
|
||||
if (shouldCache && cacheKey in cachedSecret) {
|
||||
return cachedSecret[cacheKey]
|
||||
}
|
||||
|
||||
var kDate = util.crypto.hmac(
|
||||
'JDCLOUD2' + credentials.secretAccessKey,
|
||||
date,
|
||||
'buffer'
|
||||
)
|
||||
var kRegion = util.crypto.hmac(kDate, region, 'buffer')
|
||||
var kService = util.crypto.hmac(kRegion, service, 'buffer')
|
||||
|
||||
var signingKey = util.crypto.hmac(kService, v2Identifier, 'buffer')
|
||||
if (shouldCache) {
|
||||
cachedSecret[cacheKey] = signingKey
|
||||
cacheQueue.push(cacheKey)
|
||||
if (cacheQueue.length > maxCacheEntries) {
|
||||
// remove the oldest entry (not the least recently used)
|
||||
delete cachedSecret[cacheQueue.shift()]
|
||||
}
|
||||
}
|
||||
|
||||
return signingKey
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* Empties the derived signing key cache. Made available for testing purposes
|
||||
* only.
|
||||
*/
|
||||
emptyCache: function emptyCache () {
|
||||
cachedSecret = {}
|
||||
cacheQueue = []
|
||||
}
|
||||
}
|
||||
477
packages/libs/lib-jdcloud/src/lib/util.js
Normal file
477
packages/libs/lib-jdcloud/src/lib/util.js
Normal file
@@ -0,0 +1,477 @@
|
||||
var util = {
|
||||
isBrowser: function isBrowser () {
|
||||
return process && process.browser
|
||||
},
|
||||
isNode: function isNode () {
|
||||
return !util.isBrowser()
|
||||
},
|
||||
uriEscape: function uriEscape (string) {
|
||||
var output = encodeURIComponent(string)
|
||||
output = output.replace(/[^A-Za-z0-9_.~\-%]+/g, escape)
|
||||
|
||||
// AWS percent-encodes some extra non-standard characters in a URI
|
||||
output = output.replace(/[*]/g, function (ch) {
|
||||
return (
|
||||
'%' +
|
||||
ch
|
||||
.charCodeAt(0)
|
||||
.toString(16)
|
||||
.toUpperCase()
|
||||
)
|
||||
})
|
||||
|
||||
return output
|
||||
},
|
||||
uriEscapePath: function uriEscapePath (string) {
|
||||
var parts = []
|
||||
util.arrayEach(string.split('/'), function (part) {
|
||||
parts.push(util.uriEscape(part))
|
||||
})
|
||||
return parts.join('/')
|
||||
},
|
||||
abort: {},
|
||||
each: function each (object, iterFunction) {
|
||||
for (var key in object) {
|
||||
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
||||
var ret = iterFunction.call(this, key, object[key])
|
||||
if (ret === util.abort) break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
arrayEach: function arrayEach (array, iterFunction) {
|
||||
for (var idx in array) {
|
||||
if (Object.prototype.hasOwnProperty.call(array, idx)) {
|
||||
var ret = iterFunction.call(this, array[idx], parseInt(idx, 10))
|
||||
if (ret === util.abort) break
|
||||
}
|
||||
}
|
||||
},
|
||||
arraySliceFn: function arraySliceFn (obj) {
|
||||
var fn = obj.slice || obj.webkitSlice || obj.mozSlice
|
||||
return typeof fn === 'function' ? fn : null
|
||||
},
|
||||
queryParamsToString: function queryParamsToString (params) {
|
||||
var items = []
|
||||
var escape = util.uriEscape
|
||||
var sortedKeys = Object.keys(params).sort()
|
||||
|
||||
util.arrayEach(sortedKeys, function (name) {
|
||||
var value = params[name]
|
||||
var ename = escape(name)
|
||||
var result = ename + '='
|
||||
if (Array.isArray(value)) {
|
||||
var vals = []
|
||||
util.arrayEach(value, function (item) {
|
||||
vals.push(escape(item))
|
||||
})
|
||||
result = ename + '=' + vals.sort().join('&' + ename + '=')
|
||||
} else if (value !== undefined && value !== null) {
|
||||
result = ename + '=' + escape(value)
|
||||
}
|
||||
items.push(result)
|
||||
})
|
||||
|
||||
return items.join('&')
|
||||
},
|
||||
date: {
|
||||
getDate () {
|
||||
return new Date()
|
||||
},
|
||||
iso8601: function iso8601 (date) {
|
||||
if (date === undefined) {
|
||||
date = util.date.getDate()
|
||||
}
|
||||
return date.toISOString().replace(/\.\d{3}Z$/, 'Z')
|
||||
}
|
||||
},
|
||||
crypto: {
|
||||
/* eslint-disable no-use-before-define */
|
||||
crc32Table: [
|
||||
0x00000000,
|
||||
0x77073096,
|
||||
0xee0e612c,
|
||||
0x990951ba,
|
||||
0x076dc419,
|
||||
0x706af48f,
|
||||
0xe963a535,
|
||||
0x9e6495a3,
|
||||
0x0edb8832,
|
||||
0x79dcb8a4,
|
||||
0xe0d5e91e,
|
||||
0x97d2d988,
|
||||
0x09b64c2b,
|
||||
0x7eb17cbd,
|
||||
0xe7b82d07,
|
||||
0x90bf1d91,
|
||||
0x1db71064,
|
||||
0x6ab020f2,
|
||||
0xf3b97148,
|
||||
0x84be41de,
|
||||
0x1adad47d,
|
||||
0x6ddde4eb,
|
||||
0xf4d4b551,
|
||||
0x83d385c7,
|
||||
0x136c9856,
|
||||
0x646ba8c0,
|
||||
0xfd62f97a,
|
||||
0x8a65c9ec,
|
||||
0x14015c4f,
|
||||
0x63066cd9,
|
||||
0xfa0f3d63,
|
||||
0x8d080df5,
|
||||
0x3b6e20c8,
|
||||
0x4c69105e,
|
||||
0xd56041e4,
|
||||
0xa2677172,
|
||||
0x3c03e4d1,
|
||||
0x4b04d447,
|
||||
0xd20d85fd,
|
||||
0xa50ab56b,
|
||||
0x35b5a8fa,
|
||||
0x42b2986c,
|
||||
0xdbbbc9d6,
|
||||
0xacbcf940,
|
||||
0x32d86ce3,
|
||||
0x45df5c75,
|
||||
0xdcd60dcf,
|
||||
0xabd13d59,
|
||||
0x26d930ac,
|
||||
0x51de003a,
|
||||
0xc8d75180,
|
||||
0xbfd06116,
|
||||
0x21b4f4b5,
|
||||
0x56b3c423,
|
||||
0xcfba9599,
|
||||
0xb8bda50f,
|
||||
0x2802b89e,
|
||||
0x5f058808,
|
||||
0xc60cd9b2,
|
||||
0xb10be924,
|
||||
0x2f6f7c87,
|
||||
0x58684c11,
|
||||
0xc1611dab,
|
||||
0xb6662d3d,
|
||||
0x76dc4190,
|
||||
0x01db7106,
|
||||
0x98d220bc,
|
||||
0xefd5102a,
|
||||
0x71b18589,
|
||||
0x06b6b51f,
|
||||
0x9fbfe4a5,
|
||||
0xe8b8d433,
|
||||
0x7807c9a2,
|
||||
0x0f00f934,
|
||||
0x9609a88e,
|
||||
0xe10e9818,
|
||||
0x7f6a0dbb,
|
||||
0x086d3d2d,
|
||||
0x91646c97,
|
||||
0xe6635c01,
|
||||
0x6b6b51f4,
|
||||
0x1c6c6162,
|
||||
0x856530d8,
|
||||
0xf262004e,
|
||||
0x6c0695ed,
|
||||
0x1b01a57b,
|
||||
0x8208f4c1,
|
||||
0xf50fc457,
|
||||
0x65b0d9c6,
|
||||
0x12b7e950,
|
||||
0x8bbeb8ea,
|
||||
0xfcb9887c,
|
||||
0x62dd1ddf,
|
||||
0x15da2d49,
|
||||
0x8cd37cf3,
|
||||
0xfbd44c65,
|
||||
0x4db26158,
|
||||
0x3ab551ce,
|
||||
0xa3bc0074,
|
||||
0xd4bb30e2,
|
||||
0x4adfa541,
|
||||
0x3dd895d7,
|
||||
0xa4d1c46d,
|
||||
0xd3d6f4fb,
|
||||
0x4369e96a,
|
||||
0x346ed9fc,
|
||||
0xad678846,
|
||||
0xda60b8d0,
|
||||
0x44042d73,
|
||||
0x33031de5,
|
||||
0xaa0a4c5f,
|
||||
0xdd0d7cc9,
|
||||
0x5005713c,
|
||||
0x270241aa,
|
||||
0xbe0b1010,
|
||||
0xc90c2086,
|
||||
0x5768b525,
|
||||
0x206f85b3,
|
||||
0xb966d409,
|
||||
0xce61e49f,
|
||||
0x5edef90e,
|
||||
0x29d9c998,
|
||||
0xb0d09822,
|
||||
0xc7d7a8b4,
|
||||
0x59b33d17,
|
||||
0x2eb40d81,
|
||||
0xb7bd5c3b,
|
||||
0xc0ba6cad,
|
||||
0xedb88320,
|
||||
0x9abfb3b6,
|
||||
0x03b6e20c,
|
||||
0x74b1d29a,
|
||||
0xead54739,
|
||||
0x9dd277af,
|
||||
0x04db2615,
|
||||
0x73dc1683,
|
||||
0xe3630b12,
|
||||
0x94643b84,
|
||||
0x0d6d6a3e,
|
||||
0x7a6a5aa8,
|
||||
0xe40ecf0b,
|
||||
0x9309ff9d,
|
||||
0x0a00ae27,
|
||||
0x7d079eb1,
|
||||
0xf00f9344,
|
||||
0x8708a3d2,
|
||||
0x1e01f268,
|
||||
0x6906c2fe,
|
||||
0xf762575d,
|
||||
0x806567cb,
|
||||
0x196c3671,
|
||||
0x6e6b06e7,
|
||||
0xfed41b76,
|
||||
0x89d32be0,
|
||||
0x10da7a5a,
|
||||
0x67dd4acc,
|
||||
0xf9b9df6f,
|
||||
0x8ebeeff9,
|
||||
0x17b7be43,
|
||||
0x60b08ed5,
|
||||
0xd6d6a3e8,
|
||||
0xa1d1937e,
|
||||
0x38d8c2c4,
|
||||
0x4fdff252,
|
||||
0xd1bb67f1,
|
||||
0xa6bc5767,
|
||||
0x3fb506dd,
|
||||
0x48b2364b,
|
||||
0xd80d2bda,
|
||||
0xaf0a1b4c,
|
||||
0x36034af6,
|
||||
0x41047a60,
|
||||
0xdf60efc3,
|
||||
0xa867df55,
|
||||
0x316e8eef,
|
||||
0x4669be79,
|
||||
0xcb61b38c,
|
||||
0xbc66831a,
|
||||
0x256fd2a0,
|
||||
0x5268e236,
|
||||
0xcc0c7795,
|
||||
0xbb0b4703,
|
||||
0x220216b9,
|
||||
0x5505262f,
|
||||
0xc5ba3bbe,
|
||||
0xb2bd0b28,
|
||||
0x2bb45a92,
|
||||
0x5cb36a04,
|
||||
0xc2d7ffa7,
|
||||
0xb5d0cf31,
|
||||
0x2cd99e8b,
|
||||
0x5bdeae1d,
|
||||
0x9b64c2b0,
|
||||
0xec63f226,
|
||||
0x756aa39c,
|
||||
0x026d930a,
|
||||
0x9c0906a9,
|
||||
0xeb0e363f,
|
||||
0x72076785,
|
||||
0x05005713,
|
||||
0x95bf4a82,
|
||||
0xe2b87a14,
|
||||
0x7bb12bae,
|
||||
0x0cb61b38,
|
||||
0x92d28e9b,
|
||||
0xe5d5be0d,
|
||||
0x7cdcefb7,
|
||||
0x0bdbdf21,
|
||||
0x86d3d2d4,
|
||||
0xf1d4e242,
|
||||
0x68ddb3f8,
|
||||
0x1fda836e,
|
||||
0x81be16cd,
|
||||
0xf6b9265b,
|
||||
0x6fb077e1,
|
||||
0x18b74777,
|
||||
0x88085ae6,
|
||||
0xff0f6a70,
|
||||
0x66063bca,
|
||||
0x11010b5c,
|
||||
0x8f659eff,
|
||||
0xf862ae69,
|
||||
0x616bffd3,
|
||||
0x166ccf45,
|
||||
0xa00ae278,
|
||||
0xd70dd2ee,
|
||||
0x4e048354,
|
||||
0x3903b3c2,
|
||||
0xa7672661,
|
||||
0xd06016f7,
|
||||
0x4969474d,
|
||||
0x3e6e77db,
|
||||
0xaed16a4a,
|
||||
0xd9d65adc,
|
||||
0x40df0b66,
|
||||
0x37d83bf0,
|
||||
0xa9bcae53,
|
||||
0xdebb9ec5,
|
||||
0x47b2cf7f,
|
||||
0x30b5ffe9,
|
||||
0xbdbdf21c,
|
||||
0xcabac28a,
|
||||
0x53b39330,
|
||||
0x24b4a3a6,
|
||||
0xbad03605,
|
||||
0xcdd70693,
|
||||
0x54de5729,
|
||||
0x23d967bf,
|
||||
0xb3667a2e,
|
||||
0xc4614ab8,
|
||||
0x5d681b02,
|
||||
0x2a6f2b94,
|
||||
0xb40bbe37,
|
||||
0xc30c8ea1,
|
||||
0x5a05df1b,
|
||||
0x2d02ef8d
|
||||
],
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
crc32: function crc32 (data) {
|
||||
var tbl = util.crypto.crc32Table
|
||||
var crc = 0 ^ -1
|
||||
|
||||
if (typeof data === 'string') {
|
||||
data = new util.Buffer(data)
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var code = data.readUInt8(i)
|
||||
crc = (crc >>> 8) ^ tbl[(crc ^ code) & 0xff]
|
||||
}
|
||||
return (crc ^ -1) >>> 0
|
||||
},
|
||||
|
||||
hmac: function hmac (key, string, digest, fn) {
|
||||
if (!digest) digest = 'binary'
|
||||
if (digest === 'buffer') {
|
||||
digest = undefined
|
||||
}
|
||||
if (!fn) fn = 'sha256'
|
||||
if (typeof string === 'string') string = new util.Buffer(string)
|
||||
return util.crypto.lib
|
||||
.createHmac(fn, key)
|
||||
.update(string)
|
||||
.digest(digest)
|
||||
},
|
||||
|
||||
md5: function md5 (data, digest, callback) {
|
||||
return util.crypto.hash('md5', data, digest, callback)
|
||||
},
|
||||
|
||||
sha256: function sha256 (data, digest, callback) {
|
||||
return util.crypto.hash('sha256', data, digest, callback)
|
||||
},
|
||||
|
||||
hash: function (algorithm, data, digest, callback) {
|
||||
var hash = util.crypto.createHash(algorithm)
|
||||
if (!digest) {
|
||||
digest = 'binary'
|
||||
}
|
||||
if (digest === 'buffer') {
|
||||
digest = undefined
|
||||
}
|
||||
if (typeof data === 'string') data = new util.Buffer(data)
|
||||
var sliceFn = util.arraySliceFn(data)
|
||||
var isBuffer = util.Buffer.isBuffer(data)
|
||||
// Identifying objects with an ArrayBuffer as buffers
|
||||
if (
|
||||
util.isBrowser() &&
|
||||
typeof ArrayBuffer !== 'undefined' &&
|
||||
data &&
|
||||
data.buffer instanceof ArrayBuffer
|
||||
) {
|
||||
isBuffer = true
|
||||
}
|
||||
|
||||
if (
|
||||
callback &&
|
||||
typeof data === 'object' &&
|
||||
typeof data.on === 'function' &&
|
||||
!isBuffer
|
||||
) {
|
||||
data.on('data', function (chunk) {
|
||||
hash.update(chunk)
|
||||
})
|
||||
data.on('error', function (err) {
|
||||
callback(err)
|
||||
})
|
||||
data.on('end', function () {
|
||||
callback(null, hash.digest(digest))
|
||||
})
|
||||
} else if (
|
||||
callback &&
|
||||
sliceFn &&
|
||||
!isBuffer &&
|
||||
typeof FileReader !== 'undefined'
|
||||
) {
|
||||
// this might be a File/Blob
|
||||
var index = 0
|
||||
var size = 1024 * 512
|
||||
var reader = new FileReader()
|
||||
reader.onerror = function () {
|
||||
callback(new Error('Failed to read data.'))
|
||||
}
|
||||
reader.onload = function () {
|
||||
var buf = new util.Buffer(new Uint8Array(reader.result))
|
||||
hash.update(buf)
|
||||
index += buf.length
|
||||
reader._continueReading()
|
||||
}
|
||||
reader._continueReading = function () {
|
||||
if (index >= data.size) {
|
||||
callback(null, hash.digest(digest))
|
||||
return
|
||||
}
|
||||
|
||||
var back = index + size
|
||||
if (back > data.size) back = data.size
|
||||
reader.readAsArrayBuffer(sliceFn.call(data, index, back))
|
||||
}
|
||||
|
||||
reader._continueReading()
|
||||
} else {
|
||||
if (util.isBrowser() && typeof data === 'object' && !isBuffer) {
|
||||
data = new util.Buffer(new Uint8Array(data))
|
||||
}
|
||||
var out = hash.update(data).digest(digest)
|
||||
if (callback) callback(null, out)
|
||||
return out
|
||||
}
|
||||
},
|
||||
|
||||
toHex: function toHex (data) {
|
||||
var out = []
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
out.push(('0' + data.charCodeAt(i).toString(16)).substr(-2, 2))
|
||||
}
|
||||
return out.join('')
|
||||
},
|
||||
|
||||
createHash: function createHash (algorithm) {
|
||||
return util.crypto.lib.createHash(algorithm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = util
|
||||
4150
packages/libs/lib-jdcloud/src/repo/ag/v1/ag.js
Normal file
4150
packages/libs/lib-jdcloud/src/repo/ag/v1/ag.js
Normal file
File diff suppressed because it is too large
Load Diff
261
packages/libs/lib-jdcloud/src/repo/ams/v1/ams.js
Normal file
261
packages/libs/lib-jdcloud/src/repo/ams/v1/ams.js
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright 2018 JDCLOUD.COM
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http:#www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* 应用管理平台API (仅对授权用户使用)
|
||||
* 应用管理平台API
|
||||
*
|
||||
* OpenAPI spec version: v1
|
||||
* Contact:
|
||||
*
|
||||
* NOTE: This class is auto generated by the jdcloud code generator program.
|
||||
*/
|
||||
|
||||
require('../../../lib/node_loader')
|
||||
var JDCloud = require('../../../lib/core')
|
||||
var Service = JDCloud.Service
|
||||
var serviceId = 'ams'
|
||||
Service._services[serviceId] = true
|
||||
|
||||
/**
|
||||
* ams service.
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
JDCloud.AMS = class AMS extends Service {
|
||||
constructor (options = {}) {
|
||||
options._defaultEndpoint = {}
|
||||
options._defaultEndpoint.protocol =
|
||||
options._defaultEndpoint.protocol || 'https'
|
||||
options._defaultEndpoint.host =
|
||||
options._defaultEndpoint.host || 'ams.jdcloud-api.com'
|
||||
options.basePath = '/v1' // 默认要设为空""
|
||||
super(serviceId, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收流基础数据查询
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} opts.streamId - 流ID
|
||||
* @param {string} [opts.startTime] - 起始时间 optional
|
||||
* @param {string} [opts.endTime] - 结束时间 optional
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param streamInputData streamInputDatas
|
||||
*/
|
||||
|
||||
describeStreamsInput (opts, callback) {
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.streamId === undefined || opts.streamId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.streamId' when calling describeStreamsInput"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = null
|
||||
let queryParams = {}
|
||||
if (opts.startTime !== undefined && opts.startTime !== null) {
|
||||
queryParams['startTime'] = opts.startTime
|
||||
}
|
||||
if (opts.endTime !== undefined && opts.endTime !== null) {
|
||||
queryParams['endTime'] = opts.endTime
|
||||
}
|
||||
|
||||
let pathParams = {
|
||||
regionId: 'jdcloud',
|
||||
streamId: opts.streamId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 ams/1.0.0'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeStreamsInput with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = this.makeRequest(
|
||||
'/streams/{streamId}/inputs',
|
||||
'GET',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端鉴权查询
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} opts.pId - PinId
|
||||
* @param {integer} [opts.ver] - 版本 optional
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param string pId PinId
|
||||
* @param integer ver 版本
|
||||
* @param number blacklist 集合
|
||||
* @param integer status 状态
|
||||
* @param string license 授权号
|
||||
*/
|
||||
|
||||
describeAuthenticate (opts, callback) {
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.pId === undefined || opts.pId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.pId' when calling describeAuthenticate"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = null
|
||||
let queryParams = {}
|
||||
if (opts.ver !== undefined && opts.ver !== null) {
|
||||
queryParams['ver'] = opts.ver
|
||||
}
|
||||
|
||||
let pathParams = {
|
||||
regionId: 'jdcloud',
|
||||
pId: opts.pId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 ams/1.0.0'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeAuthenticate with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = this.makeRequest(
|
||||
'/appManager/{pId}/authenticates',
|
||||
'GET',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
module.exports = JDCloud.AMS
|
||||
5241
packages/libs/lib-jdcloud/src/repo/antipro/v1/antipro.js
Normal file
5241
packages/libs/lib-jdcloud/src/repo/antipro/v1/antipro.js
Normal file
File diff suppressed because it is too large
Load Diff
9140
packages/libs/lib-jdcloud/src/repo/apigateway/v1/apigateway.js
Normal file
9140
packages/libs/lib-jdcloud/src/repo/apigateway/v1/apigateway.js
Normal file
File diff suppressed because it is too large
Load Diff
274
packages/libs/lib-jdcloud/src/repo/asset/v1/asset.js
Normal file
274
packages/libs/lib-jdcloud/src/repo/asset/v1/asset.js
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright 2018 JDCLOUD.COM
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http:#www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* JDCLOUD asset API
|
||||
* API JDCLOUD asset API
|
||||
*
|
||||
* OpenAPI spec version: v1
|
||||
* Contact:
|
||||
*
|
||||
* NOTE: This class is auto generated by the jdcloud code generator program.
|
||||
*/
|
||||
|
||||
require('../../../lib/node_loader')
|
||||
var JDCloud = require('../../../lib/core')
|
||||
var Service = JDCloud.Service
|
||||
var serviceId = 'asset'
|
||||
Service._services[serviceId] = true
|
||||
|
||||
/**
|
||||
* asset service.
|
||||
* @version 0.0.3
|
||||
*/
|
||||
|
||||
class ASSET extends Service {
|
||||
constructor (options = {}) {
|
||||
options._defaultEndpoint = {}
|
||||
options._defaultEndpoint.protocol =
|
||||
options._defaultEndpoint.protocol || 'https'
|
||||
options._defaultEndpoint.host =
|
||||
options._defaultEndpoint.host || 'asset.jdcloud-api.com'
|
||||
options.basePath = '/v1' // 默认要设为空""
|
||||
super(serviceId, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询账户金额(总金额、可用金额、冻结金额、可提现金额、提现中金额)
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param string totalAmount 总金额:可用金额+冻结金额
|
||||
* @param string availableAmount 可用金额
|
||||
* @param string frozenAmount 冻结金额:提现失败、处理中或预占中金额
|
||||
* @param string enableWithdrawAmount 可提现金额:排除对公充值金额总额后的充值总额,如果余额大于非对公充值总额,则为非对公充值总额,否则为余额(对公充值=企业线下汇款+企业充值+活动充值金额)
|
||||
* @param string withdrawingAmount 提现中金额:提现状态为处理中和预占中的金额
|
||||
*/
|
||||
|
||||
describeAccountAmount (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling describeAccountAmount"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
let postBody = null
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 asset/0.0.3'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeAccountAmount with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/assets:describeAccountAmount',
|
||||
'GET',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置余额预警信息
|
||||
* @param {Object} opts - parameters
|
||||
* @param {balanceWarningInfoVo} opts.balanceWarningInfoVo
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param boolean status
|
||||
*/
|
||||
|
||||
modifyBalanceWarningInfo (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling modifyBalanceWarningInfo"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (
|
||||
opts.balanceWarningInfoVo === undefined ||
|
||||
opts.balanceWarningInfoVo === null
|
||||
) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.balanceWarningInfoVo' when calling modifyBalanceWarningInfo"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = {}
|
||||
if (
|
||||
opts.balanceWarningInfoVo !== undefined &&
|
||||
opts.balanceWarningInfoVo !== null
|
||||
) {
|
||||
postBody['balanceWarningInfoVo'] = opts.balanceWarningInfoVo
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 asset/0.0.3'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call modifyBalanceWarningInfo with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/assets:modifyBalanceWarningInfo',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
module.exports = ASSET
|
||||
919
packages/libs/lib-jdcloud/src/repo/assistant/v1/assistant.js
Normal file
919
packages/libs/lib-jdcloud/src/repo/assistant/v1/assistant.js
Normal file
@@ -0,0 +1,919 @@
|
||||
/*
|
||||
* Copyright 2018 JDCLOUD.COM
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http:#www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* LogConfig
|
||||
* 用户日志相关配置
|
||||
*
|
||||
* OpenAPI spec version: v1
|
||||
* Contact:
|
||||
*
|
||||
* NOTE: This class is auto generated by the jdcloud code generator program.
|
||||
*/
|
||||
|
||||
require('../../../lib/node_loader')
|
||||
var JDCloud = require('../../../lib/core')
|
||||
var Service = JDCloud.Service
|
||||
var serviceId = 'assistant'
|
||||
Service._services[serviceId] = true
|
||||
|
||||
/**
|
||||
* assistant service.
|
||||
* @version 1.0.2
|
||||
*/
|
||||
|
||||
class ASSISTANT extends Service {
|
||||
constructor (options = {}) {
|
||||
options._defaultEndpoint = {}
|
||||
options._defaultEndpoint.protocol =
|
||||
options._defaultEndpoint.protocol || 'https'
|
||||
options._defaultEndpoint.host =
|
||||
options._defaultEndpoint.host || 'assistant.jdcloud-api.com'
|
||||
options.basePath = '/v1' // 默认要设为空""
|
||||
super(serviceId, options)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
保存用户自定义命令。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于保存用户自定义命令。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} opts.commandName - 命令名称,长度为1\~128个字符,只允许中文、数字、大小写字母、英文下划线(\_)、连字符(-)及点(.)。
|
||||
|
||||
* @param {string} [opts.commandType] - 命令类型,可选值:shell和powershell,默认shell
|
||||
optional
|
||||
* @param {string} opts.commandContent - 以base64编码的命令内容,编码后长度小于36KB
|
||||
|
||||
* @param {integer} [opts.timeout] - 超时时间,取值范围:[10, 86400], 超过该时间后,尚未执行完的命令会置为失败。默认60s
|
||||
optional
|
||||
* @param {string} [opts.username] - 用户名,执行该命令时的用户身份。在linux上默认是root,windows上默认是administrator。长度小于256
|
||||
optional
|
||||
* @param {string} [opts.workdir] - 命令执行路径。在linux上默认是/root,windows上默认是C:\Windows\System32。长度小于256。
|
||||
optional
|
||||
* @param {string} [opts.commandDescription] - 命令描述,描述该命令详细信息,如功能、使用注意事项等。长度小于256。
|
||||
optional
|
||||
* @param {boolean} [opts.enableParameter] - 是否使用参数, 默认false,不使用参数 optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param string commandId 命令Id。
|
||||
*/
|
||||
|
||||
createCommand (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling createCommand"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.commandName === undefined || opts.commandName === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.commandName' when calling createCommand"
|
||||
)
|
||||
}
|
||||
if (opts.commandContent === undefined || opts.commandContent === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.commandContent' when calling createCommand"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.commandName !== undefined && opts.commandName !== null) {
|
||||
postBody['commandName'] = opts.commandName
|
||||
}
|
||||
if (opts.commandType !== undefined && opts.commandType !== null) {
|
||||
postBody['commandType'] = opts.commandType
|
||||
}
|
||||
if (opts.commandContent !== undefined && opts.commandContent !== null) {
|
||||
postBody['commandContent'] = opts.commandContent
|
||||
}
|
||||
if (opts.timeout !== undefined && opts.timeout !== null) {
|
||||
postBody['timeout'] = opts.timeout
|
||||
}
|
||||
if (opts.username !== undefined && opts.username !== null) {
|
||||
postBody['username'] = opts.username
|
||||
}
|
||||
if (opts.workdir !== undefined && opts.workdir !== null) {
|
||||
postBody['workdir'] = opts.workdir
|
||||
}
|
||||
if (
|
||||
opts.commandDescription !== undefined &&
|
||||
opts.commandDescription !== null
|
||||
) {
|
||||
postBody['commandDescription'] = opts.commandDescription
|
||||
}
|
||||
if (opts.enableParameter !== undefined && opts.enableParameter !== null) {
|
||||
postBody['enableParameter'] = opts.enableParameter
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call createCommand with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/createCommand',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
查询用户自定义命令。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于查询用户保存的自定义命令。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {integer} [opts.pageNumber] - 页数,默认是第一页,取值为 1
|
||||
optional
|
||||
* @param {integer} [opts.pageSize] - 每页命令数,默认为20,最大为100
|
||||
optional
|
||||
* @param {array} [opts.commandIds] - 命令Id,最多可传入100个命令Id
|
||||
optional
|
||||
* @param {array} [opts.commandNames] - 命令名称,长度为1\~128个字符,只允许中文、数字、大小写字母、英文下划线(\_)、连字符(-)及点(.)。最多可传入100个命令名称。
|
||||
optional
|
||||
* @param {array} [opts.commandTypes] - 命令类型,可选值:shell和powershell,默认shell
|
||||
optional
|
||||
* @param {string} [opts.sourceType] - 命令来源,可选值:jdcloud(官方)和self,默认self
|
||||
optional
|
||||
* @param {array} [opts.usernames] - 用户名,执行该命令时的用户身份。在linux上默认是root,windows上默认是administrator。长度小于256
|
||||
optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param integer totalCount 总的命令数,可以根据该字段来决定是否继续查找
|
||||
* @param command commands
|
||||
*/
|
||||
|
||||
describeCommands (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling describeCommands"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
|
||||
postBody['pageNumber'] = opts.pageNumber
|
||||
}
|
||||
if (opts.pageSize !== undefined && opts.pageSize !== null) {
|
||||
postBody['pageSize'] = opts.pageSize
|
||||
}
|
||||
if (opts.commandIds !== undefined && opts.commandIds !== null) {
|
||||
postBody['commandIds'] = opts.commandIds
|
||||
}
|
||||
if (opts.commandNames !== undefined && opts.commandNames !== null) {
|
||||
postBody['commandNames'] = opts.commandNames
|
||||
}
|
||||
if (opts.commandTypes !== undefined && opts.commandTypes !== null) {
|
||||
postBody['commandTypes'] = opts.commandTypes
|
||||
}
|
||||
if (opts.sourceType !== undefined && opts.sourceType !== null) {
|
||||
postBody['sourceType'] = opts.sourceType
|
||||
}
|
||||
if (opts.usernames !== undefined && opts.usernames !== null) {
|
||||
postBody['usernames'] = opts.usernames
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeCommands with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/describeCommands',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
删除用户自定义命令。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于删除用户自定义命令。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {array} [opts.commandIds] - 用户创建的命令Id
|
||||
optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param string commandId 命令Id。
|
||||
*/
|
||||
|
||||
deleteCommands (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling deleteCommands"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.commandIds !== undefined && opts.commandIds !== null) {
|
||||
postBody['commandIds'] = opts.commandIds
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call deleteCommands with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/deleteCommands',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
执行用户保存的自定义命令。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于执行用户保存的自定义命令。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} opts.commandId - 命令Id
|
||||
|
||||
* @param {array} [opts.instances] - 运行该命令的云主机,与tags查到云主机取并集,一次最多云主机数50
|
||||
optional
|
||||
* @param {array} [opts.tags] - 根据tags确定运行该命令的云主机,与指定instances云主机取并集,一次最多云主机数50
|
||||
optional
|
||||
* @param {string} [opts.execTime] - 配置运行该命令的时刻,格式`yyyy-MM-dd HH:mm:ss`。不传该参数,立即执行命令。默认为空,可配置的时间范围为`当前时间+10minute`~`当前时间+6month`。
|
||||
optional
|
||||
* @param {integer} [opts.timeout] - 超时时间,取值范围:[10, 86400], 超过该时间后,尚未执行完的命令会置为失败。默认60s
|
||||
optional
|
||||
* @param {string} [opts.username] - 用户名,执行该命令时的用户身份。在linux上默认是root,windows上默认是administrator。长度小于256
|
||||
optional
|
||||
* @param {string} [opts.workdir] - 命令执行路径,在linux上默认为用户的home目录:/root, 在windows上默认为:C:\Windows\system32
|
||||
optional
|
||||
* @param {string} [opts.windowsPassword] - 和用户名相匹配的密码,仅适用于windows系统
|
||||
optional
|
||||
* @param {boolean} [opts.enableParameter] - 脚本中是否启用参数,true:启用,false:不启用。
|
||||
optional
|
||||
* @param {array} [opts.parameters] - 用户自定义参数和对应的参数值,数量不超过20。
|
||||
optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param string invokeId 命令调用Id。
|
||||
*/
|
||||
|
||||
invokeCommand (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling invokeCommand"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.commandId === undefined || opts.commandId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.commandId' when calling invokeCommand"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.commandId !== undefined && opts.commandId !== null) {
|
||||
postBody['commandId'] = opts.commandId
|
||||
}
|
||||
if (opts.instances !== undefined && opts.instances !== null) {
|
||||
postBody['instances'] = opts.instances
|
||||
}
|
||||
if (opts.tags !== undefined && opts.tags !== null) {
|
||||
postBody['tags'] = opts.tags
|
||||
}
|
||||
if (opts.execTime !== undefined && opts.execTime !== null) {
|
||||
postBody['execTime'] = opts.execTime
|
||||
}
|
||||
if (opts.timeout !== undefined && opts.timeout !== null) {
|
||||
postBody['timeout'] = opts.timeout
|
||||
}
|
||||
if (opts.username !== undefined && opts.username !== null) {
|
||||
postBody['username'] = opts.username
|
||||
}
|
||||
if (opts.workdir !== undefined && opts.workdir !== null) {
|
||||
postBody['workdir'] = opts.workdir
|
||||
}
|
||||
if (opts.windowsPassword !== undefined && opts.windowsPassword !== null) {
|
||||
postBody['windowsPassword'] = opts.windowsPassword
|
||||
}
|
||||
if (opts.enableParameter !== undefined && opts.enableParameter !== null) {
|
||||
postBody['enableParameter'] = opts.enableParameter
|
||||
}
|
||||
if (opts.parameters !== undefined && opts.parameters !== null) {
|
||||
postBody['parameters'] = opts.parameters
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call invokeCommand with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/invokeCommand',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
查询命令调用。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于查询命令调用。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {integer} [opts.pageNumber] - 页数,默认是第一页,取值1
|
||||
optional
|
||||
* @param {integer} [opts.pageSize] - 每页大小,默认20, 最大100
|
||||
optional
|
||||
* @param {array} [opts.invokeIds] - 命令执行Id
|
||||
optional
|
||||
* @param {array} [opts.commandIds] - 命令Id
|
||||
optional
|
||||
* @param {array} [opts.status] - 命令执行状态
|
||||
optional
|
||||
* @param {array} [opts.commandNames] - 命令名字
|
||||
optional
|
||||
* @param {array} [opts.commandTypes] - 命令类型, shell or powershell
|
||||
optional
|
||||
* @param {array} [opts.userNames] - 命令执行用户
|
||||
optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param integer totalCount 命令调用的总数
|
||||
* @param invocation invocations
|
||||
*/
|
||||
|
||||
describeInvocations (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling describeInvocations"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
|
||||
postBody['pageNumber'] = opts.pageNumber
|
||||
}
|
||||
if (opts.pageSize !== undefined && opts.pageSize !== null) {
|
||||
postBody['pageSize'] = opts.pageSize
|
||||
}
|
||||
if (opts.invokeIds !== undefined && opts.invokeIds !== null) {
|
||||
postBody['invokeIds'] = opts.invokeIds
|
||||
}
|
||||
if (opts.commandIds !== undefined && opts.commandIds !== null) {
|
||||
postBody['commandIds'] = opts.commandIds
|
||||
}
|
||||
if (opts.status !== undefined && opts.status !== null) {
|
||||
postBody['status'] = opts.status
|
||||
}
|
||||
if (opts.commandNames !== undefined && opts.commandNames !== null) {
|
||||
postBody['commandNames'] = opts.commandNames
|
||||
}
|
||||
if (opts.commandTypes !== undefined && opts.commandTypes !== null) {
|
||||
postBody['commandTypes'] = opts.commandTypes
|
||||
}
|
||||
if (opts.userNames !== undefined && opts.userNames !== null) {
|
||||
postBody['userNames'] = opts.userNames
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeInvocations with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/describeInvocations',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
配置用户日志信息。
|
||||
|
||||
详细操作说明请参考帮助文档:[用户自定义命令概述](https://docs.jdcloud.com/cn/virtual-machines/assistant-overview)
|
||||
|
||||
## 接口说明
|
||||
- 该接口用于配置用户日志信息。
|
||||
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} [opts.logset] - 用户日志集名字
|
||||
optional
|
||||
* @param {string} opts.logtopic - 用户日志主题名字
|
||||
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
*/
|
||||
|
||||
addLogConfig (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling addLogConfig"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.logtopic === undefined || opts.logtopic === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.logtopic' when calling addLogConfig"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.logset !== undefined && opts.logset !== null) {
|
||||
postBody['logset'] = opts.logset
|
||||
}
|
||||
if (opts.logtopic !== undefined && opts.logtopic !== null) {
|
||||
postBody['logtopic'] = opts.logtopic
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 assistant/1.0.2'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call addLogConfig with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/addLogConfig',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
module.exports = ASSISTANT
|
||||
File diff suppressed because it is too large
Load Diff
1933
packages/libs/lib-jdcloud/src/repo/baseanti/v1/baseanti.js
Normal file
1933
packages/libs/lib-jdcloud/src/repo/baseanti/v1/baseanti.js
Normal file
File diff suppressed because it is too large
Load Diff
1613
packages/libs/lib-jdcloud/src/repo/bastion/v1/bastion.js
Normal file
1613
packages/libs/lib-jdcloud/src/repo/bastion/v1/bastion.js
Normal file
File diff suppressed because it is too large
Load Diff
285
packages/libs/lib-jdcloud/src/repo/bgw/v1/bgw.js
Normal file
285
packages/libs/lib-jdcloud/src/repo/bgw/v1/bgw.js
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright 2018 JDCLOUD.COM
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http:#www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* instances
|
||||
* 续费查询实例信息接口
|
||||
*
|
||||
* OpenAPI spec version: v1
|
||||
* Contact:
|
||||
*
|
||||
* NOTE: This class is auto generated by the jdcloud code generator program.
|
||||
*/
|
||||
|
||||
require('../../../lib/node_loader')
|
||||
var JDCloud = require('../../../lib/core')
|
||||
var Service = JDCloud.Service
|
||||
var serviceId = 'bgw'
|
||||
Service._services[serviceId] = true
|
||||
|
||||
/**
|
||||
* bgw service.
|
||||
* @version 1.3.1
|
||||
*/
|
||||
|
||||
class BGW extends Service {
|
||||
constructor (options = {}) {
|
||||
options._defaultEndpoint = {}
|
||||
options._defaultEndpoint.protocol =
|
||||
options._defaultEndpoint.protocol || 'https'
|
||||
options._defaultEndpoint.host =
|
||||
options._defaultEndpoint.host || 'bgw.jdcloud-api.com'
|
||||
options.basePath = '/v1' // 默认要设为空""
|
||||
super(serviceId, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改VPN隧道管理状态
|
||||
* @param {Object} opts - parameters
|
||||
* @param {string} opts.vpnTunnelId - VPN Tunnel ID
|
||||
* @param {string} opts.adminStatus - 隧道管理状态, UP, DOWN
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
*/
|
||||
|
||||
modifyAdminStatus (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling modifyAdminStatus"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
if (opts.vpnTunnelId === undefined || opts.vpnTunnelId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.vpnTunnelId' when calling modifyAdminStatus"
|
||||
)
|
||||
}
|
||||
if (opts.adminStatus === undefined || opts.adminStatus === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'opts.adminStatus' when calling modifyAdminStatus"
|
||||
)
|
||||
}
|
||||
|
||||
let postBody = {}
|
||||
if (opts.adminStatus !== undefined && opts.adminStatus !== null) {
|
||||
postBody['adminStatus'] = opts.adminStatus
|
||||
}
|
||||
|
||||
let queryParams = {}
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId,
|
||||
vpnTunnelId: opts.vpnTunnelId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 bgw/1.3.1'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call modifyAdminStatus with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/vpnTunnels/{vpnTunnelId}:adminStatus',
|
||||
'POST',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询连接列表
|
||||
* @param {Object} opts - parameters
|
||||
* @param {integer} [opts.pageNumber] - 页码, 默认为1, 取值范围:[1,∞), 页码超过总页数时, 显示最后一页 optional
|
||||
* @param {integer} [opts.pageSize] - 分页大小,默认为20,取值范围:[10,100] optional
|
||||
* @param {filter} [opts.filters] - connectionIds - 连接ID列表,支持多个
|
||||
connectionNames - 连接名称列表,支持多个
|
||||
types - 类型,取值:jcloud_hosted:托管连接、jcloud_partner:合作伙伴连接、jcloud:自助连接, 支持多个
|
||||
status - Connection状态,支持单个。取值为:待审核(Ordering)、待支付(Installation_Paying)、施工中(Pending)、等待确认(Confirming)、可用(Active)、不可用(InActive)、删除中(Deleting)、已删除(Deleted)、审核未通过(Rejected)
|
||||
optional
|
||||
* @param {string} regionId - ID of the region
|
||||
* @param {string} callback - callback
|
||||
@return {Object} result
|
||||
* @param connection connections
|
||||
* @param integer totalCount 总数量
|
||||
*/
|
||||
|
||||
describeConnections (opts, regionId = this.config.regionId, callback) {
|
||||
if (typeof regionId === 'function') {
|
||||
callback = regionId
|
||||
regionId = this.config.regionId
|
||||
}
|
||||
|
||||
if (regionId === undefined || regionId === null) {
|
||||
throw new Error(
|
||||
"Missing the required parameter 'regionId' when calling describeConnections"
|
||||
)
|
||||
}
|
||||
|
||||
opts = opts || {}
|
||||
|
||||
let postBody = null
|
||||
let queryParams = {}
|
||||
if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
|
||||
queryParams['pageNumber'] = opts.pageNumber
|
||||
}
|
||||
if (opts.pageSize !== undefined && opts.pageSize !== null) {
|
||||
queryParams['pageSize'] = opts.pageSize
|
||||
}
|
||||
Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))
|
||||
|
||||
let pathParams = {
|
||||
regionId: regionId
|
||||
}
|
||||
|
||||
let headerParams = {
|
||||
'User-Agent': 'JdcloudSdkNode/1.0.0 bgw/1.3.1'
|
||||
}
|
||||
|
||||
let contentTypes = ['application/json']
|
||||
let accepts = ['application/json']
|
||||
|
||||
// 扩展自定义头
|
||||
if (opts['x-extra-header']) {
|
||||
for (let extraHeader in opts['x-extra-header']) {
|
||||
headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['content-type'])) {
|
||||
contentTypes = opts['x-extra-header']['content-type']
|
||||
} else if (typeof opts['x-extra-header']['content-type'] === 'string') {
|
||||
contentTypes = opts['x-extra-header']['content-type'].split(',')
|
||||
}
|
||||
|
||||
if (Array.isArray(opts['x-extra-header']['accept'])) {
|
||||
accepts = opts['x-extra-header']['accept']
|
||||
} else if (typeof opts['x-extra-header']['accept'] === 'string') {
|
||||
accepts = opts['x-extra-header']['accept'].split(',')
|
||||
}
|
||||
}
|
||||
|
||||
let formParams = {}
|
||||
|
||||
let returnType = null
|
||||
|
||||
this.config.logger(
|
||||
`call describeConnections with params:\npathParams:${JSON.stringify(
|
||||
pathParams
|
||||
)},\nqueryParams:${JSON.stringify(
|
||||
queryParams
|
||||
)}, \nheaderParams:${JSON.stringify(
|
||||
headerParams
|
||||
)}, \nformParams:${JSON.stringify(
|
||||
formParams
|
||||
)}, \npostBody:${JSON.stringify(postBody)}`,
|
||||
'DEBUG'
|
||||
)
|
||||
|
||||
let request = super.makeRequest(
|
||||
'/regions/{regionId}/connections/',
|
||||
'GET',
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
)
|
||||
|
||||
return request.then(
|
||||
function (result) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(null, result)
|
||||
}
|
||||
return result
|
||||
},
|
||||
function (error) {
|
||||
if (callback && typeof callback === 'function') {
|
||||
return callback(error)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
module.exports = BGW
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user