mirror of
https://github.com/certd/certd.git
synced 2026-04-17 07:10:52 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b3fb7387d | ||
|
|
feac310caf | ||
|
|
d67ec3feb3 | ||
|
|
cf8abb4528 | ||
|
|
d66de26de4 | ||
|
|
7edf3f6147 | ||
|
|
2143dff2ae | ||
|
|
32c714d1b6 | ||
|
|
84e699ee24 | ||
|
|
7fdb572b8b | ||
|
|
cfd3b66be9 | ||
|
|
75c4f9dea8 | ||
|
|
a76a32230d |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 补充类型断言 ([2143dff](https://github.com/certd/certd/commit/2143dff2ae96e6a78bef9f0498e36f8cd9e6941f))
|
||||
* 修复腾讯云部署到任意资源插件,无法使用之前已上传的腾讯云证书问题 ([32c714d](https://github.com/certd/certd/commit/32c714d1b6e68c71a74a7452115040c87ac4bfdc))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 插件支持导入导出 ([cf8abb4](https://github.com/certd/certd/commit/cf8abb45282070c8ba91469f93fd379fabf1f74a))
|
||||
* 支持上传证书到华为云CCM ([cfd3b66](https://github.com/certd/certd/commit/cfd3b66be9ebf53a26693057e70ed60c3f116be9))
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -16,6 +16,9 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
||||
* 私有化部署,数据保存本地,授权信息加密存储,镜像由Github Actions构建,过程公开透明
|
||||
* 支持SQLite,PostgreSQL、MySQL数据库
|
||||
|
||||
|
||||

|
||||
|
||||
>
|
||||
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||
>
|
||||
|
||||
@@ -1 +1 @@
|
||||
01:33
|
||||
22:26
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复登录错误次数过多阻止再次登录逻辑 ([bf4d191](https://github.com/certd/certd/commit/bf4d191c8bd2f9209eb6768f662b9c77de99e998))
|
||||
|
||||
## [1.33.2](https://github.com/certd/certd/compare/v1.33.1...v1.33.2) (2025-04-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -17,6 +17,8 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
||||
* 支持SQLite、Postgresql、MySQL数据库
|
||||
|
||||
|
||||

|
||||
|
||||
## 二、一些说明
|
||||
* 本项目申请证书过程遵循acme协议
|
||||
* 需要验证域名所有权,一般有两种方式
|
||||
|
||||
1
docs/images/intro/intro.svg
Normal file
1
docs/images/intro/intro.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 60 KiB |
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.33.3"
|
||||
"version": "1.33.4"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/publishlab/node-acme-client/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.33.3](https://github.com/publishlab/node-acme-client/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**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.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
@@ -67,5 +67,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
22:22
|
||||
23:45
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -44,5 +44,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -16,8 +16,8 @@
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/plus-core": "^1.33.3",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@certd/plus-core": "^1.33.4",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -43,5 +43,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -23,5 +23,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -30,5 +30,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -60,5 +60,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -16,7 +16,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -31,5 +31,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -27,10 +27,10 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.33.3",
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/pipeline": "^1.33.3",
|
||||
"@certd/plus-core": "^1.33.3",
|
||||
"@certd/acme-client": "^1.33.4",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@certd/pipeline": "^1.33.4",
|
||||
"@certd/plus-core": "^1.33.4",
|
||||
"@midwayjs/cache": "~3.14.0",
|
||||
"@midwayjs/core": "~3.20.3",
|
||||
"@midwayjs/i18n": "~3.20.3",
|
||||
@@ -61,5 +61,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -46,5 +46,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -15,10 +15,10 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.33.3",
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/pipeline": "^1.33.3",
|
||||
"@certd/plugin-lib": "^1.33.3",
|
||||
"@certd/acme-client": "^1.33.4",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@certd/pipeline": "^1.33.4",
|
||||
"@certd/plugin-lib": "^1.33.4",
|
||||
"@google-cloud/publicca": "^1.3.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -41,5 +41,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 插件支持导入导出 ([cf8abb4](https://github.com/certd/certd/commit/cf8abb45282070c8ba91469f93fd379fabf1f74a))
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -16,8 +16,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/pipeline": "^1.33.3",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@certd/pipeline": "^1.33.4",
|
||||
"@kubernetes/client-node": "0.21.0",
|
||||
"ali-oss": "^6.21.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
@@ -48,5 +48,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be69244e8ddb757de45c7e2b6033195c1f5a6910"
|
||||
"gitHead": "0730f5ff4f176452f82489caa837b717e176fdca"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
|
||||
import { ConnectConfig } from "ssh2";
|
||||
import { SshClient } from "./ssh.js";
|
||||
|
||||
@IsAccess({
|
||||
name: "ssh",
|
||||
title: "主机登录授权",
|
||||
@@ -9,7 +6,7 @@ import { SshClient } from "./ssh.js";
|
||||
icon: "clarity:host-line",
|
||||
input: {},
|
||||
})
|
||||
export class SshAccess extends BaseAccess implements ConnectConfig {
|
||||
export class SshAccess extends BaseAccess {
|
||||
@AccessInput({
|
||||
title: "主机地址",
|
||||
component: {
|
||||
@@ -125,6 +122,7 @@ export class SshAccess extends BaseAccess implements ConnectConfig {
|
||||
testRequest = true;
|
||||
|
||||
async onTestRequest() {
|
||||
const { SshClient } = await import("./ssh.js");
|
||||
const client = new SshClient(this.ctx.logger);
|
||||
|
||||
await client.exec({
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
// @ts-ignore
|
||||
import ssh2, { ConnectConfig, ExecOptions } from "ssh2";
|
||||
|
||||
import ssh2Constants from "ssh2/lib/protocol/constants.js";
|
||||
import path from "path";
|
||||
import * as _ from "lodash-es";
|
||||
import { isArray } from "lodash-es";
|
||||
import { ILogger } from "@certd/basic";
|
||||
import { SshAccess } from "./ssh-access.js";
|
||||
import stripAnsi from "strip-ansi";
|
||||
import { SocksClient } from "socks";
|
||||
import { SocksProxy, SocksProxyType } from "socks/typings/common/constants.js";
|
||||
|
||||
import fs from "fs";
|
||||
import { SocksProxyType } from "socks/typings/common/constants";
|
||||
|
||||
export type TransportItem = { localPath: string; remotePath: string };
|
||||
export interface SocksProxy {
|
||||
ipaddress?: string;
|
||||
host?: string;
|
||||
port: number;
|
||||
type: any;
|
||||
userId?: string;
|
||||
password?: string;
|
||||
custom_auth_method?: number;
|
||||
custom_auth_request_handler?: () => Promise<Buffer>;
|
||||
custom_auth_response_size?: number;
|
||||
custom_auth_response_handler?: (data: Buffer) => Promise<boolean>;
|
||||
}
|
||||
export type SshConnectConfig = {
|
||||
sock?: any;
|
||||
};
|
||||
|
||||
export class AsyncSsh2Client {
|
||||
conn: ssh2.Client;
|
||||
conn: any;
|
||||
logger: ILogger;
|
||||
connConf: SshAccess & ssh2.ConnectConfig;
|
||||
connConf: SshAccess & SshConnectConfig;
|
||||
windows = false;
|
||||
encoding: string;
|
||||
constructor(connConf: SshAccess, logger: ILogger) {
|
||||
@@ -40,7 +51,10 @@ export class AsyncSsh2Client {
|
||||
if (typeof this.connConf.port === "string") {
|
||||
this.connConf.port = parseInt(this.connConf.port);
|
||||
}
|
||||
const proxyOption: SocksProxy = this.parseSocksProxyFromUri(this.connConf.socksProxy);
|
||||
|
||||
const { SocksClient } = await import("socks");
|
||||
|
||||
const proxyOption = this.parseSocksProxyFromUri(this.connConf.socksProxy);
|
||||
const info = await SocksClient.createConnection({
|
||||
proxy: proxyOption,
|
||||
command: "connect",
|
||||
@@ -53,10 +67,12 @@ export class AsyncSsh2Client {
|
||||
this.connConf.sock = info.socket;
|
||||
}
|
||||
|
||||
const { SUPPORTED_KEX, SUPPORTED_SERVER_HOST_KEY, SUPPORTED_CIPHER, SUPPORTED_MAC } = ssh2Constants;
|
||||
const ssh2 = await import("ssh2");
|
||||
const ssh2Constants = await import("ssh2/lib/protocol/constants.js");
|
||||
const { SUPPORTED_KEX, SUPPORTED_SERVER_HOST_KEY, SUPPORTED_CIPHER, SUPPORTED_MAC } = ssh2Constants.default;
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const conn = new ssh2.Client();
|
||||
const conn = new ssh2.default.Client();
|
||||
conn
|
||||
.on("error", (err: any) => {
|
||||
this.logger.error("连接失败", err);
|
||||
@@ -197,6 +213,8 @@ export class AsyncSsh2Client {
|
||||
}
|
||||
|
||||
async shell(script: string | string[]): Promise<string> {
|
||||
const stripAnsiModule = await import("strip-ansi");
|
||||
const stripAnsi = stripAnsiModule.default;
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
this.logger.info(`执行shell脚本:[${this.connConf.host}][shell]: ` + script);
|
||||
this.conn.shell((err: Error, stream: any) => {
|
||||
@@ -449,7 +467,7 @@ export class SshClient {
|
||||
script = script.join(" && ");
|
||||
} else {
|
||||
const newLine = isLinux ? "\n" : "\r\n";
|
||||
if (_.isArray(script)) {
|
||||
if (isArray(script)) {
|
||||
script = script as Array<string>;
|
||||
script = script.join(newLine);
|
||||
}
|
||||
@@ -465,7 +483,7 @@ export class SshClient {
|
||||
async shell(options: { connectConf: SshAccess; script: string | Array<string> }): Promise<string> {
|
||||
let { script } = options;
|
||||
const { connectConf } = options;
|
||||
if (_.isArray(script)) {
|
||||
if (isArray(script)) {
|
||||
script = script as Array<string>;
|
||||
if (connectConf.windows) {
|
||||
script = script.join("\r\n");
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 插件支持导入导出 ([cf8abb4](https://github.com/certd/certd/commit/cf8abb45282070c8ba91469f93fd379fabf1f74a))
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -101,8 +101,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.33.3",
|
||||
"@certd/pipeline": "^1.33.3",
|
||||
"@certd/lib-iframe": "^1.33.4",
|
||||
"@certd/pipeline": "^1.33.4",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -66,6 +66,22 @@ export async function SetDisabled(data: { id?: number; name?: string; type?: str
|
||||
});
|
||||
}
|
||||
|
||||
export async function ExportPlugin(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/export",
|
||||
method: "post",
|
||||
data: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export async function ImportPlugin(body: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/import",
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
}
|
||||
|
||||
export type PluginConfigBean = {
|
||||
name: string;
|
||||
disabled: boolean;
|
||||
|
||||
@@ -2,8 +2,8 @@ import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
//@ts-ignore
|
||||
import yaml from "js-yaml";
|
||||
|
||||
@@ -36,7 +36,74 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
|
||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||
context.selectedRowKeys = selectedRowKeys;
|
||||
const { openCrudFormDialog } = useFormWrapper();
|
||||
|
||||
async function openImportDialog() {
|
||||
function createCrudOptions() {
|
||||
return {
|
||||
crudOptions: {
|
||||
columns: {
|
||||
content: {
|
||||
title: "插件文件",
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
name: "pem-input",
|
||||
vModel: "modelValue",
|
||||
textarea: {
|
||||
rows: 8,
|
||||
},
|
||||
},
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
helper: "选择插件文件",
|
||||
},
|
||||
},
|
||||
override: {
|
||||
title: "同名覆盖",
|
||||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{
|
||||
value: true,
|
||||
label: "覆盖",
|
||||
},
|
||||
{
|
||||
value: false,
|
||||
label: "不覆盖",
|
||||
},
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
helper: "如果已有相同名称插件,直接覆盖",
|
||||
},
|
||||
},
|
||||
},
|
||||
form: {
|
||||
wrapper: {
|
||||
title: "导入插件",
|
||||
saveRemind: false,
|
||||
},
|
||||
afterSubmit() {
|
||||
notification.success({ message: "操作成功" });
|
||||
},
|
||||
async doSubmit({ form }: any) {
|
||||
return await api.ImportPlugin({
|
||||
...form,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
const { crudOptions } = createCrudOptions();
|
||||
await openCrudFormDialog({ crudOptions });
|
||||
}
|
||||
return {
|
||||
crudOptions: {
|
||||
settings: {
|
||||
@@ -65,8 +132,18 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
buttons: {
|
||||
add: {
|
||||
show: true,
|
||||
icon: "ion:ios-add-circle-outline",
|
||||
text: "自定义插件",
|
||||
},
|
||||
import: {
|
||||
show: true,
|
||||
icon: "ion:cloud-upload-outline",
|
||||
text: "导入",
|
||||
type: "primary",
|
||||
async click() {
|
||||
await openImportDialog();
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
@@ -85,10 +162,33 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
}),
|
||||
},
|
||||
remove: {
|
||||
order: 999,
|
||||
show: compute(({ row }) => {
|
||||
return row.type === "custom";
|
||||
}),
|
||||
},
|
||||
export: {
|
||||
text: null,
|
||||
icon: "ion:cloud-download-outline",
|
||||
title: "导出",
|
||||
type: "link",
|
||||
show: compute(({ row }) => {
|
||||
return row.type === "custom";
|
||||
}),
|
||||
async click({ row }) {
|
||||
//将文本内容,作为文件下载
|
||||
const content = await api.ExportPlugin(row.id);
|
||||
if (content) {
|
||||
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = `${row.name}.yaml`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
table: {
|
||||
@@ -182,8 +282,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
show: true,
|
||||
helper: "必须为英文,驼峰命名,类型作为前缀\n例如AliyunDeployToCDN\n插件一旦被使用,不要修改名称",
|
||||
rules: [{ required: true }],
|
||||
helper: "必须为英文或数字,驼峰命名,类型作为前缀\n例如AliyunDeployToCDN\n插件一旦被使用,不要修改名称",
|
||||
rules: [
|
||||
{ required: true },
|
||||
{
|
||||
type: "regexp",
|
||||
pattern: /^[a-zA-Z][a-zA-Z0-9]+$/,
|
||||
message: "必须为英文或数字,驼峰命名,类型作为前缀",
|
||||
},
|
||||
],
|
||||
},
|
||||
column: {
|
||||
width: 250,
|
||||
@@ -205,7 +312,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
form: {
|
||||
show: true,
|
||||
helper: "上传到插件商店时,将作为插件名称前缀,例如:greper/pluginName",
|
||||
rules: [{ required: true }],
|
||||
rules: [
|
||||
{ required: true },
|
||||
{
|
||||
type: "regexp",
|
||||
pattern: /^[a-zA-Z][a-zA-Z0-9]+$/,
|
||||
message: "必须为英文字母或数字",
|
||||
},
|
||||
],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 补充类型断言 ([2143dff](https://github.com/certd/certd/commit/2143dff2ae96e6a78bef9f0498e36f8cd9e6941f))
|
||||
* 修复腾讯云部署到任意资源插件,无法使用之前已上传的腾讯云证书问题 ([32c714d](https://github.com/certd/certd/commit/32c714d1b6e68c71a74a7452115040c87ac4bfdc))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 插件支持导入导出 ([cf8abb4](https://github.com/certd/certd/commit/cf8abb45282070c8ba91469f93fd379fabf1f74a))
|
||||
* 支持上传证书到华为云CCM ([cfd3b66](https://github.com/certd/certd/commit/cfd3b66be9ebf53a26693057e70ed60c3f116be9))
|
||||
|
||||
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
53
packages/ui/certd-server/export-plugin-yaml.js
Normal file
53
packages/ui/certd-server/export-plugin-yaml.js
Normal file
@@ -0,0 +1,53 @@
|
||||
// 扫描目录,列出文件,然后加载为模块
|
||||
|
||||
import { join } from 'path';
|
||||
import fs from 'fs'
|
||||
import { pathToFileURL } from "node:url";
|
||||
import path from 'path'
|
||||
function scanDir(dir) {
|
||||
const files = fs.readdirSync(dir);
|
||||
const result = [];
|
||||
// 扫描目录及子目录
|
||||
for (const file of files) {
|
||||
if (file.includes("index.js")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const filePath = join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
result.push(...scanDir(filePath));
|
||||
} else {
|
||||
if (!file.endsWith(".js")) {
|
||||
continue;
|
||||
}
|
||||
result.push(filePath);
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default async function loadModules(dir) {
|
||||
const files = scanDir(dir);
|
||||
const modules = {}
|
||||
for (const file of files) {
|
||||
|
||||
try {
|
||||
// 转换为 file:// URL(Windows 必需)
|
||||
const moduleUrl = pathToFileURL(file).href
|
||||
const module = await import(moduleUrl)
|
||||
|
||||
// 如果模块有默认导出,优先使用
|
||||
modules[file] = module.default || module
|
||||
} catch (err) {
|
||||
console.error(`加载模块 ${file} 失败:`, err)
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
const modules = await loadModules('./dist/plugins');
|
||||
|
||||
for (const key in modules) {
|
||||
console.log(key)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.33.3",
|
||||
"version": "1.33.4",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -38,19 +38,19 @@
|
||||
"@aws-sdk/client-acm": "^3.699.0",
|
||||
"@aws-sdk/client-cloudfront": "^3.699.0",
|
||||
"@aws-sdk/client-s3": "^3.705.0",
|
||||
"@certd/acme-client": "^1.33.3",
|
||||
"@certd/basic": "^1.33.3",
|
||||
"@certd/commercial-core": "^1.33.3",
|
||||
"@certd/jdcloud": "^1.33.3",
|
||||
"@certd/lib-huawei": "^1.33.3",
|
||||
"@certd/lib-k8s": "^1.33.3",
|
||||
"@certd/lib-server": "^1.33.3",
|
||||
"@certd/midway-flyway-js": "^1.33.3",
|
||||
"@certd/pipeline": "^1.33.3",
|
||||
"@certd/plugin-cert": "^1.33.3",
|
||||
"@certd/plugin-lib": "^1.33.3",
|
||||
"@certd/plugin-plus": "^1.33.3",
|
||||
"@certd/plus-core": "^1.33.3",
|
||||
"@certd/acme-client": "^1.33.4",
|
||||
"@certd/basic": "^1.33.4",
|
||||
"@certd/commercial-core": "^1.33.4",
|
||||
"@certd/jdcloud": "^1.33.4",
|
||||
"@certd/lib-huawei": "^1.33.4",
|
||||
"@certd/lib-k8s": "^1.33.4",
|
||||
"@certd/lib-server": "^1.33.4",
|
||||
"@certd/midway-flyway-js": "^1.33.4",
|
||||
"@certd/pipeline": "^1.33.4",
|
||||
"@certd/plugin-cert": "^1.33.4",
|
||||
"@certd/plugin-lib": "^1.33.4",
|
||||
"@certd/plugin-plus": "^1.33.4",
|
||||
"@certd/plus-core": "^1.33.4",
|
||||
"@corsinvest/cv4pve-api-javascript": "^8.3.0",
|
||||
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
|
||||
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
|
||||
|
||||
@@ -26,6 +26,11 @@ process.on('uncaughtException', error => {
|
||||
});
|
||||
|
||||
@Configuration({
|
||||
// detectorOptions: {
|
||||
// ignore: [
|
||||
// '**/plugins/**'
|
||||
// ]
|
||||
// },
|
||||
imports: [
|
||||
koa,
|
||||
orm,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { merge } from 'lodash-es';
|
||||
import { CrudController } from '@certd/lib-server';
|
||||
import { PluginService } from '../../../modules/plugin/service/plugin-service.js';
|
||||
import { PluginImportReq, PluginService } from "../../../modules/plugin/service/plugin-service.js";
|
||||
import { CommPluginConfig, PluginConfigService } from '../../../modules/plugin/service/plugin-config-service.js';
|
||||
/**
|
||||
* 插件
|
||||
@@ -82,4 +82,17 @@ export class PluginController extends CrudController<PluginService> {
|
||||
const res = await this.pluginConfigService.saveCommPluginConfig(body);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
|
||||
@Post('/import', { summary: 'sys:settings:edit' })
|
||||
async import(@Body(ALL) body: PluginImportReq) {
|
||||
const res = await this.service.importPlugin(body);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/export', { summary: 'sys:settings:edit' })
|
||||
async export(@Body('id') id: number) {
|
||||
const res = await this.service.exportPlugin(id);
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ export type PluginFindReq = {
|
||||
name?: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class PluginConfigService {
|
||||
|
||||
@@ -12,6 +12,10 @@ import { logger } from "@certd/basic";
|
||||
import yaml from "js-yaml";
|
||||
import { getDefaultAccessPlugin, getDefaultDeployPlugin, getDefaultDnsPlugin } from "./default-plugin.js";
|
||||
|
||||
export type PluginImportReq = {
|
||||
content: string,
|
||||
override?: boolean;
|
||||
};
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
@@ -41,7 +45,7 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
const builtInList = await this.getBuiltInEntityList();
|
||||
|
||||
//获取分页数据
|
||||
const data = builtInList.slice(offset, offset + limit);
|
||||
const data = builtInList.slice(offset, offset + limit);
|
||||
|
||||
return {
|
||||
records: data,
|
||||
@@ -53,7 +57,7 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
|
||||
async getEnabledBuildInGroup(isSimple = false) {
|
||||
const groups = this.builtInPluginService.getGroups();
|
||||
if(isSimple){
|
||||
if (isSimple) {
|
||||
for (const key in groups) {
|
||||
const group = groups[key];
|
||||
group.plugins.forEach(item => {
|
||||
@@ -97,8 +101,8 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
});
|
||||
const disabledNames = list.map(it => it.name);
|
||||
|
||||
return builtInList.filter(it =>{
|
||||
return !disabledNames.includes(it.name)
|
||||
return builtInList.filter(it => {
|
||||
return !disabledNames.includes(it.name);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -168,33 +172,48 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
name: param.name,
|
||||
author: param.author
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (old) {
|
||||
throw new Error(`插件${param.author}/${param.name}已存在`);
|
||||
}
|
||||
|
||||
let plugin:any = {}
|
||||
let plugin: any = {};
|
||||
if (param.pluginType === "access") {
|
||||
plugin = getDefaultAccessPlugin()
|
||||
delete param.group
|
||||
}else if (param.pluginType === "deploy") {
|
||||
plugin = getDefaultDeployPlugin()
|
||||
}else if (param.pluginType === "dnsProvider") {
|
||||
plugin = getDefaultDnsPlugin()
|
||||
delete param.group
|
||||
}else{
|
||||
plugin = getDefaultAccessPlugin();
|
||||
delete param.group;
|
||||
} else if (param.pluginType === "deploy") {
|
||||
plugin = getDefaultDeployPlugin();
|
||||
} else if (param.pluginType === "dnsProvider") {
|
||||
plugin = getDefaultDnsPlugin();
|
||||
delete param.group;
|
||||
} else {
|
||||
throw new Error(`插件类型${param.pluginType}不支持`);
|
||||
}
|
||||
|
||||
return await super.add({
|
||||
return await super.add({
|
||||
...param,
|
||||
...plugin
|
||||
});
|
||||
}
|
||||
|
||||
async update(param: any) {
|
||||
const old = await this.repository.findOne({
|
||||
where: {
|
||||
name: param.name,
|
||||
author: param.author
|
||||
}
|
||||
});
|
||||
|
||||
if (old && old.id !== param.id) {
|
||||
throw new Error(`插件${param.author}/${param.name}已存在`);
|
||||
}
|
||||
|
||||
return await super.update(param);
|
||||
}
|
||||
|
||||
async compile(code: string) {
|
||||
const ts = await import("typescript")
|
||||
const ts = await import("typescript");
|
||||
return ts.transpileModule(code, {
|
||||
compilerOptions: { module: ts.ModuleKind.ESNext }
|
||||
}).outputText;
|
||||
@@ -220,16 +239,16 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
if (info && info.length > 0) {
|
||||
const plugin = info[0];
|
||||
|
||||
try{
|
||||
try {
|
||||
const AsyncFunction = Object.getPrototypeOf(async () => {
|
||||
}).constructor;
|
||||
// const script = await this.compile(plugin.content);
|
||||
const script = plugin.content
|
||||
const script = plugin.content;
|
||||
const getPluginClass = new AsyncFunction(script);
|
||||
return await getPluginClass({ logger: logger });
|
||||
}catch (e) {
|
||||
logger.error("编译插件失败:",e)
|
||||
throw e
|
||||
} catch (e) {
|
||||
logger.error("编译插件失败:", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -284,4 +303,80 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
});
|
||||
}
|
||||
|
||||
async exportPlugin(id: number) {
|
||||
const info = await this.info(id);
|
||||
if (!info) {
|
||||
throw new Error("插件不存在");
|
||||
}
|
||||
const metadata = yaml.load(info.metadata || "");
|
||||
const extra = yaml.load(info.extra || "");
|
||||
const content = info.content;
|
||||
delete info.metadata;
|
||||
delete info.extra;
|
||||
delete info.content;
|
||||
delete info.id;
|
||||
delete info.createTime;
|
||||
delete info.updateTime;
|
||||
const plugin = {
|
||||
...info,
|
||||
...metadata,
|
||||
...extra,
|
||||
content
|
||||
};
|
||||
|
||||
return yaml.dump(plugin) as string;
|
||||
}
|
||||
|
||||
async importPlugin(req: PluginImportReq) {
|
||||
|
||||
const loaded = yaml.load(req.content);
|
||||
if (!loaded) {
|
||||
throw new Error("插件内容不能为空");
|
||||
}
|
||||
delete loaded.id
|
||||
|
||||
const old = await this.repository.findOne({
|
||||
where: {
|
||||
name: loaded.name,
|
||||
author: loaded.author
|
||||
}
|
||||
});
|
||||
|
||||
const metadata = {
|
||||
input: loaded.input,
|
||||
output: loaded.output
|
||||
};
|
||||
const extra = {
|
||||
dependPlugins: loaded.dependPlugins,
|
||||
default: loaded.default,
|
||||
showRunStrategy: loaded.showRunStrategy
|
||||
};
|
||||
|
||||
const pluginEntity = {
|
||||
...loaded,
|
||||
metadata: yaml.dump(metadata),
|
||||
extra: yaml.dump(extra),
|
||||
content: req.content,
|
||||
disabled: false
|
||||
};
|
||||
if (!pluginEntity.pluginType) {
|
||||
throw new Error(`插件类型不能为空`);
|
||||
}
|
||||
|
||||
if (old) {
|
||||
if (!req.override) {
|
||||
throw new Error(`插件${loaded.author}/${loaded.name}已存在`);
|
||||
}
|
||||
//update
|
||||
pluginEntity.id = old.id;
|
||||
await this.update(pluginEntity);
|
||||
} else {
|
||||
//add
|
||||
const { id } = await this.add(pluginEntity);
|
||||
pluginEntity.id = id;
|
||||
}
|
||||
return {
|
||||
id: pluginEntity.id
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
//@ts-ignore
|
||||
import { HcClient } from "@huaweicloud/huaweicloud-sdk-core/HcClient";
|
||||
|
||||
export class HuaweiCcmClient {
|
||||
//@ts-ignore
|
||||
hcClient: HcClient;
|
||||
|
||||
//@ts-ignore
|
||||
constructor(client: HcClient) {
|
||||
this.hcClient = client;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
importCertificate(req: {
|
||||
name: string,
|
||||
certificate: string,
|
||||
private_key: string,
|
||||
duplicate_check: boolean,
|
||||
}) {
|
||||
const options: any = {
|
||||
method: "POST",
|
||||
url: "/v3/scm/certificates/import",
|
||||
pathParams: {},
|
||||
queryParams: {},
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
/**
|
||||
* name
|
||||
* string 是
|
||||
* 证书名称。字符长度为3~63位, 请输入英文字符,数字,下划线,中划线,英文句点。
|
||||
*
|
||||
* certificate
|
||||
* string 是
|
||||
* 证书内容,可包含中间证书及根证书。若certificate_chain字段传入证书链,则该字段只取证书本身。回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* certificate_chain
|
||||
* string 否
|
||||
* 证书链,非必填,可通过certificate字段传入。回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* private_key
|
||||
* string 是
|
||||
* 证书私钥。
|
||||
* 不能上传带有口令保护的私钥,回车换行需要使用转义字符\n或者\r\n替换。
|
||||
*
|
||||
* duplicate_check
|
||||
*/
|
||||
data: {
|
||||
...req
|
||||
}
|
||||
|
||||
};
|
||||
// @ts-ignore
|
||||
options["responseHeaders"] = ["X-Request-Id"];
|
||||
return this.hcClient.sendRequest(options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
name: HuaweiUploadToCCM
|
||||
title: 华为-上传证书至CCM
|
||||
desc: 上传证书至华为云CCM
|
||||
type: plugin
|
||||
pluginType: deploy
|
||||
author: certd
|
||||
version: 1.0.0
|
||||
icon: 'svg:icon-huawei'
|
||||
group: huawei
|
||||
default:
|
||||
strategy:
|
||||
runStrategy: 1,
|
||||
input: # 插件的输入参数
|
||||
cert:
|
||||
title: 前置任务证书
|
||||
helper: 请选择前置任务产生的证书 # 帮助说明
|
||||
component:
|
||||
name: output-selector # 输入组件名称
|
||||
vModel: modelValue # 组件参数
|
||||
from:
|
||||
- ApplyCert
|
||||
- ApplyCertLego
|
||||
- ApplyCertUpload
|
||||
required: true
|
||||
certDomains:
|
||||
title: 当前证书域名
|
||||
component:
|
||||
name: cert-domains-getter
|
||||
mergeScript: |
|
||||
return {
|
||||
component:{
|
||||
inputKey: ctx.compute(({form})=>{
|
||||
return form.cert
|
||||
}),
|
||||
}
|
||||
}
|
||||
required: true
|
||||
accessId:
|
||||
title: Access授权
|
||||
helper: xxxx的授权
|
||||
component:
|
||||
name: access-selector # 授权选择组件名称
|
||||
type: aliyun # 授权类型
|
||||
required: true
|
||||
key1:
|
||||
title: 输入示例1
|
||||
required: false
|
||||
key2:
|
||||
title: 可选项
|
||||
component:
|
||||
name: a-select
|
||||
vMode: value
|
||||
options:
|
||||
- value: "1"
|
||||
label: 选项1
|
||||
- value: "2"
|
||||
label: 选项2
|
||||
required: false
|
||||
#output: # 输出参数,一般插件都不需要配置此项
|
||||
# outputName:
|
||||
#
|
||||
@@ -0,0 +1,82 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||
import { HuaweiAccess } from "../../access/index.js";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { createCertDomainGetterInputDefine } from "@certd/plugin-lib";
|
||||
import { resetLogConfigure } from "@certd/basic";
|
||||
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'HauweiUploadToCCM',
|
||||
title: '华为云-上传证书至CCM',
|
||||
icon: 'svg:icon-huawei',
|
||||
group: pluginGroups.huawei.key,
|
||||
desc: '上传证书到华为云CCM',
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
})
|
||||
export class HauweiUploadToCCM extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames]
|
||||
},
|
||||
required: true
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: "Access授权",
|
||||
helper: "华为云授权AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "huawei"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
accessId!: string;
|
||||
@TaskOutput({
|
||||
title: '华为云CertId',
|
||||
})
|
||||
huaweiCertId!: string;
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info("开始部署证书到华为云CCM");
|
||||
const { client } = await this.getCcmClient();
|
||||
|
||||
const res = await client.importCertificate({
|
||||
name: this.appendTimeSuffix("certd"),
|
||||
certificate: this.cert.crt,
|
||||
private_key: this.cert.key,
|
||||
duplicate_check: false
|
||||
});
|
||||
this.huaweiCertId = res.certificate_id;
|
||||
this.logger.info(`上传证书到华为云ccm完成,certificate_id:${this.huaweiCertId}`);
|
||||
}
|
||||
|
||||
async getCcmClient() {
|
||||
const access = await this.getAccess<HuaweiAccess>(this.accessId);
|
||||
const { BasicCredentials } = await import("@huaweicloud/huaweicloud-sdk-core");
|
||||
const { ClientBuilder } = await import("@huaweicloud/huaweicloud-sdk-core/ClientBuilder.js");
|
||||
//@ts-ignore
|
||||
const {HuaweiCcmClient} = await import("./ccm-client.js")
|
||||
|
||||
//恢复华为云把log4j的config改了的问题
|
||||
resetLogConfigure();
|
||||
|
||||
const credentials = new BasicCredentials().withAk(access.accessKeyId).withSk(access.accessKeySecret);
|
||||
const client = new ClientBuilder((hcClient) => {
|
||||
return new HuaweiCcmClient(hcClient);
|
||||
}).withCredential(credentials).withEndpoint("https://scm.cn-north-4.myhuaweicloud.com").build();
|
||||
return {
|
||||
client
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -128,11 +128,12 @@ export class DeployCertToTencentAll extends AbstractTaskPlugin {
|
||||
});
|
||||
|
||||
let certId:string = null
|
||||
if (typeof certId === 'object') {
|
||||
//上传
|
||||
certId = await this.uploadToTencent(access,this.tencentCertId as CertInfo);
|
||||
if (typeof this.tencentCertId === 'string') {
|
||||
certId = this.tencentCertId as string;
|
||||
} else if (this.tencentCertId && typeof this.tencentCertId === 'object') {
|
||||
certId = await this.uploadToTencent(access, this.tencentCertId as CertInfo);
|
||||
} else {
|
||||
certId = this.tencentCertId as string;
|
||||
throw new Error('无效的证书输入类型');
|
||||
}
|
||||
|
||||
const params = {
|
||||
|
||||
Reference in New Issue
Block a user