mirror of https://github.com/certd/certd
perf: 支持群晖
parent
18718f6a25
commit
5c270b6b9d
|
@ -1,6 +1,4 @@
|
||||||
import { AxiosInstance } from "axios";
|
|
||||||
import { IContext } from "../core/index.js";
|
import { IContext } from "../core/index.js";
|
||||||
|
|
||||||
export type HttpClient = AxiosInstance;
|
|
||||||
export type UserContext = IContext;
|
export type UserContext = IContext;
|
||||||
export type PipelineContext = IContext;
|
export type PipelineContext = IContext;
|
||||||
|
|
|
@ -93,7 +93,7 @@ export class Executor {
|
||||||
await this.notification("success");
|
await this.notification("success");
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
await this.notification("error", e);
|
await this.notification("error", e);
|
||||||
this.logger.error("pipeline 执行失败", e.stack);
|
this.logger.error("pipeline 执行失败", e);
|
||||||
} finally {
|
} finally {
|
||||||
clearInterval(intervalFlushLogId);
|
clearInterval(intervalFlushLogId);
|
||||||
await this.onChanged(this.runtime);
|
await this.onChanged(this.runtime);
|
||||||
|
@ -237,14 +237,13 @@ export class Executor {
|
||||||
//判断是否需要跳过
|
//判断是否需要跳过
|
||||||
const lastNode = this.lastStatusMap.get(step.id);
|
const lastNode = this.lastStatusMap.get(step.id);
|
||||||
const lastResult = lastNode?.status?.status;
|
const lastResult = lastNode?.status?.status;
|
||||||
|
let inputChanged = true;
|
||||||
|
const lastInputHash = lastNode?.status?.inputHash;
|
||||||
|
if (lastInputHash && newInputHash && lastInputHash === newInputHash) {
|
||||||
|
//参数有变化
|
||||||
|
inputChanged = false;
|
||||||
|
}
|
||||||
if (step.strategy?.runStrategy === RunStrategy.SkipWhenSucceed) {
|
if (step.strategy?.runStrategy === RunStrategy.SkipWhenSucceed) {
|
||||||
//如果是成功后跳过策略
|
|
||||||
let inputChanged = true;
|
|
||||||
const lastInputHash = lastNode?.status?.inputHash;
|
|
||||||
if (lastInputHash && newInputHash && lastInputHash === newInputHash) {
|
|
||||||
//参数有变化
|
|
||||||
inputChanged = false;
|
|
||||||
}
|
|
||||||
if (lastResult != null && lastResult === ResultType.success && !inputChanged) {
|
if (lastResult != null && lastResult === ResultType.success && !inputChanged) {
|
||||||
step.status!.output = lastNode?.status?.output;
|
step.status!.output = lastNode?.status?.output;
|
||||||
step.status!.files = lastNode?.status?.files;
|
step.status!.files = lastNode?.status?.files;
|
||||||
|
@ -259,6 +258,7 @@ export class Executor {
|
||||||
lastStatus,
|
lastStatus,
|
||||||
http,
|
http,
|
||||||
logger: currentLogger,
|
logger: currentLogger,
|
||||||
|
inputChanged,
|
||||||
accessService: this.options.accessService,
|
accessService: this.options.accessService,
|
||||||
emailService: this.options.emailService,
|
emailService: this.options.emailService,
|
||||||
pipelineContext: this.pipelineContext,
|
pipelineContext: this.pipelineContext,
|
||||||
|
|
|
@ -107,8 +107,8 @@ export class RunHistory {
|
||||||
|
|
||||||
logError(runnable: Runnable, e: Error) {
|
logError(runnable: Runnable, e: Error) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const errorInfo = runnable.runnableType == "step" ? e.stack : e.message;
|
const errorInfo = runnable.runnableType === "step" ? e : e.message;
|
||||||
this._loggers[runnable.id].error(`[${runnable.runnableType}] [${runnable.title}]<id:${runnable.id}> :${errorInfo}`);
|
this._loggers[runnable.id].error(`[${runnable.runnableType}] [${runnable.title}]<id:${runnable.id}> :`, errorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
finally(runnable: Runnable) {
|
finally(runnable: Runnable) {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import { Logger } from "log4js";
|
||||||
import { IAccessService } from "../access/index.js";
|
import { IAccessService } from "../access/index.js";
|
||||||
import { IEmailService } from "../service/index.js";
|
import { IEmailService } from "../service/index.js";
|
||||||
import { IContext } from "../core/index.js";
|
import { IContext } from "../core/index.js";
|
||||||
import { AxiosInstance } from "axios";
|
|
||||||
import { ILogger, logger } from "../utils/index.js";
|
import { ILogger, logger } from "../utils/index.js";
|
||||||
|
import { HttpClient } from "../utils/util.request";
|
||||||
|
|
||||||
export enum ContextScope {
|
export enum ContextScope {
|
||||||
global,
|
global,
|
||||||
|
@ -60,11 +60,12 @@ export type TaskInstanceContext = {
|
||||||
pipeline: Pipeline;
|
pipeline: Pipeline;
|
||||||
step: Step;
|
step: Step;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
|
inputChanged: boolean;
|
||||||
accessService: IAccessService;
|
accessService: IAccessService;
|
||||||
emailService: IEmailService;
|
emailService: IEmailService;
|
||||||
pipelineContext: IContext;
|
pipelineContext: IContext;
|
||||||
userContext: IContext;
|
userContext: IContext;
|
||||||
http: AxiosInstance;
|
http: HttpClient;
|
||||||
fileStore: FileStore;
|
fileStore: FileStore;
|
||||||
lastStatus?: Runnable;
|
lastStatus?: Runnable;
|
||||||
signal: AbortSignal;
|
signal: AbortSignal;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import sleep from "./util.sleep.js";
|
import sleep from "./util.sleep.js";
|
||||||
import { request } from "./util.request.js";
|
import { http } from "./util.request.js";
|
||||||
|
export * from "./util.request.js";
|
||||||
export * from "./util.log.js";
|
export * from "./util.log.js";
|
||||||
export * from "./util.file.js";
|
export * from "./util.file.js";
|
||||||
export * from "./util.sp.js";
|
export * from "./util.sp.js";
|
||||||
|
@ -7,5 +8,5 @@ export * as promises from "./util.promise.js";
|
||||||
export * from "./util.hash.js";
|
export * from "./util.hash.js";
|
||||||
export const utils = {
|
export const utils = {
|
||||||
sleep,
|
sleep,
|
||||||
http: request,
|
http,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +1,39 @@
|
||||||
import axios from "axios";
|
import axios, { AxiosRequestConfig } from "axios";
|
||||||
import { logger } from "./util.log.js";
|
import { logger } from "./util.log.js";
|
||||||
import { Logger } from "log4js";
|
import { Logger } from "log4js";
|
||||||
|
|
||||||
export class HttpError extends Error {
|
export class HttpError extends Error {
|
||||||
request?: { url: string; method: string; data?: any };
|
|
||||||
response?: { data: any };
|
|
||||||
status?: number;
|
status?: number;
|
||||||
statusText?: string;
|
statusText?: string;
|
||||||
|
code?: string;
|
||||||
|
request?: { url: string; method: string; params?: any; data?: any };
|
||||||
|
response?: { data: any };
|
||||||
|
cause?: any;
|
||||||
constructor(error: any) {
|
constructor(error: any) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super(error.message);
|
super(error.message);
|
||||||
this.name = error.name;
|
this.name = error.name;
|
||||||
this.stack = error.stack;
|
this.code = error.code;
|
||||||
this.status = error?.response?.status;
|
this.cause = error.cause;
|
||||||
this.statusText = error?.response?.statusText;
|
|
||||||
|
this.status = error.response?.status;
|
||||||
|
this.statusText = error.response?.statusText;
|
||||||
this.request = {
|
this.request = {
|
||||||
url: error?.response?.config?.url,
|
url: error.config?.url,
|
||||||
method: error?.response?.config?.method,
|
method: error.config?.method,
|
||||||
data: error?.response?.config?.data,
|
params: error.config?.params,
|
||||||
|
data: error.config?.data,
|
||||||
};
|
};
|
||||||
this.response = {
|
this.response = {
|
||||||
data: error?.response?.data,
|
data: error.response?.data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
delete error.response;
|
||||||
|
delete error.config;
|
||||||
|
delete error.request;
|
||||||
|
logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +45,7 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||||
// 请求拦截
|
// 请求拦截
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config: any) => {
|
(config: any) => {
|
||||||
logger.info(`http request:${config.url},method:${config.method}`);
|
logger.info(`http request:${config.url},method:${config.method},params:${JSON.stringify(config.params)}`);
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error: Error) => {
|
(error: Error) => {
|
||||||
|
@ -67,9 +77,10 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||||
// default: break
|
// default: break
|
||||||
// }
|
// }
|
||||||
logger.error(
|
logger.error(
|
||||||
`请求出错:status:${error?.response?.status},statusText:${error?.response?.statusText},url:${error?.config?.url},method:${error?.config?.method}。`
|
`请求出错:status:${error.response?.status},statusText:${error.response?.statusText},url:${error.config?.url},method:${error.config?.method}。`
|
||||||
);
|
);
|
||||||
logger.error("返回数据:", JSON.stringify(error?.response?.data));
|
logger.error("返回数据:", JSON.stringify(error.response?.data));
|
||||||
|
|
||||||
if (error instanceof AggregateError) {
|
if (error instanceof AggregateError) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
|
@ -80,4 +91,8 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const request = createAxiosService({ logger });
|
export const http = createAxiosService({ logger }) as HttpClient;
|
||||||
|
export type HttpClientResponse<R> = any;
|
||||||
|
export type HttpClient = {
|
||||||
|
request<D = any, R = any>(config: AxiosRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
||||||
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "PFX密码",
|
title: "PFX证书密码",
|
||||||
component: {
|
component: {
|
||||||
name: "a-input-password",
|
name: "a-input-password",
|
||||||
vModel: "value",
|
vModel: "value",
|
||||||
|
@ -191,14 +191,14 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
||||||
*/
|
*/
|
||||||
async condition() {
|
async condition() {
|
||||||
if (this.forceUpdate) {
|
if (this.forceUpdate) {
|
||||||
|
this.logger.info("强制更新证书选项已勾选,准备申请新证书");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputChanged = false;
|
const inputChanged = this.ctx.inputChanged;
|
||||||
const oldInput = JSON.stringify(this.lastStatus?.input?.domains);
|
if (inputChanged) {
|
||||||
const thisInput = JSON.stringify(this.domains);
|
this.logger.info("输入参数变更,准备申请新证书");
|
||||||
if (oldInput !== thisInput) {
|
return null;
|
||||||
inputChanged = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldCert: CertReader | undefined = undefined;
|
let oldCert: CertReader | undefined = undefined;
|
||||||
|
@ -212,11 +212,6 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputChanged) {
|
|
||||||
this.logger.info("输入参数变更,申请新证书");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ret = this.isWillExpire(oldCert.expires, this.renewDays);
|
const ret = this.isWillExpire(oldCert.expires, this.renewDays);
|
||||||
if (!ret.isWillExpire) {
|
if (!ret.isWillExpire) {
|
||||||
this.logger.info(`证书还未过期:过期时间${dayjs(oldCert.expires).format("YYYY-MM-DD HH:mm:ss")},剩余${ret.leftDays}天`);
|
this.logger.info(`证书还未过期:过期时间${dayjs(oldCert.expires).format("YYYY-MM-DD HH:mm:ss")},剩余${ret.leftDays}天`);
|
||||||
|
|
|
@ -69,13 +69,15 @@ export class CertReader {
|
||||||
const tmpDerPath = this.saveToFile("der");
|
const tmpDerPath = this.saveToFile("der");
|
||||||
logger.info("本地文件写入成功");
|
logger.info("本地文件写入成功");
|
||||||
try {
|
try {
|
||||||
await opts.handle({
|
return await opts.handle({
|
||||||
reader: this,
|
reader: this,
|
||||||
tmpCrtPath: tmpCrtPath,
|
tmpCrtPath: tmpCrtPath,
|
||||||
tmpKeyPath: tmpKeyPath,
|
tmpKeyPath: tmpKeyPath,
|
||||||
tmpPfxPath: tmpPfxPath,
|
tmpPfxPath: tmpPfxPath,
|
||||||
tmpDerPath: tmpDerPath,
|
tmpDerPath: tmpDerPath,
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
} finally {
|
} finally {
|
||||||
//删除临时文件
|
//删除临时文件
|
||||||
logger.info("删除临时文件");
|
logger.info("删除临时文件");
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
"cache-manager": "^3.6.3",
|
"cache-manager": "^3.6.3",
|
||||||
"cron-parser": "^4.9.0",
|
"cron-parser": "^4.9.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
"glob": "^10.4.5",
|
"glob": "^10.4.5",
|
||||||
"https-proxy-agent": "^7.0.5",
|
"https-proxy-agent": "^7.0.5",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
"ssh2": "^1.15.0",
|
"ssh2": "^1.15.0",
|
||||||
"strip-ansi": "^7.1.0",
|
"strip-ansi": "^7.1.0",
|
||||||
"svg-captcha": "^1.4.0",
|
"svg-captcha": "^1.4.0",
|
||||||
|
"syno": "^2.2.0",
|
||||||
"tencentcloud-sdk-nodejs": "^4.0.44",
|
"tencentcloud-sdk-nodejs": "^4.0.44",
|
||||||
"typeorm": "^0.3.20"
|
"typeorm": "^0.3.20"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import querystring from 'querystring';
|
import querystring from 'querystring';
|
||||||
import { DogeCloudAccess } from '../access.js';
|
import { DogeCloudAccess } from '../access.js';
|
||||||
import { AxiosInstance } from 'axios';
|
import { HttpClient } from '@certd/pipeline';
|
||||||
|
|
||||||
export class DogeClient {
|
export class DogeClient {
|
||||||
accessKey: string;
|
accessKey: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
http: AxiosInstance;
|
http: HttpClient;
|
||||||
constructor(access: DogeCloudAccess, http: AxiosInstance) {
|
constructor(access: DogeCloudAccess, http: HttpClient) {
|
||||||
this.accessKey = access.accessKey;
|
this.accessKey = access.accessKey;
|
||||||
this.secretKey = access.secretKey;
|
this.secretKey = access.secretKey;
|
||||||
this.http = http;
|
this.http = http;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { utils } from '@certd/pipeline';
|
||||||
|
|
||||||
export async function request(config: any): Promise<any> {
|
export async function request(config: any): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await utils.http(config);
|
return await utils.http.request(config);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const data = e.data || e.response?.data;
|
const data = e.data || e.response?.data;
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
Loading…
Reference in New Issue