perf: 触发证书重新申请input变化对比规则优化,减少升级版本后触发申请证书的情况

pull/229/head
xiaojunnuo 2024-10-16 12:20:42 +08:00
parent 84fd3b250d
commit c46a2a9a39
10 changed files with 57 additions and 18 deletions

View File

@ -181,6 +181,9 @@ export class RunnableCollection {
if (runnable?.status) {
runnable.status.status = ResultType.none;
runnable.status.result = ResultType.none;
runnable.status.inputHash = "";
// @ts-ignore
runnable.input = {};
}
}

View File

@ -121,7 +121,6 @@ export type HistoryResultGroup = {
};
};
export type HistoryResult = {
// input: any;
inputHash?: string;
output: any;
files?: FileItem[];

View File

@ -5,6 +5,7 @@ import { CertReader } from "./cert-reader.js";
import JSZip from "jszip";
import { CertConverter } from "./convert.js";
import fs from "fs";
import { pick } from "lodash-es";
export { CertReader };
export type { CertInfo };
@ -203,11 +204,36 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
return null;
}
const inputChanged = this.ctx.inputChanged;
let inputChanged = this.ctx.inputChanged;
if (inputChanged) {
this.logger.info("input hash 有变更,检查是否需要重新申请证书");
//判断域名有没有变更
/**
* "renewDays": 20,
* "certApplyPlugin": "CertApply",
* "sslProvider": "letsencrypt",
* "privateKeyType": "rsa_2048_pkcs1",
* "dnsProviderType": "aliyun",
* "domains": [
* "*.handsfree.work"
* ],
* "email": "xiaojunnuo@qq.com",
* "dnsProviderAccess": 3,
* "useProxy": false,
* "skipLocalVerify": false,
* "successNotify": true,
* "pfxPassword": "123456"
*/
const checkInputChanges = ["domains", "sslProvider", "privateKeyType", "dnsProviderType", "dnsProviderAccess", "pfxPassword"];
const oldInput = JSON.stringify(pick(this.lastStatus?.input, checkInputChanges));
const thisInput = JSON.stringify(pick(this, checkInputChanges));
inputChanged = oldInput !== thisInput;
if (inputChanged) {
this.logger.info("输入参数变更,准备申请新证书");
return null;
}
}
let oldCert: CertReader | undefined = undefined;
try {

View File

@ -6,7 +6,6 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { message } from "ant-design-vue";
import { DoVerify } from "./api";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
@ -125,9 +124,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}),
form: {
component: {
onDictChange: ({ form, dict }) => {
onDictChange: ({ form, dict }: any) => {
if (!form.cnameProviderId) {
const item = dict.data.find((item) => item.isDefault);
const item = dict.data.find((item: any) => item.isDefault);
if (item) {
form.cnameProviderId = item.id;
}
@ -180,7 +179,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
message.success("验证成功");
row.status = "valid";
}
} catch (e) {
} catch (e: any) {
console.error(e);
message.error(e.message);
} finally {

View File

@ -8,7 +8,7 @@
<div class="title">
<div>{{ item.name }}({{ item.fileName }})</div>
<fs-copyable :model-value="item.content" :button="{ show: false }">
<a-tag type="success">复制</a-tag>
<a-tag color="success">复制</a-tag>
</fs-copyable>
</div>
</template>

View File

@ -155,7 +155,7 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp
const viewCert = async (row: any) => {
const cert = await api.GetCert(row.id);
if (!cert) {
notification.error({ message: "还没有产生证书,请先运行流水线" });
notification.error({ message: "请先运行一次流水线" });
return;
}

View File

@ -101,7 +101,7 @@
<fs-icon
v-if="!editMode"
class="pointer color-blue ml-2"
title="重新运行此步骤"
title="完全重新运行此步骤"
icon="SyncOutlined"
@click="run(item.id)"
></fs-icon>

View File

@ -64,6 +64,7 @@
"iconv-lite": "^0.6.3",
"js-yaml": "^4.1.0",
"jsonwebtoken": "^9.0.0",
"jszip": "^3.10.1",
"koa-send": "^5.0.1",
"kubernetes-client": "^9.0.0",
"lodash-es": "^4.17.21",

View File

@ -102,7 +102,7 @@ export class AsyncSsh2Client {
let iconv: any = await import('iconv-lite');
iconv = iconv.default;
return new Promise((resolve, reject) => {
this.logger.info(`执行命令:[${this.connConf.host}][exec]: ` + script);
this.logger.info(`执行命令:[${this.connConf.host}][exec]: \n` + script);
this.conn.exec(script, (err: Error, stream: any) => {
if (err) {
reject(err);
@ -274,7 +274,7 @@ export class SshClient {
let { script } = options;
const { connectConf } = options;
this.logger.info('命令:', script);
// this.logger.info('命令:', script);
return await this._call({
connectConf,
callable: async (conn: AsyncSsh2Client) => {

View File

@ -4,6 +4,8 @@ import path from 'path';
import dayjs from 'dayjs';
import { SshAccess, SshClient } from '../../plugin-host/index.js';
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
import JSZip from 'jszip';
import * as os from 'node:os';
const defaultBackupDir = 'certd_backup';
const defaultFilePrefix = 'db-backup';
@ -100,16 +102,25 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin {
return;
}
this.logger.info('当前备份方式:', this.backupMode);
//本地压缩
const zip = new JSZip();
zip.file(dbPath);
const content = await zip.generateAsync({ type: 'nodebuffer' });
const dbZipFilename = `${this.filePrefix}.${dayjs().format('YYYYMMDD.HHmmss')}.sqlite.zip`;
const dbZipPath = path.resolve(os.tmpdir(), dbZipFilename);
await fs.promises.writeFile(dbZipPath, content);
this.logger.info(`数据库文件压缩完成:${dbZipPath}`);
this.logger.info('开始备份,当前备份方式:', this.backupMode);
const backupDir = this.backupDir || defaultBackupDir;
const backupFile = `${backupDir}/${this.filePrefix}.${dayjs().format('YYYYMMDD.HHmmss')}.sqlite`;
const backupFilePath = `${backupDir}/${dbZipFilename}`;
if (this.backupMode === 'local') {
await this.localBackup(dbPath, backupDir, backupFile);
await this.localBackup(dbPath, backupDir, backupFilePath);
} else if (this.backupMode === 'ssh') {
await this.sshBackup(dbPath, backupDir, backupFile);
await this.sshBackup(dbPath, backupDir, backupFilePath);
} else if (this.backupMode === 'oss') {
await this.ossBackup(dbPath, backupDir, backupFile);
await this.ossBackup(dbPath, backupDir, backupFilePath);
} else {
throw new Error(`不支持的备份方式:${this.backupMode}`);
}