Compare commits

...

21 Commits

Author SHA1 Message Date
xiaojunnuo
031df8fc35 v1.21.2 2024-07-08 15:58:51 +08:00
xiaojunnuo
62419a8212 build: prepare to build 2024-07-08 15:57:13 +08:00
xiaojunnuo
09d93af853 build: prepare to build 2024-07-08 15:47:51 +08:00
xiaojunnuo
b6ab178de9 chore: 1 2024-07-08 15:47:36 +08:00
xiaojunnuo
5a08f27d2c build: prepare to build 2024-07-08 15:36:18 +08:00
xiaojunnuo
fe91d94090 perf: 申请证书时可以选择跳过本地dns校验 2024-07-08 15:35:58 +08:00
xiaojunnuo
56ab3269d2 chore: 1 2024-07-08 12:05:56 +08:00
xiaojunnuo
c8243c573f chore: 1 2024-07-08 12:04:59 +08:00
xiaojunnuo
0b769a1c86 v1.21.1 2024-07-08 11:58:09 +08:00
xiaojunnuo
a8189a974d build: prepare to build 2024-07-08 11:46:13 +08:00
xiaojunnuo
322875d241 chore: 1 2024-07-08 11:45:31 +08:00
xiaojunnuo
ed8a54a2bc chore: 1 2024-07-08 11:29:11 +08:00
xiaojunnuo
5ba9831ed1 perf: 上传到主机,支持设置不mkdirs 2024-07-08 11:19:02 +08:00
xiaojunnuo
f9c9fce581 docs: 1 2024-07-08 11:10:08 +08:00
xiaojunnuo
bc650a32cd docs: 1 2024-07-08 10:59:19 +08:00
xiaojunnuo
c6d3e3fe5b docs: 1 2024-07-08 10:57:42 +08:00
xiaojunnuo
73acc62af1 docs: 1 2024-07-08 10:56:19 +08:00
xiaojunnuo
0d4491f3a0 docs: 1 2024-07-08 10:55:55 +08:00
xiaojunnuo
85248044ab docs: 1 2024-07-08 10:53:55 +08:00
xiaojunnuo
c532449102 docs: 1 2024-07-05 10:56:29 +08:00
xiaojunnuo
970c7fd8a0 perf: 说明优化,默认值优化 2024-07-04 02:22:52 +08:00
36 changed files with 321 additions and 125 deletions

View File

