perf: 手动上传证书部署流水线

This commit is contained in:
xiaojunnuo
2025-03-22 02:06:02 +08:00
parent fedf90ea78
commit fbb66f3c43
25 changed files with 329 additions and 511 deletions

View File

@@ -4,6 +4,7 @@ import type { CertInfo } from "./acme.js";
import { CertReader } from "./cert-reader.js";
import JSZip from "jszip";
import { CertConverter } from "./convert.js";
export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
@TaskInput({
@@ -76,6 +77,16 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
abstract onInit(): Promise<void>;
//必须output之后执行
async emitCertApplySuccess() {
const emitter = this.ctx.emitter;
const value = {
cert: this.cert,
file: this._result.files[0].path,
};
await emitter.emit(EVENT_CERT_APPLY_SUCCESS, value);
}
async output(certReader: CertReader, isNew: boolean) {
const cert: CertInfo = certReader.toCertInfo();
this.cert = cert;

View File

@@ -1,15 +1,9 @@
import { NotificationBody, Step, TaskEmitter, TaskInput } from "@certd/pipeline";
import { NotificationBody, Step, TaskInput } from "@certd/pipeline";
import dayjs from "dayjs";
import { CertReader } from "./cert-reader.js";
import { pick } from "lodash-es";
import { CertApplyBaseConvertPlugin } from "./base-convert.js";
export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
export async function emitCertApplySuccess(emitter: TaskEmitter, cert: CertReader) {
await emitter.emit(EVENT_CERT_APPLY_SUCCESS, cert);
}
export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
@TaskInput({
title: "邮箱",
@@ -75,7 +69,7 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
if (cert != null) {
await this.output(cert, true);
await emitCertApplySuccess(this.ctx.emitter, cert);
await this.emitCertApplySuccess();
//清空后续任务的状态,让后续任务能够重新执行
this.clearLastStatus();

View File

@@ -1,5 +0,0 @@
import { CertInfo } from "../acme";
export interface ICertApplyUploadService {
getCertInfo: (opts: { certId: number; userId: number }) => Promise<any>;
updateCert: (opts: { certId: number; cert: CertInfo; userId: number }) => Promise<any>;
}

View File

@@ -2,9 +2,8 @@ import { IsTaskPlugin, pluginGroups, RunStrategy, Step, TaskInput, TaskOutput }
import type { CertInfo } from "../acme.js";
import { CertReader } from "../cert-reader.js";
import { CertApplyBaseConvertPlugin } from "../base-convert.js";
export * from "./d.js";
import dayjs from "dayjs";
import { ICertApplyUploadService } from "./d";
export { CertReader };
export type { CertInfo };
@IsTaskPlugin({
@@ -84,7 +83,7 @@ export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
}
`,
})
certInfoId!: string;
uploadCert!: CertInfo;
@TaskOutput({
title: "证书MD5",
@@ -100,14 +99,7 @@ export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
async onInit(): Promise<void> {}
async getCertFromStore() {
const certApplyUploadService: ICertApplyUploadService = await this.ctx.serviceGetter.get("CertApplyUploadService");
const certInfo = await certApplyUploadService.getCertInfo({
certId: Number(this.certInfoId),
userId: this.pipeline.userId,
});
const certReader = new CertReader(certInfo);
const certReader = new CertReader(this.uploadCert);
if (!certReader.expires && certReader.expires < new Date().getTime()) {
throw new Error("证书已过期,停止部署,请重新上传证书");
}
@@ -121,39 +113,43 @@ export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
const leftDays = dayjs(certReader.expires).diff(dayjs(), "day");
this.logger.info(`证书过期时间${dayjs(certReader.expires).format("YYYY-MM-DD HH:mm:ss")},剩余${leftDays}`);
const lastCrtMd5 = this.lastStatus?.status?.output?.certMd5;
this.logger.info("证书MD5", crtMd5);
this.logger.info("上次证书MD5", lastCrtMd5);
if (lastCrtMd5 === crtMd5) {
this.logger.info("证书无变化,跳过");
//输出证书MD5
this.certMd5 = crtMd5;
await this.output(certReader, false);
return "skip";
if (!this.ctx.inputChanged) {
this.logger.info("输入参数无变化");
const lastCrtMd5 = this.lastStatus?.status?.output?.certMd5;
this.logger.info("证书MD5", crtMd5);
this.logger.info("上次证书MD5", lastCrtMd5);
if (lastCrtMd5 === crtMd5) {
this.logger.info("证书无变化,跳过");
//输出证书MD5
this.certMd5 = crtMd5;
await this.output(certReader, false);
return "skip";
}
this.logger.info("证书有变化,重新部署");
} else {
this.logger.info("输入参数有变化,重新部署");
}
this.logger.info("证书有变化,重新部署");
this.clearLastStatus();
//输出证书MD5
this.certMd5 = crtMd5;
await this.output(certReader, true);
//必须output之后执行
await this.emitCertApplySuccess();
return;
}
async onCertUpdate(data: any) {
const certApplyUploadService = await this.ctx.serviceGetter.get("CertApplyUploadService");
const res = await certApplyUploadService.updateCert({
certId: this.certInfoId,
userId: this.ctx.user.id,
cert: {
crt: data.crt,
key: data.key,
},
});
const certReader = new CertReader(data);
return {
input: {
domains: res.domains,
uploadCert: {
crt: data.crt,
key: data.key,
},
domains: certReader.getAllDomains(),
},
};
}

View File

@@ -1,3 +1,5 @@
export { EVENT_CERT_APPLY_SUCCESS } from "./cert-plugin/base-convert.js";
export * from "./cert-plugin/index.js";
export * from "./cert-plugin/lego/index.js";
export * from "./cert-plugin/custom/index.js";