mirror of
https://github.com/certd/certd.git
synced 2026-07-17 11:37:32 +08:00
chore: format
This commit is contained in:
@@ -1 +1 @@
|
||||
export * from './plugins/index.js';
|
||||
export * from "./plugins/index.js";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from './plugin-wait.js';
|
||||
export * from './plugin-deploy-to-mail.js';
|
||||
export * from './plugin-webhook.js';
|
||||
export * from "./plugin-wait.js";
|
||||
export * from "./plugin-deploy-to-mail.js";
|
||||
export * from "./plugin-webhook.js";
|
||||
|
||||
+63
-68
@@ -1,13 +1,13 @@
|
||||
import { AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AbstractTaskPlugin, FileItem, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { CertInfo, CertReader } from "@certd/plugin-cert";
|
||||
import dayjs from "dayjs";
|
||||
import { get } from 'lodash-es';
|
||||
import { get } from "lodash-es";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToMailPlugin',
|
||||
title: '邮件发送证书',
|
||||
icon: 'ion:mail-outline',
|
||||
desc: '通过邮件发送证书',
|
||||
name: "DeployCertToMailPlugin",
|
||||
title: "邮件发送证书",
|
||||
icon: "ion:mail-outline",
|
||||
desc: "通过邮件发送证书",
|
||||
group: pluginGroups.other.key,
|
||||
showRunStrategy: false,
|
||||
default: {
|
||||
@@ -17,12 +17,11 @@ import { get } from 'lodash-es';
|
||||
},
|
||||
})
|
||||
export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
|
||||
@TaskInput({
|
||||
title: '域名证书',
|
||||
helper: '请选择前置任务输出的域名证书',
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
name: "output-selector",
|
||||
from: [":cert:"],
|
||||
},
|
||||
required: true,
|
||||
@@ -30,10 +29,10 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput({
|
||||
title: '证书压缩文件',
|
||||
helper: '请选择前置任务输出的域名证书压缩文件',
|
||||
title: "证书压缩文件",
|
||||
helper: "请选择前置任务输出的域名证书压缩文件",
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
name: "output-selector",
|
||||
from: [":certZip:"],
|
||||
},
|
||||
required: true,
|
||||
@@ -41,17 +40,16 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
certZip!: FileItem;
|
||||
|
||||
@TaskInput({
|
||||
title: '接收邮箱',
|
||||
title: "接收邮箱",
|
||||
component: {
|
||||
name: 'EmailSelector',
|
||||
vModel: 'value',
|
||||
name: "EmailSelector",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
email!: string[];
|
||||
|
||||
|
||||
/**
|
||||
* title:
|
||||
* title: 邮件标题
|
||||
@@ -77,60 +75,57 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
* required: false
|
||||
*/
|
||||
|
||||
// @TaskInput({
|
||||
// title: '邮件标题',
|
||||
// component: {
|
||||
// name: 'a-input',
|
||||
// vModel: 'value',
|
||||
// placeholder: `证书申请成功【$\{mainDomain}】`,
|
||||
// },
|
||||
// helper: '请输入邮件标题否则将使用默认标题\n模板变量:主域名=$\{mainDomain}、全部域名=$\{domains}、过期时间=$\{expiresTime}、备注=$\{remark}、证书PEM=$\{crt}、证书私钥=$\{key}、中间证书/CA证书=$\{ic}',
|
||||
// required: false,
|
||||
// })
|
||||
// title!: string;
|
||||
|
||||
// @TaskInput({
|
||||
// title: '邮件标题',
|
||||
// component: {
|
||||
// name: 'a-input',
|
||||
// vModel: 'value',
|
||||
// placeholder: `证书申请成功【$\{mainDomain}】`,
|
||||
// },
|
||||
// helper: '请输入邮件标题否则将使用默认标题\n模板变量:主域名=$\{mainDomain}、全部域名=$\{domains}、过期时间=$\{expiresTime}、备注=$\{remark}、证书PEM=$\{crt}、证书私钥=$\{key}、中间证书/CA证书=$\{ic}',
|
||||
// required: false,
|
||||
// })
|
||||
// title!: string;
|
||||
|
||||
// @TaskInput({
|
||||
// title: '邮件模版',
|
||||
// component: {
|
||||
// name: 'a-textarea',
|
||||
// vModel: 'value',
|
||||
// autosize: {
|
||||
// minRows: 6,
|
||||
// maxRows: 10,
|
||||
// },
|
||||
// placeholder: `
|
||||
// <div>
|
||||
// <p>证书申请成功</p>
|
||||
// <p>域名:$\{domains}</p>
|
||||
// <p>证书有效期:$\{expiresTime}</p>
|
||||
// <p>备注:$\{remark}</p>
|
||||
// </div>
|
||||
// `,
|
||||
// },
|
||||
// helper: `请输入模版内容否则将使用默认模版,模板变量同上`,
|
||||
// required: false,
|
||||
// })
|
||||
// template!: string;
|
||||
// @TaskInput({
|
||||
// title: '邮件模版',
|
||||
// component: {
|
||||
// name: 'a-textarea',
|
||||
// vModel: 'value',
|
||||
// autosize: {
|
||||
// minRows: 6,
|
||||
// maxRows: 10,
|
||||
// },
|
||||
// placeholder: `
|
||||
// <div>
|
||||
// <p>证书申请成功</p>
|
||||
// <p>域名:$\{domains}</p>
|
||||
// <p>证书有效期:$\{expiresTime}</p>
|
||||
// <p>备注:$\{remark}</p>
|
||||
// </div>
|
||||
// `,
|
||||
// },
|
||||
// helper: `请输入模版内容否则将使用默认模版,模板变量同上`,
|
||||
// required: false,
|
||||
// })
|
||||
// template!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: '备注',
|
||||
title: "备注",
|
||||
component: {
|
||||
name: 'a-input',
|
||||
vModel: 'value',
|
||||
name: "a-input",
|
||||
vModel: "value",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
remark!: string;
|
||||
|
||||
async onInstance() { }
|
||||
async onInstance() {}
|
||||
async execute(): Promise<void> {
|
||||
|
||||
this.logger.info(`开始发送邮件`);
|
||||
const certReader = new CertReader(this.cert)
|
||||
const certReader = new CertReader(this.cert);
|
||||
const mainDomain = certReader.getMainDomain();
|
||||
const domains = certReader.getAllDomains().join(',');
|
||||
|
||||
const domains = certReader.getAllDomains().join(",");
|
||||
|
||||
const data: any = {
|
||||
mainDomain,
|
||||
@@ -140,20 +135,20 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
crt: this.cert.crt,
|
||||
key: this.cert.key,
|
||||
ic: this.cert.ic,
|
||||
url: ""
|
||||
}
|
||||
url: "",
|
||||
};
|
||||
|
||||
let title = `证书申请成功【${mainDomain}】`;
|
||||
let content = `证书申请成功
|
||||
const title = `证书申请成功【${mainDomain}】`;
|
||||
const content = `证书申请成功
|
||||
域名:${domains}
|
||||
证书有效期:${data.expiresTime}
|
||||
备注:${this.remark || ""}
|
||||
`;
|
||||
data.content = content;
|
||||
data.title = title
|
||||
const file = this.certZip
|
||||
data.title = title;
|
||||
const file = this.certZip;
|
||||
if (!file) {
|
||||
throw new Error('证书压缩文件还未生成,重新运行证书任务');
|
||||
throw new Error("证书压缩文件还未生成,重新运行证书任务");
|
||||
}
|
||||
await this.ctx.emailService.sendByTemplate({
|
||||
type: "sendCert",
|
||||
@@ -165,13 +160,13 @@ export class DeployCertToMailPlugin extends AbstractTaskPlugin {
|
||||
path: file.path,
|
||||
},
|
||||
],
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
compile(templateString: string) {
|
||||
return function (data) {
|
||||
return templateString.replace(/\${(.*?)}/g, (match, key) => {
|
||||
const value = get(data, key, '');
|
||||
const value = get(data, key, "");
|
||||
return String(value);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'WaitPlugin',
|
||||
title: '等待',
|
||||
icon: 'ri:rest-time-line',
|
||||
desc: '等待一段时间',
|
||||
name: "WaitPlugin",
|
||||
title: "等待",
|
||||
icon: "ri:rest-time-line",
|
||||
desc: "等待一段时间",
|
||||
group: pluginGroups.other.key,
|
||||
showRunStrategy:true,
|
||||
showRunStrategy: true,
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
@@ -15,13 +15,13 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
||||
})
|
||||
export class WaitPlugin extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: '等待时长',
|
||||
title: "等待时长",
|
||||
value: 30,
|
||||
component: {
|
||||
name: 'a-input-number',
|
||||
vModel: 'value',
|
||||
name: "a-input-number",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: '单位:秒',
|
||||
helper: "单位:秒",
|
||||
required: true,
|
||||
})
|
||||
waitTime!: number;
|
||||
@@ -30,7 +30,7 @@ export class WaitPlugin extends AbstractTaskPlugin {
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info(`等待${this.waitTime}s`);
|
||||
await this.ctx.utils.sleep(this.waitTime * 1000);
|
||||
this.logger.info('等待结束');
|
||||
this.logger.info("等待结束");
|
||||
}
|
||||
}
|
||||
new WaitPlugin();
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import qs from 'qs';
|
||||
import {
|
||||
AbstractTaskPlugin,
|
||||
IsTaskPlugin,
|
||||
pluginGroups,
|
||||
RunStrategy,
|
||||
TaskInput
|
||||
} from '@certd/pipeline';
|
||||
import {CertApplyPluginNames, CertInfo, CertReader} from "@certd/plugin-cert";
|
||||
import qs from "qs";
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'WebhookDeployCert',
|
||||
title: 'webhook方式部署证书',
|
||||
icon: 'ion:send-sharp',
|
||||
desc: '调用webhook部署证书',
|
||||
name: "WebhookDeployCert",
|
||||
title: "webhook方式部署证书",
|
||||
icon: "ion:send-sharp",
|
||||
desc: "调用webhook部署证书",
|
||||
group: pluginGroups.other.key,
|
||||
showRunStrategy: false,
|
||||
default: {
|
||||
@@ -22,85 +16,84 @@ import {CertApplyPluginNames, CertInfo, CertReader} from "@certd/plugin-cert";
|
||||
},
|
||||
})
|
||||
export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames]
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true
|
||||
required: true,
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput({
|
||||
title: 'webhook地址',
|
||||
title: "webhook地址",
|
||||
component: {
|
||||
placeholder: 'https://xxxxx.com/xxxx',
|
||||
placeholder: "https://xxxxx.com/xxxx",
|
||||
},
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
webhook = '';
|
||||
webhook = "";
|
||||
|
||||
@TaskInput({
|
||||
title: '请求方式',
|
||||
value: 'POST',
|
||||
title: "请求方式",
|
||||
value: "POST",
|
||||
component: {
|
||||
name: 'a-select',
|
||||
placeholder: 'post/put/get',
|
||||
name: "a-select",
|
||||
placeholder: "post/put/get",
|
||||
options: [
|
||||
{value: 'POST', label: 'POST'},
|
||||
{value: 'PUT', label: 'PUT'},
|
||||
{value: 'GET', label: 'GET'},
|
||||
{ value: "POST", label: "POST" },
|
||||
{ value: "PUT", label: "PUT" },
|
||||
{ value: "GET", label: "GET" },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
method = '';
|
||||
method = "";
|
||||
|
||||
@TaskInput({
|
||||
title: 'ContentType',
|
||||
value: 'application/json',
|
||||
title: "ContentType",
|
||||
value: "application/json",
|
||||
component: {
|
||||
name: 'a-auto-complete',
|
||||
name: "a-auto-complete",
|
||||
options: [
|
||||
{value: 'application/json', label: 'application/json'},
|
||||
{value: 'application/x-www-form-urlencoded', label: 'application/x-www-form-urlencoded'},
|
||||
{ value: "application/json", label: "application/json" },
|
||||
{ value: "application/x-www-form-urlencoded", label: "application/x-www-form-urlencoded" },
|
||||
],
|
||||
},
|
||||
helper: '也可以自定义填写',
|
||||
helper: "也可以自定义填写",
|
||||
required: true,
|
||||
})
|
||||
contentType = '';
|
||||
contentType = "";
|
||||
|
||||
@TaskInput({
|
||||
title: 'Headers',
|
||||
title: "Headers",
|
||||
component: {
|
||||
name: 'a-textarea',
|
||||
vModel: 'value',
|
||||
name: "a-textarea",
|
||||
vModel: "value",
|
||||
rows: 2,
|
||||
},
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
helper: '一行一个,格式为key=value',
|
||||
helper: "一行一个,格式为key=value",
|
||||
required: false,
|
||||
})
|
||||
headers = '';
|
||||
headers = "";
|
||||
|
||||
@TaskInput({
|
||||
title: '消息body模版',
|
||||
title: "消息body模版",
|
||||
value: `{
|
||||
"id":"123",
|
||||
"crt":"\${crt}",
|
||||
"key":"\${key}"
|
||||
}`,
|
||||
component: {
|
||||
name: 'a-textarea',
|
||||
name: "a-textarea",
|
||||
rows: 4,
|
||||
},
|
||||
col: {
|
||||
@@ -112,29 +105,28 @@ export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
变量列表:\${domain} 主域名、\${domains} 全部域名、\${crt} 证书、\${key} 私钥、\${ic} 中间证书、\${one} 一体证书、\${der} der证书(base64)、\${pfx} pfx证书(base64)、\${jks} jks证书(base64)、`,
|
||||
required: true,
|
||||
})
|
||||
template = '';
|
||||
template = "";
|
||||
|
||||
@TaskInput({
|
||||
title: '忽略证书校验',
|
||||
title: "忽略证书校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: 'a-switch',
|
||||
vModel: 'checked',
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
skipSslVerify: boolean;
|
||||
|
||||
|
||||
@TaskInput({
|
||||
title: '成功判定',
|
||||
title: "成功判定",
|
||||
helper: "返回结果中包含此字符串则表示部署成功,不填则仅通过statusCode判定",
|
||||
component: {
|
||||
name: 'a-input',
|
||||
name: "a-input",
|
||||
placeholder: '例如: status:"success"',
|
||||
},
|
||||
})
|
||||
successStr = '';
|
||||
successStr = "";
|
||||
|
||||
replaceTemplate(target: string, body: any, urlEncode = false) {
|
||||
let bodyStr = target;
|
||||
@@ -143,34 +135,32 @@ export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
let value = urlEncode ? encodeURIComponent(body[key]) : body[key];
|
||||
value = value.replaceAll(`\n`, "\\n");
|
||||
bodyStr = bodyStr.replaceAll(`\${${key}}`, value);
|
||||
|
||||
}
|
||||
return bodyStr;
|
||||
}
|
||||
|
||||
async send() {
|
||||
if (!this.template) {
|
||||
throw new Error('模版不能为空');
|
||||
throw new Error("模版不能为空");
|
||||
}
|
||||
if (!this.webhook) {
|
||||
throw new Error('webhook不能为空');
|
||||
throw new Error("webhook不能为空");
|
||||
}
|
||||
|
||||
|
||||
const certReader = new CertReader(this.cert)
|
||||
const certReader = new CertReader(this.cert);
|
||||
|
||||
const replaceBody = {
|
||||
domain: certReader.getMainDomain(),
|
||||
domains: certReader.getAllDomains().join(","),
|
||||
...this.cert
|
||||
...this.cert,
|
||||
};
|
||||
const bodyStr = this.replaceTemplate(this.template, replaceBody);
|
||||
let data = JSON.parse(bodyStr);
|
||||
|
||||
let url = this.webhook;
|
||||
if (this.method.toLowerCase() === 'get') {
|
||||
if (this.method.toLowerCase() === "get") {
|
||||
const query = qs.stringify(data);
|
||||
if (url.includes('?')) {
|
||||
if (url.includes("?")) {
|
||||
url = `${url}&${query}`;
|
||||
} else {
|
||||
url = `${url}?${query}`;
|
||||
@@ -180,12 +170,12 @@ export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
|
||||
const headers: any = {};
|
||||
if (this.headers && this.headers.trim()) {
|
||||
this.headers.split('\n').forEach(item => {
|
||||
this.headers.split("\n").forEach(item => {
|
||||
item = item.trim();
|
||||
if (item) {
|
||||
const eqIndex = item.indexOf('=');
|
||||
const eqIndex = item.indexOf("=");
|
||||
if (eqIndex <= 0) {
|
||||
this.logger.warn('header格式错误,请使用=号分割', item);
|
||||
this.logger.warn("header格式错误,请使用=号分割", item);
|
||||
return;
|
||||
}
|
||||
const key = item.substring(0, eqIndex);
|
||||
@@ -194,23 +184,23 @@ export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
let res = null
|
||||
let res = null;
|
||||
try {
|
||||
res = await this.http.request({
|
||||
url: url,
|
||||
method: this.method,
|
||||
headers: {
|
||||
'Content-Type': `${this.contentType}; charset=UTF-8`,
|
||||
"Content-Type": `${this.contentType}; charset=UTF-8`,
|
||||
...headers,
|
||||
},
|
||||
data: data,
|
||||
skipSslVerify: this.skipSslVerify,
|
||||
responseType: "text",
|
||||
returnOriginRes: true
|
||||
returnOriginRes: true,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.response?.data) {
|
||||
throw new Error(e.message + ',' + JSON.stringify(e.response.data));
|
||||
throw new Error(e.message + "," + JSON.stringify(e.response.data));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
@@ -218,16 +208,15 @@ export class WebhookDeployCert extends AbstractTaskPlugin {
|
||||
if (this.successStr && !res?.data?.includes(this.successStr)) {
|
||||
throw new Error(`请求失败,期望包含:${this.successStr},实际返回:${res.data}`);
|
||||
}
|
||||
return res
|
||||
return res;
|
||||
}
|
||||
|
||||
async onInstance() {
|
||||
}
|
||||
async onInstance() {}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info(`通过webhook部署开始`);
|
||||
await this.send();
|
||||
this.logger.info('部署成功');
|
||||
this.logger.info("部署成功");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user