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
@@ -11,6 +11,7 @@ export type UploadCertReq = {
certReader: CertReader;
fromType?: string;
userId?: number;
file?:any
};
@@ -38,7 +39,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
});
}
async updateDomains(pipelineId: number, userId: number, domains: string[]) {
async updateDomains(pipelineId: number, userId: number, domains: string[],fromType?:string) {
const found = await this.repository.findOne({
where: {
pipelineId,
@@ -53,6 +54,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
//create
bean.pipelineId = pipelineId;
bean.userId = userId;
bean.fromType = fromType
if (!domains || domains.length === 0) {
return;
}
@@ -133,7 +135,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
return certReader.toCertInfo();
}
async updateCertByPipelineId(pipelineId: number, certReader: CertReader, fromType = 'pipeline') {
async updateCertByPipelineId(pipelineId: number, cert: CertInfo,file?:string,fromType = 'pipeline') {
const found = await this.repository.findOne({
where: {
pipelineId,
@@ -141,8 +143,9 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
});
const bean = await this.updateCert({
id: found?.id,
certReader,
certReader: new CertReader(cert),
fromType,
file
});
return bean;
}
@@ -165,6 +168,9 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
bean.expiresTime = certReader.expires;
bean.certProvider = certReader.detail.issuer.commonName;
bean.userId = userId
if(req.file){
bean.certFile = req.file
}
await this.addOrUpdate(bean);
return bean;
}
@@ -1,203 +0,0 @@
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core";
import { BaseService, CommonException } from "@certd/lib-server";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { EntityManager, Repository } from "typeorm";
import { CertInfoEntity } from "../entity/cert-info.js";
import { CertInfo, CertReader } from "@certd/plugin-cert";
import { PipelineService } from "../../pipeline/service/pipeline-service.js";
import { CertInfoService } from "./cert-info-service.js";
import { PipelineEntity } from "../../pipeline/entity/pipeline.js";
import { nanoid } from "nanoid";
export type UploadCertReq = {
id?: number;
certReader: CertReader;
fromType?: string;
userId?: number;
pipelineId?: number;
};
export type UpdateCertReq = {
id: number;
cert: CertInfo;
userId?: number;
};
export type CreateUploadPipelineReq = {
cert: CertInfo;
userId: number;
pipelineId?: number;
pipeline?:{
input?:any;
notifications?:any[]
}
};
@Provide("CertUploadService")
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class CertUploadService extends BaseService<CertInfoEntity> {
@InjectEntityModel(CertInfoEntity)
repository: Repository<CertInfoEntity>;
@Inject()
pipelineService: PipelineService;
@Inject()
certInfoService: CertInfoService;
//@ts-ignore
getRepository() {
return this.repository;
}
/**
* 更新证书,触发流水线
* @param req
*/
async updateCert(req: UpdateCertReq) {
const certInfoEntity = await this.certInfoService.info(req.id);
if (!certInfoEntity) {
throw new CommonException("cert not found");
}
if(certInfoEntity.fromType !== 'upload') {
throw new CommonException("cert can't be custom upload");
}
await this.uploadCert(this.repository.manager,{
id: req.id,
fromType: 'upload',
userId: req.userId,
certReader: new CertReader(req.cert)
})
return {
id: certInfoEntity.id,
domains: certInfoEntity.domains.split(','),
pipelineId: certInfoEntity.pipelineId,
fromType: certInfoEntity.fromType,
updateTime: certInfoEntity.updateTime,
}
}
async createUploadCertPipeline(body:CreateUploadPipelineReq) {
const { userId, cert } = body;
if (!cert) {
throw new CommonException("cert can't be empty");
}
const certReader = new CertReader(cert)
return await this.transaction(async (tx:EntityManager)=>{
let pipelineId = body.pipelineId;
const newCertInfo = await this.uploadCert(tx,{
certReader: certReader,
fromType: 'upload',
userId,
pipelineId
});
if(!pipelineId){
const pipelineTitle = certReader.getAllDomains()[0] +"上传证书自动部署";
const notifications = body.pipeline?.notifications ||[];
if(notifications.length === 0){
notifications.push({
type: "custom",
when: ["error", "turnToSuccess", "success"],
notificationId: 0,
title: "默认通知",
});
}
let pipeline = {
title: pipelineTitle,
runnableType: "pipeline",
stages: [
{
id: nanoid(10),
title: "上传证书解析阶段",
maxTaskCount: 1,
runnableType: "stage",
tasks: [
{
id: nanoid(10),
title: "上传证书解析转换",
runnableType: "task",
steps: [
{
id: nanoid(10),
title: "上传证书解析转换",
runnableType: "step",
input: {
certInfoId: newCertInfo.id,
domains: newCertInfo.domains.split(','),
...body.pipeline?.input
},
strategy: {
runStrategy: 0, // 正常执行
},
type: "CertApplyUpload",
},
],
},
],
},
],
triggers:[],
notifications,
}
const newPipeline = await tx.getRepository(PipelineEntity).save({
userId,
title: pipelineTitle,
type:"cert_upload",
content: JSON.stringify(pipeline),
keepHistory:20,
})
newCertInfo.pipelineId = newPipeline.id;
await tx.getRepository(CertInfoEntity).save({
id: newCertInfo.id,
pipelineId: newPipeline.id
});
pipelineId = newPipeline.id;
}
return {
id:newCertInfo.id,
pipelineId: pipelineId,
domains: newCertInfo.domains.split(','),
fromType: newCertInfo.fromType,
updateTime: newCertInfo.updateTime,
}
})
}
private async uploadCert(tx:EntityManager,req: UploadCertReq) {
const bean = new CertInfoEntity();
const { id, fromType,userId, certReader } = req;
if (id) {
bean.id = id;
} else {
bean.fromType = fromType;
bean.userId = userId
}
const certInfo = certReader.toCertInfo();
bean.certInfo = JSON.stringify(certInfo);
bean.applyTime = new Date().getTime();
const domains = certReader.detail.domains.altNames;
bean.domains = domains.join(',');
bean.domain = domains[0];
bean.domainCount = domains.length;
bean.expiresTime = certReader.expires;
bean.certProvider = certReader.detail.issuer.commonName;
if (req.pipelineId){
bean.pipelineId = req.pipelineId;
}
await tx.getRepository(CertInfoEntity).save(bean);
return bean;
}
}