From 7d96a57d73a6ddfd64c05eac6d8ca3688f3cebd6 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 24 Apr 2025 17:27:13 +0800 Subject: [PATCH] chore: --- .../src/plugin/cert-plugin/base-convert.ts | 3 +- packages/plugins/plugin-lib/src/oss/alioss.ts | 25 +++++++ packages/plugins/plugin-lib/src/oss/api.ts | 12 ++++ .../src/router/source/modules/certd.ts | 22 +++--- .../plugin-other/plugins/plugin-db-backup.ts | 72 ++++++++++++++++--- 5 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 packages/plugins/plugin-lib/src/oss/alioss.ts create mode 100644 packages/plugins/plugin-lib/src/oss/api.ts diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts index a73dd2c4..9301e144 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts @@ -27,8 +27,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin { "1、支持多个域名打到一个证书上,例如: foo.com,*.foo.com,*.bar.com\n" + "2、子域名被通配符包含的不要填写,例如:www.foo.com已经被*.foo.com包含,不要填写www.foo.com\n" + "3、泛域名只能通配*号那一级(*.foo.com的证书不能用于xxx.yyy.foo.com、不能用于foo.com)\n" + - "4、输入一个,空格之后,再输入下一个\n" + - "5、如果你配置了子域托管解析,请先[设置托管子域名](#/certd/pipeline/subDomain)", + "4、输入一个,空格之后,再输入下一个", }) domains!: string[]; diff --git a/packages/plugins/plugin-lib/src/oss/alioss.ts b/packages/plugins/plugin-lib/src/oss/alioss.ts new file mode 100644 index 00000000..809bcf86 --- /dev/null +++ b/packages/plugins/plugin-lib/src/oss/alioss.ts @@ -0,0 +1,25 @@ +import { AliyunAccess } from "../aliyun"; +import { HttpClient, ILogger } from "@certd/basic"; +import { IOssClient, OssClientDeleteReq } from "./api"; + +export class AliossClient implements IOssClient { + access: AliyunAccess; + logger: ILogger; + http: HttpClient; + + constructor(opts: { access: AliyunAccess; http: HttpClient; logger: ILogger }) { + this.access = opts.access; + this.http = opts.http; + this.logger = opts.logger; + } + + upload(key: string, content: Buffer | string): Promise { + throw new Error("Method not implemented."); + } + download(key: string, savePath?: string): Promise { + throw new Error("Method not implemented."); + } + delete(opts: OssClientDeleteReq): Promise { + throw new Error("Method not implemented."); + } +} diff --git a/packages/plugins/plugin-lib/src/oss/api.ts b/packages/plugins/plugin-lib/src/oss/api.ts new file mode 100644 index 00000000..3ef0147a --- /dev/null +++ b/packages/plugins/plugin-lib/src/oss/api.ts @@ -0,0 +1,12 @@ +export type OssClientDeleteReq = { + key: string; + beforeDays?: number; +}; + +export interface IOssClient { + upload(key: string, content: Buffer | string): Promise; + + download(key: string, savePath?: string): Promise; + + delete(opts: OssClientDeleteReq): Promise; +} diff --git a/packages/ui/certd-client/src/router/source/modules/certd.ts b/packages/ui/certd-client/src/router/source/modules/certd.ts index a9c992be..2d6bd6e8 100644 --- a/packages/ui/certd-client/src/router/source/modules/certd.ts +++ b/packages/ui/certd-client/src/router/source/modules/certd.ts @@ -98,17 +98,17 @@ export const certdResources = [ keepAlive: true, }, }, - { - title: "子域名托管设置", - name: "SubDomain", - path: "/certd/pipeline/subDomain", - component: "/certd/pipeline/sub-domain/index.vue", - meta: { - icon: "material-symbols:approval-delegation-outline", - auth: true, - keepAlive: true, - }, - }, + // { + // title: "子域名托管设置", + // name: "SubDomain", + // path: "/certd/pipeline/subDomain", + // component: "/certd/pipeline/sub-domain/index.vue", + // meta: { + // icon: "material-symbols:approval-delegation-outline", + // auth: true, + // keepAlive: true, + // }, + // }, { title: "流水线分组管理", name: "PipelineGroupManager", diff --git a/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-db-backup.ts b/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-db-backup.ts index 8ccf4515..86218822 100644 --- a/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-db-backup.ts +++ b/packages/ui/certd-server/src/plugins/plugin-other/plugins/plugin-db-backup.ts @@ -1,14 +1,15 @@ -import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; +import {IsTaskPlugin, pluginGroups, RunStrategy, TaskInput} from '@certd/pipeline'; import fs from 'fs'; import path from 'path'; import dayjs from 'dayjs'; -import { AbstractPlusTaskPlugin } from '@certd/plugin-plus'; +import {AbstractPlusTaskPlugin} from '@certd/plugin-plus'; import JSZip from 'jszip'; import * as os from 'node:os'; -import { SshAccess, SshClient } from '@certd/plugin-lib'; +import {SshAccess, SshClient} from '@certd/plugin-lib'; const defaultBackupDir = 'certd_backup'; const defaultFilePrefix = 'db-backup'; + @IsTaskPlugin({ name: 'DBBackupPlugin', title: '数据库备份', @@ -30,8 +31,9 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { component: { name: 'a-select', options: [ - { label: '本地复制', value: 'local' }, - { label: 'ssh上传', value: 'ssh' }, + {label: '本地复制', value: 'local'}, + {label: 'ssh上传', value: 'ssh'}, + {label: 'oss上传', value: 'oss'}, ], placeholder: '', }, @@ -57,6 +59,51 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { }) sshAccessId!: number; + + @TaskInput({ + title: 'OSS类型', + component: { + name: 'a-input', + options: [ + {value: "aliyun", label: "阿里云OSS"}, + {value: "s3", label: "MinIO/S3"}, + {value: "qiniu", label: "七牛云"}, + {value: "tencent", label: "腾讯云COS"} + ] + }, + mergeScript: ` + return { + show:ctx.compute(({form})=>{ + return form.backupMode === 'oss'; + }) + } + `, + required: true, + }) + ossType!: string; + + @TaskInput({ + title: 'OSS授权', + component: { + name: 'access-selector', + }, + mergeScript: ` + return { + show:ctx.compute(({form})=>{ + return form.backupMode === 'ssh'; + }), + component:{ + type: ctx.compute(({form})=>{ + return form.ossType; + }), + } + } + `, + required: true, + }) + ossAccessId!: number; + + @TaskInput({ title: '备份保存目录', component: { @@ -104,7 +151,9 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { }) retainDays!: number; - async onInstance() {} + async onInstance() { + } + async execute(): Promise { this.logger.info('开始备份数据库'); @@ -118,7 +167,7 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { const dbZipFilename = `${dbTmpFilename}.zip`; const tempDir = path.resolve(os.tmpdir(), 'certd_backup'); if (!fs.existsSync(tempDir)) { - await fs.promises.mkdir(tempDir, { recursive: true }); + await fs.promises.mkdir(tempDir, {recursive: true}); } const dbTmpPath = path.resolve(tempDir, dbTmpFilename); const dbZipPath = path.resolve(tempDir, dbZipFilename); @@ -129,14 +178,14 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { const zip = new JSZip(); const stream = fs.createReadStream(dbTmpPath); // 使用流的方式添加文件内容 - zip.file(dbTmpFilename, stream, { binary: true, compression: 'DEFLATE' }); + zip.file(dbTmpFilename, stream, {binary: true, compression: 'DEFLATE'}); const uploadDir = path.resolve('data', 'upload'); if (this.withUpload && fs.existsSync(uploadDir)) { zip.folder(uploadDir); } - const content = await zip.generateAsync({ type: 'nodebuffer' }); + const content = await zip.generateAsync({type: 'nodebuffer'}); await fs.promises.writeFile(dbZipPath, content); this.logger.info(`数据库文件压缩完成:${dbZipPath}`); @@ -164,7 +213,7 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { } const dir = path.dirname(backupPath); if (!fs.existsSync(dir)) { - await fs.promises.mkdir(dir, { recursive: true }); + await fs.promises.mkdir(dir, {recursive: true}); } backupPath = path.resolve(backupPath); await fs.promises.copyFile(dbPath, backupPath); @@ -195,7 +244,7 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { this.logger.info('备份目录:', backupPath); await sshClient.uploadFiles({ connectConf: access, - transports: [{ localPath: dbPath, remotePath: backupPath }], + transports: [{localPath: dbPath, remotePath: backupPath}], mkdirs: true, }); this.logger.info('备份文件上传完成'); @@ -224,4 +273,5 @@ export class DBBackupPlugin extends AbstractPlusTaskPlugin { // TODO } } + new DBBackupPlugin();