perf: 优化dokploy 部署插件,配置选择serverId

This commit is contained in:
xiaojunnuo
2025-11-19 23:47:26 +08:00
parent be4f479afd
commit c9709f2698
3 changed files with 47 additions and 23 deletions
@@ -36,6 +36,7 @@ export class CertReader {
detail: CertificateInfo; detail: CertificateInfo;
//毫秒时间戳 //毫秒时间戳
effective: number; effective: number;
//毫秒时间戳
expires: number; expires: number;
constructor(certInfo: CertInfo) { constructor(certInfo: CertInfo) {
this.cert = certInfo; this.cert = certInfo;
@@ -50,6 +50,14 @@ export class DokployAccess extends BaseAccess {
return "ok" return "ok"
} }
async getServerList(){
const req = {
url :"/api/server.all",
method: "get",
}
return await this.doRequest(req);
}
async getCertList(){ async getCertList(){
const req = { const req = {
url :"/api/certificates.all", url :"/api/certificates.all",
@@ -96,7 +104,7 @@ export class DokployAccess extends BaseAccess {
headers, headers,
baseURL: this.endpoint, baseURL: this.endpoint,
...req, ...req,
logRes: true, logRes: false,
}); });
} }
@@ -1,13 +1,13 @@
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import {CertApplyPluginNames, CertInfo} from "@certd/plugin-cert"; import {CertApplyPluginNames, CertInfo, CertReader} from "@certd/plugin-cert";
import {createCertDomainGetterInputDefine, createRemoteSelectInputDefine} from "@certd/plugin-lib"; import {createCertDomainGetterInputDefine, createRemoteSelectInputDefine} from "@certd/plugin-lib";
import {DokployAccess} from "../access.js"; import {DokployAccess} from "../access.js";
@IsTaskPlugin({ @IsTaskPlugin({
//命名规范,插件类型+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名 //命名规范,插件类型+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名
name: "DokployRefreshCert", name: "DokployRefreshCert",
title: "Dokploy-更新证书", title: "Dokploy-部署server证书",
desc: "自动更新Dokploy证书", desc: "自动更新Dokploy server证书",
icon: "svg:icon-lucky", icon: "svg:icon-lucky",
//插件分组 //插件分组
group: pluginGroups.panel.key, group: pluginGroups.panel.key,
@@ -52,12 +52,12 @@ export class DokployRefreshCert extends AbstractTaskPlugin {
createRemoteSelectInputDefine({ createRemoteSelectInputDefine({
title: "证书名称", title: "证书名称",
helper: "要更新的证书名称,如果这里没有,请先给手动绑定一次证书", helper: "要更新的证书名称,如果这里没有,请先给手动绑定一次证书",
action: DokployRefreshCert.prototype.onGetCertList.name, action: DokployRefreshCert.prototype.onGetServerList.name,
pager: false, pager: false,
search: false search: false
}) })
) )
certList!: string[]; serverList!: string[];
//插件实例化时执行的方法 //插件实例化时执行的方法
async onInstance() { async onInstance() {
@@ -67,46 +67,61 @@ export class DokployRefreshCert extends AbstractTaskPlugin {
async execute(): Promise<void> { async execute(): Promise<void> {
const access = await this.getAccess<DokployAccess>(this.accessId); const access = await this.getAccess<DokployAccess>(this.accessId);
if (!this.serverList || this.serverList.length === 0) {
throw new Error("请先选择要部署证书的server");
}
// await access.createCert({cert:this.cert}) // await access.createCert({cert:this.cert})
const certList = await access.getCertList(); const oldCertList = await access.getCertList();
for (const certId of this.certList) { const certReader = new CertReader(this.cert);
this.logger.info(`----------- 开始更新证书:${certId}`); for (const serverId of this.serverList) {
const [serverId,name] = certId.split("#"); this.logger.info(`----------- 开始部署server证书:${serverId}`);
const founds = certList.filter((item: any) => item.name === name); if(!serverId){
if (founds){ this.logger.error(`----------- serverId不能为空,跳过更新`);
for (const found of founds) { continue;
await access.removeCert({id:found.certificateId})
}
} }
await access.createCert({ await access.createCert({
name, name: certReader.buildCertName(),
cert: this.cert, cert: this.cert,
serverId: serverId, serverId: serverId,
}); });
this.logger.info(`----------- 更新证书${certId}成功`); this.logger.info(`----------- 部署server${serverId}证书成功`);
}
this.logger.info(`----------- 等待10秒后开始清理过期证书`);
await this.ctx.utils.sleep(10000);
//清理过期证书
for (const certItem of oldCertList) {
const certDetail = CertReader.readCertDetail(certItem.certificateData);
if (certDetail.expires.getTime() < new Date().getTime()){
this.logger.info(`----------- 证书${certItem.certificateId}已过期`);
await access.removeCert({id:certItem.certificateId});
this.logger.info(`----------- 清理过期证书${certItem.certificateId}成功`);
}else{
this.logger.info(`----------- 证书${certItem.certificateId}还未过期`);
}
} }
this.logger.info("部署完成"); this.logger.info("部署完成");
} }
async onGetCertList(data: PageSearch = {}) { async onGetServerList(data: PageSearch = {}) {
const access = await this.getAccess<DokployAccess>(this.accessId); const access = await this.getAccess<DokployAccess>(this.accessId);
const res = await access.getCertList() const res = await access.getServerList()
const list = res const list = res
if (!list || list.length === 0) { if (!list || list.length === 0) {
throw new Error("没有找到证书,你可以直接手动输入id,如果id不存在将自动创建"); throw new Error("没有找到Server,你可以直接手动输入serverId");
} }
const options = list.map((item: any) => { const options = list.map((item: any) => {
return { return {
label: `${item.name}<${item.serverId}>`, label: `${item.name}<${item.serverId}>`,
value: `${item.serverId}#${item.name}`, value: `${item.serverId}`,
domain: item.name
}; };
}); });
return options; return options;