@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
### Performance Improvements
* 申请证书时可以选择跳过本地dns校验 ([fe91d94](https://github.com/certd/certd/commit/fe91d94090d22ed0a3ea753ba74dfaa1bf057c17))
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
### Performance Improvements
* 上传到主机支持设置不mkdirs ([5ba9831](https://github.com/certd/certd/commit/5ba9831ed1aa6ec6057df246f1035b36b9c41d2e))
* 说明优化,默认值优化 ([970c7fd](https://github.com/certd/certd/commit/970c7fd8a0f557770e973d8462ee5684ef742810))
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
### Features

View File

@@ -1,13 +1,15 @@
# CertD
CertD 是一个免费全自动申请和部署SSL证书的工具。
CertD 是一个免费全自动申请和自动部署更新SSL证书的工具。
后缀D取自linux守护进程的命名风格意为证书守护进程。
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签
## 一、特性
本项目不仅支持证书申请过程自动化,还可以自动化部署证书,让你的证书永不过期。
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
* 全自动申请证书支持阿里云、腾讯云、华为云、Cloudflare注册的域名
* 全自动部署证书(目前支持服务器上传部署、部署到阿里云、腾讯云等)
* 全自动部署更新证书(目前支持服务器上传部署、部署到阿里云、腾讯云等)
* 支持通配符域名
* 支持多个域名打到一个证书上
* 邮件通知
@@ -108,8 +110,8 @@ http://your_server_ip:7001
* http-01 在网站根目录下放置一份txt文件
* dns-01 需要给域名添加txt解析记录通配符域名只能用这种方式
* 证书续期:
* 实际上acme并没有续期概念
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书。
* 实际上没有办法不改变证书文件本身情况下直接续期或者续签
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去
* 免费证书过期时间90天以后可能还会缩短所以自动化部署必不可少
* 设置每天自动运行当证书过期前20天会自动重新申请证书并部署
@@ -172,3 +174,7 @@ docker compose up -d
* [袖手GPT](https://ai.handsfree.work/) ChatGPT国内可用无需FQ每日免费额度
* [fast-crud](https://gitee.com/fast-crud/fast-crud/) 基于vue3的crud快速开发框架
* [dev-sidecar](https://github.com/docmirror/dev-sidecar/) 直连访问github工具无需FQ解决github无法访问的问题
## 十二、版本更新日志
https://github.com/certd/certd/blob/v2/CHANGELOG.md

View File

@@ -1,6 +1,5 @@
import http from 'axios'
import fs from 'fs'
//读取 packages/core/pipline/package.json的版本号
import {default as packageJson} from './packages/core/pipeline/package.json' assert { type: "json" };

View File

@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.21.0"
"version": "1.21.2"
}

View File

@@ -14,9 +14,10 @@
"i-all": "lerna link && lerna exec npm install ",
"publish": "npm run prepublishOnly1 && lerna publish --conventional-commits && npm run afterpublishOnly && npm run deploy1",
"afterpublishOnly": "",
"prepublishOnly1": "npm run before-build && lerna run build ",
"prepublishOnly1": "npm run check && npm run before-build && lerna run build ",
"before-build": "cd ./packages/core/acme-client && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
"deploy1": "node --experimental-json-modules deploy.js "
"deploy1": "node --experimental-json-modules deploy.js ",
"check": "node --experimental-json-modules publish-check.js"
},
"license": "AGPL-3.0",
"dependencies": {

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/publishlab/node-acme-client/compare/v1.21.1...v1.21.2) (2024-07-08)
**Note:** Version bump only for package @certd/acme-client
## [1.21.1](https://github.com/publishlab/node-acme-client/compare/v1.21.0...v1.21.1) (2024-07-08)
**Note:** Version bump only for package @certd/acme-client
# [1.21.0](https://github.com/publishlab/node-acme-client/compare/v1.20.17...v1.21.0) (2024-07-03)
### Features

View File

@@ -1 +1 @@
01:14
15:57

View File

@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.21.0",
"version": "1.21.2",
"main": "src/index.js",
"types": "types/index.d.ts",
"license": "MIT",

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
**Note:** Version bump only for package @certd/pipeline
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
**Note:** Version bump only for package @certd/pipeline
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
**Note:** Version bump only for package @certd/pipeline

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.21.0",
"version": "1.21.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -23,7 +23,7 @@
"qs": "^6.11.2"
},
"devDependencies": {
"@certd/acme-client": "workspace:^1.21.0",
"@certd/acme-client": "workspace:^1.21.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",

View File

@@ -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.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
### Performance Improvements
* 申请证书时可以选择跳过本地dns校验 ([fe91d94](https://github.com/certd/certd/commit/fe91d94090d22ed0a3ea753ba74dfaa1bf057c17))
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
### Performance Improvements
* 说明优化,默认值优化 ([970c7fd](https://github.com/certd/certd/commit/970c7fd8a0f557770e973d8462ee5684ef742810))
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
### Features

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-cert",
"private": false,
"version": "1.21.0",
"version": "1.21.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,8 +17,8 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/acme-client": "workspace:^1.21.0",
"@certd/pipeline": "workspace:^1.21.0",
"@certd/acme-client": "workspace:^1.21.2",
"@certd/pipeline": "workspace:^1.21.2",
"jszip": "^3.10.1",
"node-forge": "^0.10.0",
"psl": "^1.9.0"

View File

@@ -2,7 +2,7 @@ import { IsAccess, AccessInput } from "@certd/pipeline";
@IsAccess({
name: "eab",
title: "EABAccess",
title: "EAB授权",
desc: "ZeroSSL证书申请需要EAB授权",
})
export class EabAccess {

View File

@@ -18,12 +18,20 @@ export class AcmeService {
userContext: IContext;
logger: Logger;
sslProvider: SSLProvider;
skipLocalVerify = true;
eab?: ClientExternalAccountBindingOptions;
constructor(options: { userContext: IContext; logger: Logger; sslProvider: SSLProvider; eab?: ClientExternalAccountBindingOptions }) {
constructor(options: {
userContext: IContext;
logger: Logger;
sslProvider: SSLProvider;
eab?: ClientExternalAccountBindingOptions;
skipLocalVerify?: boolean;
}) {
this.userContext = options.userContext;
this.logger = options.logger;
this.sslProvider = options.sslProvider || "letsencrypt";
this.eab = options.eab;
this.skipLocalVerify = options.skipLocalVerify ?? false;
acme.setLogger((text: string) => {
this.logger.info(text);
});
@@ -192,7 +200,7 @@ export class AcmeService {
csr,
email: email,
termsOfServiceAgreed: true,
skipChallengeVerification: false,
skipChallengeVerification: this.skipLocalVerify,
challengePriority: ["dns-01"],
challengeCreateFn: async (authz: acme.Authorization, challenge: Challenge, keyAuthorization: string): Promise<any> => {
return await this.challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider);

View File

@@ -38,10 +38,10 @@ export class CertApplyPlugin extends AbstractTaskPlugin {
span: 24,
},
helper:
"支持通配符域名,例如: *.foo.com、foo.com、*.test.handsfree.work\n" +
"支持多个域名、多个子域名、多个通配符域名打到一个证书上域名必须是在同一个DNS提供商解析\n" +
"多级子域名要分成多个域名输入(*.foo.com的证书不能用于xxx.yyy.foo.com、foo.com\n" +
"输入一个回车之后,再输入下一个",
"1、支持通配符域名,例如: *.foo.com、foo.com、*.test.handsfree.work\n" +
"2、支持多个域名、多个子域名、多个通配符域名打到一个证书上域名必须是在同一个DNS提供商解析\n" +
"3、多级子域名要分成多个域名输入(*.foo.com的证书不能用于xxx.yyy.foo.com、foo.com\n" +
"4、输入一个回车之后,再输入下一个",
})
domains!: string;
@@ -58,7 +58,7 @@ export class CertApplyPlugin extends AbstractTaskPlugin {
@TaskInput({
title: "证书提供商",
value: "letsencrypt",
default: "letsencrypt",
component: {
name: "a-select",
vModel: "value",
@@ -109,6 +109,17 @@ export class CertApplyPlugin extends AbstractTaskPlugin {
})
dnsProviderAccess!: string;
@TaskInput({
title: "跳过本地校验DNS",
default: false,
component: {
name: "a-switch",
vModel: "checked",
},
helper: "如果重试多次出现Authorization not found TXT record导致无法申请成功请尝试开启此选项",
})
skipLocalVerify = false;
@TaskInput({
title: "更新天数",
component: {
@@ -165,7 +176,13 @@ export class CertApplyPlugin extends AbstractTaskPlugin {
if (this.eabAccessId) {
eab = await this.ctx.accessService.getById(this.eabAccessId);
}
this.acme = new AcmeService({ userContext: this.userContext, logger: this.logger, sslProvider: this.sslProvider, eab });
this.acme = new AcmeService({
userContext: this.userContext,
logger: this.logger,
sslProvider: this.sslProvider,
eab,
skipLocalVerify: this.skipLocalVerify,
});
}
async execute(): Promise<void> {

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
**Note:** Version bump only for package @certd/plugin-util
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
**Note:** Version bump only for package @certd/plugin-util
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
**Note:** Version bump only for package @certd/plugin-util

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-util",
"private": false,
"version": "1.21.0",
"version": "1.21.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -21,7 +21,7 @@
"shelljs": "^0.8.5"
},
"devDependencies": {
"@certd/pipeline": "workspace:^1.21.0",
"@certd/pipeline": "workspace:^1.21.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/certd/certd/compare/v1.21.1...v1.21.2) (2024-07-08)
**Note:** Version bump only for package @certd/ui-client
## [1.21.1](https://github.com/certd/certd/compare/v1.21.0...v1.21.1) (2024-07-08)
### Performance Improvements
* 说明优化,默认值优化 ([970c7fd](https://github.com/certd/certd/commit/970c7fd8a0f557770e973d8462ee5684ef742810))
# [1.21.0](https://github.com/certd/certd/compare/v1.20.17...v1.21.0) (2024-07-03)
**Note:** Version bump only for package @certd/ui-client

View File

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

View File

@@ -5,7 +5,7 @@
<fs-icon class="cd-icon-button" icon="ion:close-circle-outline" @click="clear"></fs-icon>
</span>
<span v-else class="mlr-5 gray">请选择</span>
<a-button @click="chooseForm.open">选择</a-button>
<a-button class="ml-5" @click="chooseForm.open">选择</a-button>
<a-form-item-rest v-if="chooseForm.show">
<a-modal v-model:open="chooseForm.show" title="选择授权提供者" width="700px" @ok="chooseForm.ok">
<div style="height: 400px; position: relative">
@@ -46,9 +46,9 @@ export default defineComponent({
}
}
function clear(){
function clear() {
selectedId.value = "";
target.value = null
target.value = null;
ctx.emit("update:modelValue", selectedId.value);
}
@@ -99,7 +99,6 @@ export default defineComponent({
}
});
return {
clear,
target,

View File

@@ -97,7 +97,6 @@ async function changePassword() {
const formOptions = buildFormOptions(passwordFormOptions);
formOptions.newInstance = true; //新实例打开
passwordFormRef.value = await openDialog(formOptions);
debugger;
console.log(passwordFormRef.value);
}
</script>

View File

@@ -1,7 +1,7 @@
import { compute } from "@fast-crud/fast-crud";
import { compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from "@fast-crud/fast-crud";
import { Dicts } from "./dicts";
export default function () {
export default function (): CreateCrudOptionsRet {
return {
crudOptions: {
form: {
@@ -12,7 +12,7 @@ export default function () {
columns: {
domains: {
title: "域名",
type: ["dict-select"],
type: "dict-select",
search: {
show: true,
component: {
@@ -58,6 +58,30 @@ export default function () {
rules: [{ required: true, type: "email", message: "请填写邮箱" }]
}
},
blank: {
title: "占位",
type: "text",
form: {
blank: true
}
},
sslProvider: {
title: "证书提供商",
type: "dict-select",
dict: Dicts.sslProviderDict
},
eabAccess: {
title: "EAB授权",
type: "dict-select",
form: {
component: {
name: "PiAccessSelector",
type: "eab",
vModel: "modelValue"
},
helper: "如果是ZeroSSL需要配置EAB授权https://app.zerossl.com/developer 生成 'EAB' "
}
},
dnsProviderType: {
title: "DNS提供商",
type: "dict-select",

View File

@@ -1,7 +1,12 @@
import { dict } from "@fast-crud/fast-crud";
export const Dicts = {
certIssuerDict: dict({ data: [{ value: "letencrypt", label: "LetEncrypt" }] }),
sslProviderDict: dict({
data: [
{ value: "letsencrypt", label: "Lets Encrypt" },
{ value: "zerossl", label: "ZeroSSL" }
]
}),
challengeTypeDict: dict({ data: [{ value: "dns", label: "DNS校验" }] }),
dnsProviderTypeDict: dict({
url: "pi/dnsProvider/dnsProviderTypeDict"

View File

@@ -9,7 +9,7 @@ import { ref } from "vue";
import _ from "lodash-es";
export default {
name: "PiCertdForm",
setup(props:any, ctx:any) {
setup(props: any, ctx: any) {
// 自定义表单配置
const { buildFormOptions } = useColumns();
//使用crudOptions结构来构建自定义表单配置
@@ -18,7 +18,7 @@ export default {
const formOptions = buildFormOptions(
_.merge(crudOptions, {
form: {
doSubmit({ form }:any) {
doSubmit({ form }: any) {
// 创建certd 的pipeline
doSubmitRef.value({ form });
}
@@ -29,7 +29,7 @@ export default {
const formWrapperRef = ref();
const formWrapperOptions = ref();
formWrapperOptions.value = formOptions;
function open(doSubmit:any) {
function open(doSubmit: any) {
doSubmitRef.value = doSubmit;
formWrapperRef.value.open(formWrapperOptions.value);
}

View File

@@ -7,6 +7,11 @@
<template #actionbar-right>
<!-- <span style="margin-left: 10px">出现<a-tag>Promise rejected attempt #18,retrying in 10000ms:No TXT recordsfound for name</a-tag>属于正常现象多重试几次</span>-->
</template>
<template #form-bottom>
<div>
申请证书
</div>
</template>
<pi-certd-form ref="certdFormRef"></pi-certd-form>
</fs-crud>
</fs-page>

View File

@@ -64,11 +64,11 @@
name: 'a-select',
vModel: 'value',
options: [
{ value: 0, label: '正常运行' },
{ value: 1, label: '成功后跳过' }
{ value: 0, label: '正常运行(证书申请任务请选择它)' },
{ value: 1, label: '成功后跳过(其他任务请选择它)' }
]
},
helper:'该任务运行成功一次之后下次运行是否跳过,证书申请任务务必选择正常运行',
helper: '该任务运行成功一次之后下次运行是否跳过,保持默认即可',
rules: [{ required: true, message: '此项必填' }]
}"
:get-context-fn="blankFn"
@@ -90,10 +90,10 @@ import { message, Modal } from "ant-design-vue";
import { computed, inject, Ref, ref } from "vue";
import _ from "lodash-es";
import { nanoid } from "nanoid";
import {CopyOutlined} from "@ant-design/icons-vue";
import { CopyOutlined } from "@ant-design/icons-vue";
export default {
name: "PiStepForm",
components:{CopyOutlined},
components: { CopyOutlined },
props: {
editMode: {
type: Boolean,
@@ -173,7 +173,7 @@ export default {
stepDrawerShow();
};
const stepAdd = (emit: any,stepDef:any) => {
const stepAdd = (emit: any, stepDef: any) => {
mode.value = "add";
const step: any = {
id: nanoid(),
@@ -183,7 +183,7 @@ export default {
input: {},
status: null
};
_.merge(step,stepDef)
_.merge(step, stepDef);
stepOpen(step, emit);
};
@@ -222,6 +222,10 @@ export default {
);
}
}
//设置初始值
if (input.default != null && currentStep.value.input[key] == null) {
currentStep.value.input[key] = input.default ?? input.value;
}
}
}

View File

@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.2](https://github.com/fast-crud/fast-server-js/compare/v1.21.1...v1.21.2) (2024-07-08)
**Note:** Version bump only for package @certd/ui-server
## [1.21.1](https://github.com/fast-crud/fast-server-js/compare/v1.21.0...v1.21.1) (2024-07-08)
### Performance Improvements
* 上传到主机支持设置不mkdirs ([5ba9831](https://github.com/fast-crud/fast-server-js/commit/5ba9831ed1aa6ec6057df246f1035b36b9c41d2e))
* 说明优化,默认值优化 ([970c7fd](https://github.com/fast-crud/fast-server-js/commit/970c7fd8a0f557770e973d8462ee5684ef742810))
# [1.21.0](https://github.com/fast-crud/fast-server-js/compare/v1.20.17...v1.21.0) (2024-07-03)
**Note:** Version bump only for package @certd/ui-server

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.21.0",
"version": "1.21.2",
"description": "fast-server base midway",
"private": true,
"scripts": {
@@ -24,10 +24,10 @@
"@alicloud/cs20151215": "^3.0.3",
"@alicloud/openapi-client": "^0.4.0",
"@alicloud/pop-core": "^1.7.10",
"@certd/acme-client": "^1.21.0",
"@certd/pipeline": "^1.21.0",
"@certd/plugin-cert": "^1.21.0",
"@certd/plugin-util": "^1.21.0",
"@certd/acme-client": "^1.21.2",
"@certd/pipeline": "^1.21.2",
"@certd/plugin-cert": "^1.21.2",
"@certd/plugin-util": "^1.21.2",
"@koa/cors": "^3.4.3",
"@midwayjs/bootstrap": "^3.15.0",
"@midwayjs/cache": "^3.14.0",

View File

@@ -45,7 +45,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
@TaskInput({
title: '大区',
value: 'cn-shanghai',
default: 'cn-shanghai',
component: {
placeholder: '集群所属大区',
},
@@ -55,7 +55,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
@TaskInput({
title: '命名空间',
value: 'default',
default: 'default',
component: {
placeholder: '命名空间',
},
@@ -64,7 +64,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
namespace!: string;
@TaskInput({
title: 'ingress名称',
value: '',
default: '',
component: {
placeholder: 'ingress名称',
},
@@ -74,7 +74,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
ingressName!: string;
@TaskInput({
title: 'ingress类型',
value: 'nginx',
default: 'nginx',
component: {
placeholder: '暂时只支持nginx类型',
},
@@ -83,8 +83,10 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
ingressClass!: string;
@TaskInput({
title: '是否私网ip',
value: false,
default: false,
component: {
name: 'a-switch',
vModel: 'checked',
placeholder: '集群连接端点是否是私网ip',
},
helper: '如果您当前certd运行在同一个私网下可以选择是。',

View File

@@ -30,7 +30,7 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
@TaskInput({
title: '大区',
value: 'cn-hangzhou',
default: 'cn-hangzhou',
component: {
name: 'a-select',
vModel: 'value',

View File

@@ -4,13 +4,13 @@ import path from 'path';
import _ from 'lodash';
import { ILogger } from '@certd/pipeline';
import iconv from 'iconv-lite';
import {SshAccess} from "../access";
import { SshAccess } from '../access';
export class AsyncSsh2Client {
conn: ssh2.Client;
logger: ILogger;
connConf: ssh2.ConnectConfig;
windows:boolean = false;
encoding:string;
windows = false;
encoding: string;
constructor(connConf: SshAccess, logger: ILogger) {
this.connConf = connConf;
this.logger = logger;
@@ -19,7 +19,7 @@ export class AsyncSsh2Client {
}
convert(buffer: Buffer) {
if(this.encoding){
if (this.encoding) {
return iconv.decode(buffer, this.encoding);
}
return buffer.toString();
@@ -77,7 +77,7 @@ export class AsyncSsh2Client {
reject(err);
return;
}
let data: string = '';
let data = '';
stream
.on('close', (code: any, signal: any) => {
this.logger.info(`[${this.connConf.host}][close]:code:${code}`);
@@ -88,14 +88,16 @@ export class AsyncSsh2Client {
}
})
.on('data', (ret: Buffer) => {
const out = this.convert(ret)
data += out
const out = this.convert(ret);
data += out;
this.logger.info(`[${this.connConf.host}][info]: ` + out.trimEnd());
})
.stderr.on('data', (ret:Buffer) => {
const err = this.convert(ret)
data += err
this.logger.info(`[${this.connConf.host}][error]: ` + err.trimEnd());
.stderr.on('data', (ret: Buffer) => {
const err = this.convert(ret);
data += err;
this.logger.info(
`[${this.connConf.host}][error]: ` + err.trimEnd()
);
});
});
});
@@ -118,15 +120,15 @@ export class AsyncSsh2Client {
resolve(output);
})
.on('data', (ret: Buffer) => {
const data = this.convert(ret)
const data = this.convert(ret);
this.logger.info('' + data);
output.push(data);
})
.stderr.on('data', (ret:Buffer) => {
const data = this.convert(ret)
.stderr.on('data', (ret: Buffer) => {
const data = this.convert(ret);
output.push(data);
this.logger.info(`[${this.connConf.host}][error]: ` + data);
});
});
stream.end(script + '\nexit\n');
});
});
@@ -153,30 +155,39 @@ export class SshClient {
}
* @param options
*/
async uploadFiles(options: { connectConf: SshAccess; transports: any }) {
const { connectConf, transports } = options;
async uploadFiles(options: {
connectConf: SshAccess;
transports: any;
mkdirs: boolean;
}) {
const { connectConf, transports, mkdirs } = options;
await this._call({
connectConf,
callable: async (conn: AsyncSsh2Client) => {
const sftp = await conn.getSftp();
this.logger.info('开始上传');
for (const transport of transports) {
let filePath = path.dirname(transport.remotePath);
let mkdirCmd = `mkdir -p ${filePath} `;
if(conn.windows){
if(filePath.indexOf("/") > -1){
this.logger.info("--------------------------")
this.logger.info("请注意windows下文件目录分隔应该写成\\而不是/")
this.logger.info("--------------------------")
}
const spec = await conn.exec(`echo %COMSPEC%`);
if (spec.toString().trim() === '%COMSPEC%') {
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
} else {
mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`;
if (mkdirs !== false) {
const filePath = path.dirname(transport.remotePath);
let mkdirCmd = `mkdir -p ${filePath} `;
if (conn.windows) {
if (filePath.indexOf('/') > -1) {
this.logger.info('--------------------------');
this.logger.info(
'请注意windows下文件目录分隔应该写成\\而不是/'
);
this.logger.info('--------------------------');
}
const spec = await conn.exec('echo %COMSPEC%');
if (spec.toString().trim() === '%COMSPEC%') {
mkdirCmd = `New-Item -ItemType Directory -Path "${filePath}" -Force`;
} else {
mkdirCmd = `if not exist "${filePath}" mkdir "${filePath}"`;
}
}
await conn.exec(mkdirCmd);
}
await conn.exec(mkdirCmd);
await conn.fastPut({ sftp, ...transport });
}
this.logger.info('文件全部上传成功');

View File

@@ -10,7 +10,7 @@ import {
import { SshClient } from '../../lib/ssh';
import { CertInfo, CertReader } from '@certd/plugin-cert';
import * as fs from 'fs';
import {SshAccess} from "../../access";
import { SshAccess } from '../../access';
@IsTaskPlugin({
name: 'uploadCertToHost',
@@ -48,6 +48,7 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin {
required: true,
})
cert!: CertInfo;
@TaskInput({
title: '主机登录配置',
helper: 'access授权',
@@ -59,13 +60,24 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin {
})
accessId!: string;
@TaskInput({
title: '自动创建远程目录',
helper: '是否自动创建远程目录,如果关闭则你需要自己确保远程目录存在',
default: true,
component: {
name: 'a-switch',
vModel: 'checked',
},
})
mkdirs = true;
@TaskInput({
title: '仅复制到当前主机',
helper:
'开启后将直接复制到当前主机某个目录不上传到主机由于是docker启动实际上是复制到docker容器内的“证书保存路径”你需要事先在docker-compose.yaml中配置主机目录映射 volumes: /your_target_path:/your_target_path',
default: false,
component: {
name: 'a-switch',
value: false,
vModel: 'checked',
},
})
@@ -102,39 +114,58 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin {
this.logger.info('将证书写入本地缓存文件');
const saveCrtPath = certReader.saveToFile('crt');
const saveKeyPath = certReader.saveToFile('key');
if (this.copyToThisHost) {
this.logger.info('复制到目标路径');
this.copyFile(saveCrtPath, crtPath);
this.copyFile(saveKeyPath, keyPath);
this.logger.info('证书复制成功crtPath=', crtPath, ',keyPath=', keyPath);
} else {
if (!accessId) {
throw new Error('主机登录授权配置不能为空');
this.logger.info('本地文件写入成功');
try {
if (this.copyToThisHost) {
this.logger.info('复制到目标路径');
this.copyFile(saveCrtPath, crtPath);
this.copyFile(saveKeyPath, keyPath);
this.logger.info(
'证书复制成功crtPath=',
crtPath,
',keyPath=',
keyPath
);
} else {
if (!accessId) {
throw new Error('主机登录授权配置不能为空');
}
this.logger.info('准备上传文件到服务器');
const connectConf: SshAccess = await this.accessService.getById(
accessId
);
const sshClient = new SshClient(this.logger);
await sshClient.uploadFiles({
connectConf,
transports: [
{
localPath: saveCrtPath,
remotePath: crtPath,
},
{
localPath: saveKeyPath,
remotePath: keyPath,
},
],
mkdirs: this.mkdirs,
});
this.logger.info(
'证书上传成功crtPath=',
crtPath,
',keyPath=',
keyPath
);
}
this.logger.info('准备上传到服务器');
const connectConf:SshAccess = await this.accessService.getById(accessId);
const sshClient = new SshClient(this.logger);
await sshClient.uploadFiles({
connectConf,
transports: [
{
localPath: saveCrtPath,
remotePath: crtPath,
},
{
localPath: saveKeyPath,
remotePath: keyPath,
},
],
});
this.logger.info('证书上传成功crtPath=', crtPath, ',keyPath=', keyPath);
} catch (e) {
this.logger.error(`上传失败:${e.message}`);
throw e;
} finally {
//删除临时文件
this.logger.info('删除临时文件');
fs.unlinkSync(saveCrtPath);
fs.unlinkSync(saveKeyPath);
}
//删除临时文件
fs.unlinkSync(saveCrtPath);
fs.unlinkSync(saveKeyPath);
this.logger.info('执行完成');
//输出
this.hostCrtPath = crtPath;
this.hostKeyPath = keyPath;

View File

@@ -10,7 +10,7 @@ import { DnspodAccess } from '../access';
@IsDnsProvider({
name: 'dnspod',
title: 'dnspod(已过时)',
title: 'dnspod(已过时,请尽快换成腾讯云)',
desc: '请尽快换成腾讯云类型',
accessType: 'dnspod',
})

View File

@@ -24,7 +24,7 @@ import dayjs from 'dayjs';
export class DeployToClbPlugin extends AbstractTaskPlugin {
@TaskInput({
title: '大区',
value: 'ap-guangzhou',
default: 'ap-guangzhou',
component: {
name: 'a-select',
options: [{ value: 'ap-guangzhou' }],

13
publish-check.js Normal file
View File

@@ -0,0 +1,13 @@
import fs from 'fs'
function check(){
const gitAdd = fs.readFileSync("./node_modules/@lerna-lite/version/dist/lib/git-add.js","utf-8")
if(gitAdd.indexOf("('git', ['add', '.']") > -1){
console.log("git-add 已经修改过了")
}else{
console.error("git-add 没有修改过")
throw new Error("git-add 还没修改过")
}
}
check()

View File

@@ -2,6 +2,8 @@
本示例演示从创建证书申请任务到自动部署证书全流程
> 申请证书->部署证书->设置定时执行->设置邮件通知
## 准备工作
1. 已部署CertD服务可官方Demo自助注册体验 https://certd.handsfree.work/
2. 注册一个域名支持阿里云万网、腾讯云DnsPod、华为云