mirror of https://github.com/certd/certd
chore: 支持手动上传证书并部署
parent
29a6a992f0
commit
de40be430b
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -7,8 +7,8 @@ function sha256(data: string, digest: BinaryToTextEncoding = 'hex') {
|
|||
return crypto.createHash('sha256').update(data).digest(digest);
|
||||
}
|
||||
|
||||
function HmacSha256(data: string, key: string, digest: BinaryToTextEncoding = 'base64') {
|
||||
return crypto.createHmac('sha256', Buffer.from(key, 'base64')).update(data).digest(digest);
|
||||
function hmacSha256(data: string, digest: BinaryToTextEncoding = 'base64') {
|
||||
return crypto.createHmac('sha256', data).update(Buffer.alloc(0)).digest(digest);
|
||||
}
|
||||
|
||||
function base64(data: string) {
|
||||
|
@ -18,5 +18,5 @@ export const hashUtils = {
|
|||
md5,
|
||||
sha256,
|
||||
base64,
|
||||
HmacSha256,
|
||||
hmacSha256,
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -7,7 +7,7 @@ import { createAxiosService, hashUtils, HttpRequestConfig, ILogger, logger, util
|
|||
import { IAccessService } from "../access/index.js";
|
||||
import { RegistryItem } from "../registry/index.js";
|
||||
import { Decorator } from "../decorator/index.js";
|
||||
import { ICnameProxyService, IEmailService, IPluginConfigService, IUrlService } from "../service/index.js";
|
||||
import { ICnameProxyService, IEmailService, IPluginConfigService, IServiceGetter, IUrlService } from "../service/index.js";
|
||||
import { FileStore } from "./file-store.js";
|
||||
import { cloneDeep, forEach, merge } from "lodash-es";
|
||||
import { INotificationService } from "../notification/index.js";
|
||||
|
@ -33,7 +33,7 @@ export type ExecutorOptions = {
|
|||
user: UserInfo;
|
||||
baseURL?: string;
|
||||
sysInfo?: SysInfo;
|
||||
serviceGetter: (name: string) => any;
|
||||
serviceGetter: IServiceGetter;
|
||||
};
|
||||
|
||||
export class Executor {
|
||||
|
@ -366,6 +366,7 @@ export class Executor {
|
|||
step,
|
||||
pipeline: this.pipeline,
|
||||
}),
|
||||
serviceGetter: this.options.serviceGetter,
|
||||
};
|
||||
instance.setCtx(taskCtx);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Registrable } from "../registry/index.js";
|
|||
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../dt/index.js";
|
||||
import { FileStore } from "../core/file-store.js";
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { ICnameProxyService, IEmailService, IUrlService } from "../service/index.js";
|
||||
import { ICnameProxyService, IEmailService, IServiceGetter, IUrlService } from "../service/index.js";
|
||||
import { CancelError, IContext, RunHistory, RunnableCollection } from "../core/index.js";
|
||||
import { HttpRequestConfig, ILogger, logger, utils } from "@certd/basic";
|
||||
import { HttpClient } from "@certd/basic";
|
||||
|
@ -116,7 +116,7 @@ export type TaskInstanceContext = {
|
|||
emitter: TaskEmitter;
|
||||
|
||||
//service 容器
|
||||
serviceContainer?: Record<string, any>;
|
||||
serviceGetter?: IServiceGetter;
|
||||
};
|
||||
|
||||
export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
|
@ -224,7 +224,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
|||
|
||||
getStepFromPipeline(stepId: string) {
|
||||
let found: any = null;
|
||||
RunnableCollection.each(this.ctx.pipeline.stages, (step) => {
|
||||
RunnableCollection.each(this.ctx.pipeline.stages, step => {
|
||||
if (step.id === stepId) {
|
||||
found = step;
|
||||
return;
|
||||
|
|
|
@ -3,3 +3,6 @@ export * from "./cname.js";
|
|||
export * from "./config.js";
|
||||
export * from "./url.js";
|
||||
export * from "./emit.js";
|
||||
export type IServiceGetter = {
|
||||
get: (name: string) => Promise<any>;
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"printWidth": 160,
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"printWidth": 160,
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"printWidth": 160,
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"printWidth": 160,
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
import { AbstractTaskPlugin, IContext, Step, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||
import dayjs from "dayjs";
|
||||
import type { CertInfo } from "./acme.js";
|
||||
import { CertReader } from "./cert-reader.js";
|
||||
import JSZip from "jszip";
|
||||
import { CertConverter } from "./convert.js";
|
||||
|
||||
export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名",
|
||||
component: {
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
placeholder: "foo.com / *.foo.com / *.bar.com",
|
||||
tokenSeparators: [",", " ", ",", "、", "|"],
|
||||
},
|
||||
rules: [{ type: "domains" }],
|
||||
required: true,
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
order: -999,
|
||||
helper:
|
||||
"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、输入一个,空格之后,再输入下一个",
|
||||
})
|
||||
domains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: "证书密码",
|
||||
component: {
|
||||
name: "input-password",
|
||||
vModel: "value",
|
||||
},
|
||||
required: false,
|
||||
order: 100,
|
||||
helper: "PFX、jks格式证书是否加密\njks必须设置密码,不传则默认123456\npfx不传则为空密码",
|
||||
})
|
||||
pfxPassword!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "PFX证书转换参数",
|
||||
value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
|
||||
component: {
|
||||
name: "a-auto-complete",
|
||||
vModel: "value",
|
||||
options: [
|
||||
{ value: "", label: "兼容 Windows Server 最新" },
|
||||
{ value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2016" },
|
||||
{ value: "-nomac -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2008" },
|
||||
],
|
||||
},
|
||||
required: false,
|
||||
order: 100,
|
||||
helper: "兼容Windows Server各个版本",
|
||||
})
|
||||
pfxArgs = "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES";
|
||||
|
||||
userContext!: IContext;
|
||||
lastStatus!: Step;
|
||||
|
||||
@TaskOutput({
|
||||
title: "域名证书",
|
||||
})
|
||||
cert?: CertInfo;
|
||||
|
||||
async onInstance() {
|
||||
this.userContext = this.ctx.userContext;
|
||||
this.lastStatus = this.ctx.lastStatus as Step;
|
||||
await this.onInit();
|
||||
}
|
||||
|
||||
abstract onInit(): Promise<void>;
|
||||
|
||||
async output(certReader: CertReader, isNew: boolean) {
|
||||
const cert: CertInfo = certReader.toCertInfo();
|
||||
this.cert = cert;
|
||||
|
||||
this._result.pipelineVars.certExpiresTime = dayjs(certReader.detail.notAfter).valueOf();
|
||||
if (!this._result.pipelinePrivateVars) {
|
||||
this._result.pipelinePrivateVars = {};
|
||||
}
|
||||
this._result.pipelinePrivateVars.cert = cert;
|
||||
|
||||
if (isNew) {
|
||||
try {
|
||||
const converter = new CertConverter({ logger: this.logger });
|
||||
const res = await converter.convert({
|
||||
cert,
|
||||
pfxPassword: this.pfxPassword,
|
||||
pfxArgs: this.pfxArgs,
|
||||
});
|
||||
if (cert.pfx == null && res.pfx) {
|
||||
cert.pfx = res.pfx;
|
||||
}
|
||||
|
||||
if (cert.der == null && res.der) {
|
||||
cert.der = res.der;
|
||||
}
|
||||
|
||||
if (cert.jks == null && res.jks) {
|
||||
cert.jks = res.jks;
|
||||
}
|
||||
|
||||
this.logger.info("转换证书格式成功");
|
||||
} catch (e) {
|
||||
this.logger.error("转换证书格式失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
const zipFileName = certReader.buildCertFileName("zip", certReader.detail.notBefore);
|
||||
await this.zipCert(cert, zipFileName);
|
||||
} else {
|
||||
this.extendsFiles();
|
||||
}
|
||||
}
|
||||
|
||||
async zipCert(cert: CertInfo, filename: string) {
|
||||
const zip = new JSZip();
|
||||
zip.file("证书.pem", cert.crt);
|
||||
zip.file("私钥.pem", cert.key);
|
||||
zip.file("中间证书.pem", cert.ic);
|
||||
zip.file("cert.crt", cert.crt);
|
||||
zip.file("cert.key", cert.key);
|
||||
zip.file("intermediate.crt", cert.ic);
|
||||
zip.file("origin.crt", cert.oc);
|
||||
zip.file("one.pem", cert.one);
|
||||
if (cert.pfx) {
|
||||
zip.file("cert.pfx", Buffer.from(cert.pfx, "base64"));
|
||||
}
|
||||
if (cert.der) {
|
||||
zip.file("cert.der", Buffer.from(cert.der, "base64"));
|
||||
}
|
||||
if (cert.jks) {
|
||||
zip.file("cert.jks", Buffer.from(cert.jks, "base64"));
|
||||
}
|
||||
|
||||
zip.file(
|
||||
"说明.txt",
|
||||
`证书文件说明
|
||||
cert.crt:证书文件,包含证书链,pem格式
|
||||
cert.key:私钥文件,pem格式
|
||||
intermediate.crt:中间证书文件,pem格式
|
||||
origin.crt:原始证书文件,不含证书链,pem格式
|
||||
one.pem: 证书和私钥简单合并成一个文件,pem格式,crt正文+key正文
|
||||
cert.pfx:pfx格式证书文件,iis服务器使用
|
||||
cert.der:der格式证书文件
|
||||
cert.jks:jks格式证书文件,java服务器使用
|
||||
`
|
||||
);
|
||||
|
||||
const content = await zip.generateAsync({ type: "nodebuffer" });
|
||||
this.saveFile(filename, content);
|
||||
this.logger.info(`已保存文件:${filename}`);
|
||||
}
|
||||
|
||||
formatCert(pem: string) {
|
||||
pem = pem.replace(/\r/g, "");
|
||||
pem = pem.replace(/\n\n/g, "\n");
|
||||
pem = pem.replace(/\n$/g, "");
|
||||
return pem;
|
||||
}
|
||||
|
||||
formatCerts(cert: { crt: string; key: string; csr: string }) {
|
||||
const newCert: CertInfo = {
|
||||
crt: this.formatCert(cert.crt),
|
||||
key: this.formatCert(cert.key),
|
||||
csr: this.formatCert(cert.csr),
|
||||
};
|
||||
return newCert;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
import { AbstractTaskPlugin, IContext, NotificationBody, Step, TaskEmitter, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||
import { NotificationBody, Step, TaskEmitter, TaskInput } from "@certd/pipeline";
|
||||
import dayjs from "dayjs";
|
||||
import type { CertInfo } from "./acme.js";
|
||||
import { CertReader } from "./cert-reader.js";
|
||||
import JSZip from "jszip";
|
||||
import { CertConverter } from "./convert.js";
|
||||
import { pick } from "lodash-es";
|
||||
import { CertApplyBaseConvertPlugin } from "./base-convert.js";
|
||||
|
||||
export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
|
||||
|
||||
|
@ -12,30 +10,7 @@ export async function emitCertApplySuccess(emitter: TaskEmitter, cert: CertReade
|
|||
await emitter.emit(EVENT_CERT_APPLY_SUCCESS, cert);
|
||||
}
|
||||
|
||||
export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名",
|
||||
component: {
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false,
|
||||
placeholder: "foo.com / *.foo.com / *.bar.com",
|
||||
tokenSeparators: [",", " ", ",", "、", "|"],
|
||||
},
|
||||
rules: [{ type: "domains" }],
|
||||
required: true,
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
order: -999,
|
||||
helper:
|
||||
"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、输入一个,空格之后,再输入下一个",
|
||||
})
|
||||
domains!: string[];
|
||||
export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
|
||||
|
||||
@TaskInput({
|
||||
title: "邮箱",
|
||||
|
@ -50,36 +25,6 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
})
|
||||
email!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "证书密码",
|
||||
component: {
|
||||
name: "input-password",
|
||||
vModel: "value",
|
||||
},
|
||||
required: false,
|
||||
order: 100,
|
||||
helper: "PFX、jks格式证书是否加密\njks必须设置密码,不传则默认123456\npfx不传则为空密码",
|
||||
})
|
||||
pfxPassword!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "PFX证书转换参数",
|
||||
value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES",
|
||||
component: {
|
||||
name: "a-auto-complete",
|
||||
vModel: "value",
|
||||
options: [
|
||||
{ value: "", label: "兼容 Windows Server 最新" },
|
||||
{ value: "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2016" },
|
||||
{ value: "-nomac -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES", label: "兼容 Windows Server 2008" },
|
||||
],
|
||||
},
|
||||
required: false,
|
||||
order: 100,
|
||||
helper: "兼容Windows Server各个版本",
|
||||
})
|
||||
pfxArgs = "-macalg SHA1 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES";
|
||||
|
||||
@TaskInput({
|
||||
title: "更新天数",
|
||||
value: 35,
|
||||
|
@ -111,14 +56,6 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
// })
|
||||
csrInfo!: string;
|
||||
|
||||
userContext!: IContext;
|
||||
lastStatus!: Step;
|
||||
|
||||
@TaskOutput({
|
||||
title: "域名证书",
|
||||
})
|
||||
cert?: CertInfo;
|
||||
|
||||
async onInstance() {
|
||||
this.userContext = this.ctx.userContext;
|
||||
this.lastStatus = this.ctx.lastStatus as Step;
|
||||
|
@ -151,89 +88,6 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
async output(certReader: CertReader, isNew: boolean) {
|
||||
const cert: CertInfo = certReader.toCertInfo();
|
||||
this.cert = cert;
|
||||
|
||||
this._result.pipelineVars.certExpiresTime = dayjs(certReader.detail.notAfter).valueOf();
|
||||
if (!this._result.pipelinePrivateVars) {
|
||||
this._result.pipelinePrivateVars = {};
|
||||
}
|
||||
this._result.pipelinePrivateVars.cert = cert;
|
||||
|
||||
if (isNew) {
|
||||
try {
|
||||
const converter = new CertConverter({ logger: this.logger });
|
||||
const res = await converter.convert({
|
||||
cert,
|
||||
pfxPassword: this.pfxPassword,
|
||||
pfxArgs: this.pfxArgs,
|
||||
});
|
||||
if (cert.pfx == null && res.pfx) {
|
||||
cert.pfx = res.pfx;
|
||||
}
|
||||
|
||||
if (cert.der == null && res.der) {
|
||||
cert.der = res.der;
|
||||
}
|
||||
|
||||
if (cert.jks == null && res.jks) {
|
||||
cert.jks = res.jks;
|
||||
}
|
||||
|
||||
this.logger.info("转换证书格式成功");
|
||||
} catch (e) {
|
||||
this.logger.error("转换证书格式失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
const zipFileName = certReader.buildCertFileName("zip", certReader.detail.notBefore);
|
||||
await this.zipCert(cert, zipFileName);
|
||||
} else {
|
||||
this.extendsFiles();
|
||||
}
|
||||
}
|
||||
|
||||
async zipCert(cert: CertInfo, filename: string) {
|
||||
const zip = new JSZip();
|
||||
zip.file("证书.pem", cert.crt);
|
||||
zip.file("私钥.pem", cert.key);
|
||||
zip.file("中间证书.pem", cert.ic);
|
||||
zip.file("cert.crt", cert.crt);
|
||||
zip.file("cert.key", cert.key);
|
||||
zip.file("intermediate.crt", cert.ic);
|
||||
zip.file("origin.crt", cert.oc);
|
||||
zip.file("one.pem", cert.one);
|
||||
if (cert.pfx) {
|
||||
zip.file("cert.pfx", Buffer.from(cert.pfx, "base64"));
|
||||
}
|
||||
if (cert.der) {
|
||||
zip.file("cert.der", Buffer.from(cert.der, "base64"));
|
||||
}
|
||||
if (cert.jks) {
|
||||
zip.file("cert.jks", Buffer.from(cert.jks, "base64"));
|
||||
}
|
||||
|
||||
zip.file(
|
||||
"说明.txt",
|
||||
`证书文件说明
|
||||
cert.crt:证书文件,包含证书链,pem格式
|
||||
cert.key:私钥文件,pem格式
|
||||
intermediate.crt:中间证书文件,pem格式
|
||||
origin.crt:原始证书文件,不含证书链,pem格式
|
||||
one.pem: 证书和私钥简单合并成一个文件,pem格式,crt正文+key正文
|
||||
cert.pfx:pfx格式证书文件,iis服务器使用
|
||||
cert.der:der格式证书文件
|
||||
cert.jks:jks格式证书文件,java服务器使用
|
||||
`
|
||||
);
|
||||
|
||||
const content = await zip.generateAsync({ type: "nodebuffer" });
|
||||
this.saveFile(filename, content);
|
||||
this.logger.info(`已保存文件:${filename}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否更新证书
|
||||
*/
|
||||
|
@ -279,22 +133,6 @@ cert.jks:jks格式证书文件,java服务器使用
|
|||
return null;
|
||||
}
|
||||
|
||||
formatCert(pem: string) {
|
||||
pem = pem.replace(/\r/g, "");
|
||||
pem = pem.replace(/\n\n/g, "\n");
|
||||
pem = pem.replace(/\n$/g, "");
|
||||
return pem;
|
||||
}
|
||||
|
||||
formatCerts(cert: { crt: string; key: string; csr: string }) {
|
||||
const newCert: CertInfo = {
|
||||
crt: this.formatCert(cert.crt),
|
||||
key: this.formatCert(cert.key),
|
||||
csr: this.formatCert(cert.csr),
|
||||
};
|
||||
return newCert;
|
||||
}
|
||||
|
||||
async readLastCert(): Promise<CertReader | undefined> {
|
||||
const cert = this.lastStatus?.status?.output?.cert;
|
||||
if (cert == null) {
|
||||
|
|
|
@ -1,38 +1,53 @@
|
|||
import { IsTaskPlugin, pluginGroups, RunStrategy, Step, TaskInput } from "@certd/pipeline";
|
||||
import { IsTaskPlugin, pluginGroups, RunStrategy, Step, TaskInput, TaskOutput } from "@certd/pipeline";
|
||||
import type { CertInfo } from "../acme.js";
|
||||
import { CertReader } from "../cert-reader.js";
|
||||
import { CertApplyBasePlugin } from "../base.js";
|
||||
import { CertApplyBaseConvertPlugin } from "../base-convert.js";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export { CertReader };
|
||||
export type { CertInfo };
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "CertUpload",
|
||||
name: "CertApplyUpload",
|
||||
icon: "ph:certificate",
|
||||
title: "证书手动上传",
|
||||
group: pluginGroups.cert.key,
|
||||
desc: "在证书仓库手动上传后触发部署证书",
|
||||
default: {
|
||||
input: {
|
||||
renewDays: 35,
|
||||
forceUpdate: false,
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.AlwaysRun,
|
||||
},
|
||||
},
|
||||
})
|
||||
export class CertUploadPlugin extends CertApplyBasePlugin {
|
||||
export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
|
||||
@TaskInput({
|
||||
title: "证书仓库ID",
|
||||
component: {
|
||||
name: "a-cert-select",
|
||||
vModel: "value",
|
||||
name: "cert-info-selector",
|
||||
vModel: "modelValue",
|
||||
},
|
||||
order: -9999,
|
||||
required: true,
|
||||
mergeScript: `
|
||||
return {
|
||||
component:{
|
||||
on:{
|
||||
selectedChange(scope){
|
||||
console.log(scope)
|
||||
scope.form.input.domains = scope.$event?.domains
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
certInfoId!: string;
|
||||
|
||||
@TaskOutput({
|
||||
title: "证书MD5",
|
||||
})
|
||||
certMd5?: string;
|
||||
|
||||
async onInstance() {
|
||||
this.accessService = this.ctx.accessService;
|
||||
this.logger = this.ctx.logger;
|
||||
|
@ -41,21 +56,45 @@ export class CertUploadPlugin extends CertApplyBasePlugin {
|
|||
}
|
||||
async onInit(): Promise<void> {}
|
||||
|
||||
async doCertApply() {
|
||||
const siteInfoService = this.ctx.serviceContainer["CertInfoService"];
|
||||
async getCertFromStore() {
|
||||
const siteInfoService = await this.ctx.serviceGetter.get("CertInfoService");
|
||||
|
||||
const certInfo = await siteInfoService.getCertInfo({
|
||||
certId: this.certInfoId,
|
||||
userid: this.pipeline.userId,
|
||||
userId: this.pipeline.userId,
|
||||
});
|
||||
|
||||
const certReader = new CertReader(certInfo);
|
||||
if (!certReader.expires && certReader.expires < new Date().getTime()) {
|
||||
throw new Error("证书已过期,停止部署");
|
||||
throw new Error("证书已过期,停止部署,请重新上传证书");
|
||||
}
|
||||
|
||||
return certReader;
|
||||
}
|
||||
|
||||
async execute(): Promise<string | void> {
|
||||
const certReader = await this.getCertFromStore();
|
||||
const crtMd5 = this.ctx.utils.hash.md5(certReader.cert.crt);
|
||||
|
||||
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";
|
||||
}
|
||||
this.logger.info("证书有变化,重新部署");
|
||||
this.clearLastStatus();
|
||||
//输出证书MD5
|
||||
this.certMd5 = crtMd5;
|
||||
await this.output(certReader, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
new CertUploadPlugin();
|
||||
new CertApplyUploadPlugin();
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
export * from "./cert-plugin/index.js";
|
||||
export * from "./cert-plugin/lego/index.js";
|
||||
export * from "./cert-plugin/custom/index.js";
|
||||
export const CertApplyPluginNames = ["CertApply", "CertApplyLego", "CertApplyUpload"];
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -3,34 +3,34 @@ module.exports = {
|
|||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true
|
||||
es6: true,
|
||||
},
|
||||
parser: "vue-eslint-parser",
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: "@typescript-eslint/parser",
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module",
|
||||
jsxPragma: "React",
|
||||
sourceType: 'module',
|
||||
jsxPragma: 'React',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
tsx: true
|
||||
}
|
||||
tsx: true,
|
||||
},
|
||||
},
|
||||
extends: ["plugin:vue/vue3-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "prettier"],
|
||||
extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', 'prettier'],
|
||||
rules: {
|
||||
//"max-len": [0, 200, 2, { ignoreUrls: true }],
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off"
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
// "@typescript-eslint/no-unused-vars": [
|
||||
// "error",
|
||||
// {
|
||||
|
@ -69,5 +69,5 @@ module.exports = {
|
|||
// math: "always",
|
||||
// },
|
||||
// ],
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
|
||||
"trailingComma": "none",
|
||||
"printWidth": 220
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import OutputSelector from "/@/components/plugins/common/output-selector/index.v
|
|||
import DnsProviderSelector from "/@/components/plugins/cert/dns-provider-selector/index.vue";
|
||||
import DomainsVerifyPlanEditor from "/@/components/plugins/cert/domains-verify-plan-editor/index.vue";
|
||||
import AccessSelector from "/@/views/certd/access/access-selector/index.vue";
|
||||
import CertInfoSelector from "/@/views/certd/monitor/cert/selector/index.vue";
|
||||
import InputPassword from "./common/input-password.vue";
|
||||
import ApiTest from "./common/api-test.vue";
|
||||
export * from "./cert/index.js";
|
||||
|
@ -14,6 +15,8 @@ export default {
|
|||
app.component("DnsProviderSelector", DnsProviderSelector);
|
||||
app.component("DomainsVerifyPlanEditor", DomainsVerifyPlanEditor);
|
||||
app.component("AccessSelector", AccessSelector);
|
||||
app.component("CertInfoSelector", CertInfoSelector);
|
||||
|
||||
app.component("ApiTest", ApiTest);
|
||||
|
||||
app.component("SynologyDeviceIdGetter", SynologyIdDeviceGetter);
|
||||
|
|
|
@ -7,7 +7,7 @@ export const certInfoApi = {
|
|||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query
|
||||
data: query,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -15,7 +15,7 @@ export const certInfoApi = {
|
|||
return await request({
|
||||
url: apiPrefix + "/add",
|
||||
method: "post",
|
||||
data: obj
|
||||
data: obj,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -23,7 +23,7 @@ export const certInfoApi = {
|
|||
return await request({
|
||||
url: apiPrefix + "/update",
|
||||
method: "post",
|
||||
data: obj
|
||||
data: obj,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -31,7 +31,7 @@ export const certInfoApi = {
|
|||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id }
|
||||
params: { id },
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -39,27 +39,35 @@ export const certInfoApi = {
|
|||
return await request({
|
||||
url: apiPrefix + "/info",
|
||||
method: "post",
|
||||
params: { id }
|
||||
params: { id },
|
||||
});
|
||||
},
|
||||
async ListAll() {
|
||||
return await request({
|
||||
url: apiPrefix + "/all",
|
||||
method: "post"
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
async Upload(body: { id?: number; cert: { crt: string; key: string } }) {
|
||||
return await request({
|
||||
url: apiPrefix + "/upload",
|
||||
method: "post",
|
||||
data: body
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
async GetCert(id: number): Promise<CertInfo> {
|
||||
return await request({
|
||||
url: apiPrefix + "/getCert",
|
||||
method: "post",
|
||||
params: { id: id }
|
||||
params: { id: id },
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async GetOptionsByIds(ids: number[]): Promise<any[]> {
|
||||
return await request({
|
||||
url: apiPrefix + "/getOptionsByIds",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import {
|
||||
AddReq,
|
||||
compute,
|
||||
CreateCrudOptionsProps,
|
||||
CreateCrudOptionsRet,
|
||||
DelReq,
|
||||
dict,
|
||||
EditReq,
|
||||
useFormWrapper,
|
||||
UserPageQuery,
|
||||
UserPageRes
|
||||
} from "@fast-crud/fast-crud";
|
||||
import { certInfoApi } from "./api";
|
||||
import dayjs from "dayjs";
|
||||
import { useRouter } from "vue-router";
|
||||
|
@ -9,7 +20,6 @@ import { notification } from "ant-design-vue";
|
|||
import CertView from "/@/views/certd/pipeline/cert-view.vue";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
const api = certInfoApi;
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
|
@ -48,7 +58,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
width: 800,
|
||||
content: () => {
|
||||
return <CertView cert={cert}></CertView>;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -69,35 +79,35 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
title: "ID",
|
||||
type: "number",
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
"cert.crt": {
|
||||
title: "证书",
|
||||
type: "textarea",
|
||||
form: {
|
||||
component: {
|
||||
rows: 4
|
||||
rows: 4,
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }],
|
||||
col: { span: 24 }
|
||||
}
|
||||
col: { span: 24 },
|
||||
},
|
||||
},
|
||||
"cert.key": {
|
||||
title: "私钥",
|
||||
type: "textarea",
|
||||
form: {
|
||||
component: {
|
||||
rows: 4
|
||||
rows: 4,
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }],
|
||||
col: { span: 24 }
|
||||
}
|
||||
}
|
||||
col: { span: 24 },
|
||||
},
|
||||
},
|
||||
},
|
||||
form: {
|
||||
wrapper: {
|
||||
title: "上传自定义证书"
|
||||
title: "上传自定义证书",
|
||||
},
|
||||
async doSubmit({ form }: any) {
|
||||
if (!id) {
|
||||
|
@ -106,9 +116,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
form.id = id;
|
||||
}
|
||||
return await api.Upload(form);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
const { crudOptions } = createCrudOptions();
|
||||
|
@ -121,22 +131,22 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest
|
||||
delRequest,
|
||||
},
|
||||
form: {
|
||||
labelCol: {
|
||||
//固定label宽度
|
||||
span: null,
|
||||
style: {
|
||||
width: "100px"
|
||||
}
|
||||
width: "100px",
|
||||
},
|
||||
},
|
||||
col: {
|
||||
span: 22
|
||||
span: 22,
|
||||
},
|
||||
wrapper: {
|
||||
width: 600
|
||||
}
|
||||
width: 600,
|
||||
},
|
||||
},
|
||||
actionbar: {
|
||||
show: true,
|
||||
|
@ -147,13 +157,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
show: true,
|
||||
async click() {
|
||||
await openUpload();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tabs: {
|
||||
name: "fromType",
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
rowHandle: {
|
||||
width: 140,
|
||||
|
@ -167,7 +177,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
icon: "ph:certificate",
|
||||
async click({ row }) {
|
||||
await viewCert(row);
|
||||
}
|
||||
},
|
||||
},
|
||||
copy: { show: false },
|
||||
edit: { show: false },
|
||||
|
@ -181,15 +191,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
icon: "ph:upload",
|
||||
async click({ row }) {
|
||||
await openUpload(row.id);
|
||||
}
|
||||
},
|
||||
},
|
||||
remove: {
|
||||
order: 10,
|
||||
show: compute(({ row }) => {
|
||||
return row.fromType === "upload";
|
||||
})
|
||||
}
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
|
@ -197,85 +207,85 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
key: "id",
|
||||
type: "number",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
editable: {
|
||||
disabled: true
|
||||
}
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
fromType: {
|
||||
title: "来源",
|
||||
search: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "流水线", value: "pipeline" },
|
||||
{ label: "手动上传", value: "upload" }
|
||||
]
|
||||
{ label: "手动上传", value: "upload" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
sorter: true,
|
||||
component: {
|
||||
color: "auto"
|
||||
color: "auto",
|
||||
},
|
||||
conditionalRender: false
|
||||
conditionalRender: false,
|
||||
},
|
||||
valueBuilder({ value, row, key }) {
|
||||
if (!value) {
|
||||
row[key] = "pipeline";
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
domains: {
|
||||
title: "域名",
|
||||
search: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
rules: [{ required: true, message: "请输入域名" }]
|
||||
rules: [{ required: true, message: "请输入域名" }],
|
||||
},
|
||||
column: {
|
||||
width: 450,
|
||||
sorter: true,
|
||||
component: {
|
||||
name: "fs-values-format",
|
||||
color: "auto"
|
||||
}
|
||||
}
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
domainCount: {
|
||||
title: "域名数量",
|
||||
type: "number",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 120,
|
||||
sorter: true,
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
expiresLeft: {
|
||||
title: "有效天数",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
type: "date",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
|
@ -290,54 +300,54 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
const color = leftDays < 20 ? "red" : "#389e0d";
|
||||
const percent = (leftDays / 90) * 100;
|
||||
return <a-progress title={expireDate + "过期"} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}天`} />;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
expiresTime: {
|
||||
title: "过期时间",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true
|
||||
}
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
certProvider: {
|
||||
title: "证书颁发机构",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 200
|
||||
}
|
||||
width: 200,
|
||||
},
|
||||
},
|
||||
applyTime: {
|
||||
title: "申请时间",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true
|
||||
}
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
"pipeline.title": {
|
||||
title: "关联流水线",
|
||||
search: { show: false },
|
||||
type: "link",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 350,
|
||||
|
@ -346,12 +356,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
on: {
|
||||
onClick({ row }) {
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id: row.pipelineId, editMode: "false" } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<div class="cert-info-selector w-full">
|
||||
<div class="flex-o w-full">
|
||||
<fs-table-select
|
||||
ref="tableSelectRef"
|
||||
class="flex-0"
|
||||
:model-value="modelValue"
|
||||
:dict="optionsDictRef"
|
||||
:create-crud-options="createCrudOptions"
|
||||
:crud-options-override="{
|
||||
search: { show: false },
|
||||
table: {
|
||||
scroll: {
|
||||
x: 540,
|
||||
},
|
||||
},
|
||||
}"
|
||||
:show-current="false"
|
||||
:show-select="false"
|
||||
:dialog="{ width: 960 }"
|
||||
:destroy-on-close="false"
|
||||
height="400px"
|
||||
@update:model-value="onChange"
|
||||
@dialog-closed="doRefresh"
|
||||
@selected-change="onSelectedChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import { inject, ref, Ref, watch } from "vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import createCrudOptions from "../crud";
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
import { certInfoApi } from "../api";
|
||||
|
||||
defineOptions({
|
||||
name: "CertInfoSelector",
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: number | string;
|
||||
type?: string;
|
||||
placeholder?: string;
|
||||
size?: string;
|
||||
disabled?: boolean;
|
||||
}>();
|
||||
|
||||
const onChange = async (value: number) => {
|
||||
await emitValue(value);
|
||||
};
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "selectedChange", "change"]);
|
||||
|
||||
const tableSelectRef = ref();
|
||||
|
||||
const optionsDictRef = dict({
|
||||
value: "id",
|
||||
label: "domain",
|
||||
getNodesByValues: async (values: any[]) => {
|
||||
return await certInfoApi.GetOptionsByIds(values);
|
||||
},
|
||||
});
|
||||
|
||||
// async function openTableSelectDialog() {
|
||||
// await tableSelectRef.value.open({});
|
||||
// await tableSelectRef.value.crudExpose.openAdd({});
|
||||
// }
|
||||
|
||||
const target: Ref<any> = ref({});
|
||||
|
||||
function clear() {
|
||||
if (props.disabled) {
|
||||
return;
|
||||
}
|
||||
emitValue(null);
|
||||
}
|
||||
|
||||
async function emitValue(value: any) {
|
||||
target.value = optionsDictRef.dataMap[value];
|
||||
if (value !== 0 && pipeline?.value && target && pipeline.value.userId !== target.value.userId) {
|
||||
message.error("对不起,您不能修改他人流水线的证书仓库ID");
|
||||
return;
|
||||
}
|
||||
emit("change", value);
|
||||
emit("update:modelValue", value);
|
||||
}
|
||||
|
||||
function onSelectedChange(value: any) {
|
||||
if (value && value.length > 0) {
|
||||
emit("selectedChange", value[0]);
|
||||
} else {
|
||||
emit("selectedChange", null);
|
||||
}
|
||||
}
|
||||
|
||||
// watch(
|
||||
// () => {
|
||||
// return props.modelValue;
|
||||
// },
|
||||
// async value => {
|
||||
// await optionsDictRef.loadDict();
|
||||
// target.value = optionsDictRef.dataMap[value];
|
||||
// emit("selectedChange", target.value);
|
||||
// },
|
||||
// {
|
||||
// immediate: true,
|
||||
// }
|
||||
// );
|
||||
|
||||
//当不在pipeline中编辑时,可能为空
|
||||
const pipeline = inject("pipeline", null);
|
||||
|
||||
async function doRefresh() {
|
||||
await optionsDictRef.reloadDict();
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.cert-info-selector {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -1,16 +1,7 @@
|
|||
<template>
|
||||
<div class="notification-selector">
|
||||
<div class="flex-o w-100">
|
||||
<fs-dict-select
|
||||
class="flex-1"
|
||||
:value="modelValue"
|
||||
:dict="optionsDictRef"
|
||||
:disabled="disabled"
|
||||
:render-label="renderLabel"
|
||||
:slots="selectSlots"
|
||||
:allow-clear="true"
|
||||
@update:value="onChange"
|
||||
/>
|
||||
<fs-dict-select class="flex-1" :value="modelValue" :dict="optionsDictRef" :disabled="disabled" :render-label="renderLabel" :slots="selectSlots" :allow-clear="true" @update:value="onChange" />
|
||||
<fs-table-select
|
||||
ref="tableSelectRef"
|
||||
class="flex-0"
|
||||
|
@ -18,12 +9,12 @@
|
|||
:dict="optionsDictRef"
|
||||
:create-crud-options="createCrudOptions"
|
||||
:crud-options-override="{
|
||||
search: { show: false },
|
||||
search: { show: false, initialForm: { fromType: 'upload' } },
|
||||
table: {
|
||||
scroll: {
|
||||
x: 540
|
||||
}
|
||||
}
|
||||
x: 540,
|
||||
},
|
||||
},
|
||||
}"
|
||||
:show-current="false"
|
||||
:show-select="false"
|
||||
|
@ -50,7 +41,7 @@ import createCrudOptions from "../crud";
|
|||
import { notificationProvide } from "/@/views/certd/notification/common";
|
||||
|
||||
defineOptions({
|
||||
name: "NotificationSelector"
|
||||
name: "NotificationSelector",
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -89,12 +80,12 @@ const optionsDictRef = dict({
|
|||
{
|
||||
id: 0,
|
||||
name: "使用默认通知",
|
||||
icon: "ion:notifications"
|
||||
icon: "ion:notifications",
|
||||
},
|
||||
...dict.data
|
||||
...dict.data,
|
||||
];
|
||||
dict.setData(data);
|
||||
}
|
||||
},
|
||||
});
|
||||
const renderLabel = (option: any) => {
|
||||
return <span>{option.name}</span>;
|
||||
|
@ -115,7 +106,7 @@ const selectSlots = ref({
|
|||
// res.push(<a-space style="padding: 4px 8px" />);
|
||||
// res.push(<fs-button class="w-100" type="text" icon="plus-outlined" text="新建通知渠道" onClick={openTableSelectDialog}></fs-button>);
|
||||
return res;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const target: Ref<any> = ref({});
|
||||
|
@ -141,13 +132,13 @@ watch(
|
|||
() => {
|
||||
return props.modelValue;
|
||||
},
|
||||
async (value) => {
|
||||
async value => {
|
||||
await optionsDictRef.loadDict();
|
||||
target.value = optionsDictRef.dataMap[value];
|
||||
emit("selectedChange", target.value);
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
title: inputDefine.title,
|
||||
form: {
|
||||
...inputDefine,
|
||||
show: compute((ctx) => {
|
||||
show: compute(ctx => {
|
||||
const form = formWrapperRef.value.getFormData();
|
||||
if (!form) {
|
||||
return false;
|
||||
|
@ -43,8 +43,8 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
}
|
||||
}
|
||||
return form?.certApplyPlugin === plugin.name && inputDefineShow;
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -57,17 +57,17 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
wrapper: {
|
||||
width: 1350,
|
||||
saveRemind: false,
|
||||
title: "创建证书流水线"
|
||||
title: "创建证书流水线",
|
||||
},
|
||||
group: {
|
||||
groups: {
|
||||
more: {
|
||||
header: "更多参数",
|
||||
columns: moreParams,
|
||||
collapsed: true
|
||||
}
|
||||
}
|
||||
}
|
||||
collapsed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
certApplyPlugin: {
|
||||
|
@ -76,8 +76,8 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
dict: dict({
|
||||
data: [
|
||||
{ value: "CertApply", label: "JS-ACME" },
|
||||
{ value: "CertApplyLego", label: "Lego-ACME" }
|
||||
]
|
||||
{ value: "CertApplyLego", label: "Lego-ACME" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
order: 0,
|
||||
|
@ -90,21 +90,21 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
valueChange: {
|
||||
handle: async ({ form, value }) => {
|
||||
const config = await api.GetPluginConfig({
|
||||
name: value,
|
||||
type: "builtIn"
|
||||
type: "builtIn",
|
||||
});
|
||||
if (config.sysSetting?.input) {
|
||||
merge(form, config.sysSetting.input);
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
...inputs,
|
||||
triggerCron: {
|
||||
|
@ -115,11 +115,11 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
component: {
|
||||
name: "cron-editor",
|
||||
vModel: "modelValue",
|
||||
placeholder: "0 0 4 * * *"
|
||||
placeholder: "0 0 4 * * *",
|
||||
},
|
||||
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||
order: 100
|
||||
}
|
||||
order: 100,
|
||||
},
|
||||
},
|
||||
notification: {
|
||||
title: "失败通知",
|
||||
|
@ -132,14 +132,14 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
|
|||
on: {
|
||||
selectedChange({ $event, form }) {
|
||||
form.notificationTarget = $event;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
order: 101,
|
||||
helper: "任务执行失败实时提醒"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
helper: "任务执行失败实时提醒",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
const addRequest = async ({ form }: AddReq) => {
|
||||
if (form.content == null) {
|
||||
form.content = JSON.stringify({
|
||||
title: form.title
|
||||
title: form.title,
|
||||
});
|
||||
} else {
|
||||
//复制的流水线
|
||||
|
@ -106,7 +106,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
const max = suiteDetail.pipelineCount.max;
|
||||
if (max != -1 && max <= suiteDetail.pipelineCount.used) {
|
||||
notification.error({
|
||||
message: `对不起,您最多只能创建${max}条流水线,请购买或升级套餐`
|
||||
message: `对不起,您最多只能创建${max}条流水线,请购买或升级套餐`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
type: "custom",
|
||||
when: ["error", "turnToSuccess", "success"],
|
||||
notificationId: form.notification,
|
||||
title: form.notificationTarget?.name || "自定义通知"
|
||||
title: form.notificationTarget?.name || "自定义通知",
|
||||
});
|
||||
}
|
||||
let pipeline = {
|
||||
|
@ -145,20 +145,20 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
runnableType: "step",
|
||||
input: {
|
||||
renewDays: 35,
|
||||
...form
|
||||
...form,
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: 0 // 正常执行
|
||||
runStrategy: 0, // 正常执行
|
||||
},
|
||||
type: form.certApplyPlugin
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
type: form.certApplyPlugin,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
triggers,
|
||||
notifications
|
||||
notifications,
|
||||
};
|
||||
pipeline = setRunnableIds(pipeline);
|
||||
|
||||
|
@ -173,7 +173,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
content: JSON.stringify(pipeline),
|
||||
keepHistoryCount: 30,
|
||||
type: "cert",
|
||||
from: "custom"
|
||||
from: "custom",
|
||||
});
|
||||
message.success("创建成功,请添加证书部署任务");
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id, editMode: "true" } });
|
||||
|
@ -195,7 +195,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
width: 800,
|
||||
content: () => {
|
||||
return <CertView cert={cert}></CertView>;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -230,7 +230,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
<div> {children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
const userStore = useUserStore();
|
||||
|
@ -242,7 +242,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest
|
||||
delRequest,
|
||||
},
|
||||
settings: {
|
||||
plugins: {
|
||||
|
@ -259,16 +259,16 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
selectedRowKeys,
|
||||
onSelectedChanged(selected) {
|
||||
console.log("已选择变化:", selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: {
|
||||
order: 5,
|
||||
text: "自定义流水线"
|
||||
text: "自定义流水线",
|
||||
},
|
||||
addCertd: {
|
||||
order: 1,
|
||||
|
@ -276,29 +276,29 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
type: "primary",
|
||||
click() {
|
||||
addCertdPipeline();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
form: {
|
||||
afterSubmit({ form, res, mode }) {
|
||||
if (mode === "add") {
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id: res.id, editMode: "true" } });
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
table: {
|
||||
scroll: { x: 1500 }
|
||||
scroll: { x: 1500 },
|
||||
},
|
||||
tabs: {
|
||||
name: "groupId",
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
rowHandle: {
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
dropdown: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
buttons: {
|
||||
play: {
|
||||
|
@ -313,18 +313,18 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
async onOk() {
|
||||
await api.Trigger(row.id);
|
||||
notification.success({ message: "管道已经开始运行" });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
view: {
|
||||
show: false,
|
||||
click({ row }) {
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "false" } });
|
||||
}
|
||||
},
|
||||
},
|
||||
copy: {
|
||||
click: async (context) => {
|
||||
click: async context => {
|
||||
settingStore.checkPlus();
|
||||
const { ui } = useUi();
|
||||
// @ts-ignore
|
||||
|
@ -333,10 +333,10 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
row.title = row.title + "_copy";
|
||||
await crudExpose.openCopy({
|
||||
row: row,
|
||||
index: context.index
|
||||
index: context.index,
|
||||
});
|
||||
},
|
||||
class: "need-plus"
|
||||
class: "need-plus",
|
||||
},
|
||||
config: {
|
||||
order: 1,
|
||||
|
@ -346,13 +346,13 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
icon: "ant-design:edit-outlined",
|
||||
click({ row }) {
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "true" } });
|
||||
}
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
order: 2,
|
||||
title: "修改配置/分组",
|
||||
icon: "ant-design:setting-outlined",
|
||||
dropdown: true
|
||||
dropdown: true,
|
||||
},
|
||||
viewCert: {
|
||||
order: 3,
|
||||
|
@ -361,7 +361,7 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
icon: "ph:certificate",
|
||||
async click({ row }) {
|
||||
await viewCert(row);
|
||||
}
|
||||
},
|
||||
},
|
||||
download: {
|
||||
order: 4,
|
||||
|
@ -370,13 +370,13 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
icon: "ant-design:download-outlined",
|
||||
async click({ row }) {
|
||||
await downloadCert(row);
|
||||
}
|
||||
},
|
||||
},
|
||||
remove: {
|
||||
order: 5,
|
||||
dropdown: true
|
||||
}
|
||||
}
|
||||
dropdown: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
|
@ -384,14 +384,14 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
key: "id",
|
||||
type: "number",
|
||||
search: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
column: {
|
||||
width: 100
|
||||
width: 100,
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
userId: {
|
||||
title: "用户Id",
|
||||
|
@ -399,17 +399,17 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
search: {
|
||||
show: computed(() => {
|
||||
return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
|
||||
})
|
||||
}),
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
show: computed(() => {
|
||||
return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
|
||||
}),
|
||||
width: 100
|
||||
}
|
||||
width: 100,
|
||||
},
|
||||
},
|
||||
title: {
|
||||
title: "流水线名称",
|
||||
|
@ -418,11 +418,11 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
show: true,
|
||||
title: "关键字",
|
||||
component: {
|
||||
name: "a-input"
|
||||
}
|
||||
name: "a-input",
|
||||
},
|
||||
},
|
||||
form: {
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
rules: [{ required: true, message: "此项必填" }],
|
||||
},
|
||||
column: {
|
||||
width: 350,
|
||||
|
@ -432,16 +432,16 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
// 注意:必须要on前缀
|
||||
onClick({ row }) {
|
||||
router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "false" } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
content: {
|
||||
title: "流水线内容",
|
||||
form: { show: false },
|
||||
column: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
valueBuilder({ row }) {
|
||||
if (row.content) {
|
||||
|
@ -463,18 +463,18 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
if (row.content) {
|
||||
row.content = JSON.stringify(row.content);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
_triggerCount: {
|
||||
title: "定时任务数",
|
||||
type: "number",
|
||||
column: {
|
||||
align: "center",
|
||||
width: 100
|
||||
width: 100,
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
_stepCount: {
|
||||
title: "部署任务数",
|
||||
|
@ -482,14 +482,14 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
form: { show: false },
|
||||
column: {
|
||||
align: "center",
|
||||
width: 100
|
||||
}
|
||||
width: 100,
|
||||
},
|
||||
},
|
||||
lastVars: {
|
||||
title: "到期剩余",
|
||||
type: "number",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
cellRender({ row }) {
|
||||
|
@ -501,52 +501,52 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
const percent = (leftDays / 90) * 100;
|
||||
return <a-progress percent={percent} strokeColor={color} format={(percent: number) => `${leftDays} 天`} />;
|
||||
},
|
||||
width: 150
|
||||
}
|
||||
width: 150,
|
||||
},
|
||||
},
|
||||
"lastVars.certExpiresTime": {
|
||||
title: "过期时间",
|
||||
search: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
align: "center"
|
||||
}
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
type: "dict-select",
|
||||
search: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
dict: dict({
|
||||
data: statusUtil.getOptions()
|
||||
data: statusUtil.getOptions(),
|
||||
}),
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 120,
|
||||
align: "center"
|
||||
}
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
lastHistoryTime: {
|
||||
title: "最后运行",
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 150,
|
||||
align: "center"
|
||||
}
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
title: "启用",
|
||||
|
@ -554,12 +554,12 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
dict: dict({
|
||||
data: [
|
||||
{ value: false, label: "启用" },
|
||||
{ value: true, label: "禁用" }
|
||||
]
|
||||
{ value: true, label: "禁用" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
|
@ -567,30 +567,30 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
align: "center",
|
||||
component: {
|
||||
name: "fs-dict-switch",
|
||||
vModel: "checked"
|
||||
vModel: "checked",
|
||||
},
|
||||
async valueChange({ row, key, value }) {
|
||||
return await api.UpdateObj({
|
||||
id: row.id,
|
||||
disabled: row[key]
|
||||
disabled: row[key],
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
groupId: {
|
||||
title: "分组",
|
||||
type: "dict-select",
|
||||
search: {
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
dict: groupDictRef,
|
||||
column: {
|
||||
width: 130,
|
||||
align: "center",
|
||||
component: {
|
||||
color: "auto"
|
||||
}
|
||||
}
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
order: {
|
||||
title: "排序号",
|
||||
|
@ -598,48 +598,48 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
|||
column: {
|
||||
sorter: true,
|
||||
align: "center",
|
||||
width: 80
|
||||
width: 80,
|
||||
},
|
||||
form: {
|
||||
value: 0
|
||||
}
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
keepHistoryCount: {
|
||||
title: "历史记录保持数",
|
||||
type: "number",
|
||||
form: {
|
||||
value: 20,
|
||||
helper: "历史记录保持条数,多余的会被删除"
|
||||
helper: "历史记录保持条数,多余的会被删除",
|
||||
},
|
||||
column: {
|
||||
width: 130,
|
||||
show: false
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
createTime: {
|
||||
title: "创建时间",
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 155,
|
||||
align: "center"
|
||||
}
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
updateTime: {
|
||||
title: "更新时间",
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 125,
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
"@typescript-eslint/no-empty-function": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"printWidth": 220,
|
||||
"bracketSpacing": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
|
@ -3,6 +3,9 @@ import { Constants, CrudController } from '@certd/lib-server';
|
|||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { CertInfoService } from '../../../modules/monitor/index.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import { SelectQueryBuilder } from "typeorm";
|
||||
import { CertUploadService } from "../../../modules/monitor/service/cert-upload-service.js";
|
||||
import { CertInfo } from "@certd/plugin-cert";
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -14,6 +17,8 @@ export class CertInfoController extends CrudController<CertInfoService> {
|
|||
@Inject()
|
||||
authService: AuthService;
|
||||
@Inject()
|
||||
certUploadService: CertUploadService;
|
||||
@Inject()
|
||||
pipelineService: PipelineService;
|
||||
|
||||
getService(): CertInfoService {
|
||||
|
@ -57,6 +62,31 @@ export class CertInfoController extends CrudController<CertInfoService> {
|
|||
return await super.list(body);
|
||||
}
|
||||
|
||||
|
||||
@Post('/getOptionsByIds', { summary: Constants.per.authOnly })
|
||||
async getOptionsByIds(@Body(ALL) body: {ids:any[]}) {
|
||||
|
||||
const list = await this.service.list({
|
||||
query:{
|
||||
userId: this.getUserId(),
|
||||
},
|
||||
buildQuery: (bq: SelectQueryBuilder<any>) => {
|
||||
bq.andWhere('id in (:...ids)', { ids: body.ids });
|
||||
}
|
||||
})
|
||||
|
||||
const safeList =list.map((item:any) => {
|
||||
const domainsArr = item.domains? item.domains.split(',') : [];
|
||||
return {
|
||||
id: item.id,
|
||||
domain: item.domain,
|
||||
domains:domainsArr,
|
||||
userId: item.userId,
|
||||
}
|
||||
})
|
||||
return this.ok(safeList);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
bean.userId = this.getUserId();
|
||||
|
@ -92,18 +122,25 @@ export class CertInfoController extends CrudController<CertInfoService> {
|
|||
}
|
||||
|
||||
@Post('/upload', { summary: Constants.per.authOnly })
|
||||
async upload(@Body(ALL) body: any) {
|
||||
async upload(@Body(ALL) body: {cert: CertInfo, pipeline: any, id?: number}) {
|
||||
if (body.id) {
|
||||
//修改
|
||||
await this.service.checkUserId(body.id, this.getUserId());
|
||||
await this.certUploadService.updateCert({
|
||||
id: body.id,
|
||||
userId: this.getUserId(),
|
||||
cert: body.cert,
|
||||
});
|
||||
}else{
|
||||
//添加
|
||||
body.userId = this.getUserId();
|
||||
await this.certUploadService.createUploadCertPipeline({
|
||||
userId: this.getUserId(),
|
||||
cert: body.cert,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const res = await this.service.upload(body);
|
||||
|
||||
return this.ok(res);
|
||||
return this.ok();
|
||||
}
|
||||
|
||||
@Post('/getCert', { summary: Constants.per.authOnly })
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { BaseService, CodeException, CommonException, Constants, PageReq } from '@certd/lib-server';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { CertInfoEntity } from '../entity/cert-info.js';
|
||||
import { utils } from '@certd/basic';
|
||||
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||
import { Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||
import { BaseService, CodeException, Constants, PageReq } from "@certd/lib-server";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import { CertInfoEntity } from "../entity/cert-info.js";
|
||||
import { utils } from "@certd/basic";
|
||||
import { CertInfo, CertReader } from "@certd/plugin-cert";
|
||||
|
||||
export type UploadCertReq = {
|
||||
id?: number;
|
||||
|
@ -13,6 +13,7 @@ export type UploadCertReq = {
|
|||
userId?: number;
|
||||
};
|
||||
|
||||
|
||||
@Provide("CertInfoService")
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
|
@ -168,17 +169,4 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||
return bean;
|
||||
}
|
||||
|
||||
async upload(body: { id?: number; userId?:number ;cert: CertInfo }) {
|
||||
const { id, userId, cert } = body;
|
||||
if (!cert) {
|
||||
throw new CommonException("cert can't be empty");
|
||||
}
|
||||
const res = await this.updateCert({
|
||||
id,
|
||||
certReader: new CertReader(cert),
|
||||
fromType: 'upload',
|
||||
userId
|
||||
});
|
||||
return res.id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
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 { logger } from "@certd/basic";
|
||||
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;
|
||||
};
|
||||
|
||||
export type UpdateCertReq = {
|
||||
id: number;
|
||||
cert: CertInfo;
|
||||
userId?: number;
|
||||
};
|
||||
|
||||
export type CreateUploadPipelineReq = {
|
||||
cert: CertInfo;
|
||||
userId: number;
|
||||
};
|
||||
|
||||
@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)
|
||||
})
|
||||
|
||||
if (certInfoEntity.pipelineId) {
|
||||
logger.info( `触发流水线部署:${certInfoEntity.pipelineId}`)
|
||||
await this.pipelineService.trigger(certInfoEntity.pipelineId)
|
||||
}
|
||||
}
|
||||
|
||||
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)=>{
|
||||
const newCertInfo = await this.uploadCert(tx,{
|
||||
certReader: certReader,
|
||||
fromType: 'upload',
|
||||
userId
|
||||
});
|
||||
|
||||
const pipelineTitle = certReader.getAllDomains()[0] +"上传证书自动部署";
|
||||
const notifications = [];
|
||||
notifications.push({
|
||||
type: "custom",
|
||||
when: ["error", "turnToSuccess", "success"],
|
||||
notificationId: 0,
|
||||
title: "默认通知",
|
||||
});
|
||||
let pipeline = {
|
||||
id: nanoid(10),
|
||||
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(','),
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: 0, // 正常执行
|
||||
},
|
||||
type: "CertApplyUpload",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
triggers:[],
|
||||
notifications,
|
||||
}
|
||||
const newPipeline = await tx.getRepository(PipelineEntity).save({
|
||||
userId,
|
||||
title: pipelineTitle,
|
||||
type:"cert",
|
||||
from:"cert_upload",
|
||||
content: JSON.stringify(pipeline),
|
||||
keepHistory:20,
|
||||
})
|
||||
|
||||
newCertInfo.pipelineId = newPipeline.id;
|
||||
await tx.getRepository(CertInfoEntity).save({
|
||||
id: newCertInfo.id,
|
||||
pipelineId: newPipeline.id
|
||||
});
|
||||
|
||||
return newCertInfo.id
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
await tx.getRepository(CertInfoEntity).save(bean);
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { In, MoreThan, Repository } from 'typeorm';
|
||||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from "@midwayjs/core";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { In, MoreThan, Repository } from "typeorm";
|
||||
import {
|
||||
AccessGetter,
|
||||
AccessService,
|
||||
|
@ -10,35 +10,37 @@ import {
|
|||
PageReq,
|
||||
SysPublicSettings,
|
||||
SysSettingsService,
|
||||
SysSiteInfo,
|
||||
} from '@certd/lib-server';
|
||||
import { PipelineEntity } from '../entity/pipeline.js';
|
||||
import { PipelineDetail } from '../entity/vo/pipeline-detail.js';
|
||||
import { Executor, Pipeline, ResultType, RunHistory, RunnableCollection, SysInfo, UserInfo } from '@certd/pipeline';
|
||||
import { DbStorage } from './db-storage.js';
|
||||
import { StorageService } from './storage-service.js';
|
||||
import { Cron } from '../../cron/cron.js';
|
||||
import { HistoryService } from './history-service.js';
|
||||
import { HistoryEntity } from '../entity/history.js';
|
||||
import { HistoryLogEntity } from '../entity/history-log.js';
|
||||
import { HistoryLogService } from './history-log-service.js';
|
||||
import { EmailService } from '../../basic/service/email-service.js';
|
||||
import { UserService } from '../../sys/authority/service/user-service.js';
|
||||
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
|
||||
import { CnameProxyService } from './cname-proxy-service.js';
|
||||
import { PluginConfigGetter } from '../../plugin/service/plugin-config-getter.js';
|
||||
import dayjs from 'dayjs';
|
||||
import { DbAdapter } from '../../db/index.js';
|
||||
import { isComm } from '@certd/plus-core';
|
||||
import { logger } from '@certd/basic';
|
||||
import { UrlService } from './url-service.js';
|
||||
import { NotificationService } from './notification-service.js';
|
||||
import { NotificationGetter } from './notification-getter.js';
|
||||
import { UserSuiteEntity, UserSuiteService } from '@certd/commercial-core';
|
||||
import { CertInfoService } from '../../monitor/service/cert-info-service.js';
|
||||
SysSiteInfo
|
||||
} from "@certd/lib-server";
|
||||
import { PipelineEntity } from "../entity/pipeline.js";
|
||||
import { PipelineDetail } from "../entity/vo/pipeline-detail.js";
|
||||
import { Executor, Pipeline, ResultType, RunHistory, RunnableCollection, SysInfo, UserInfo } from "@certd/pipeline";
|
||||
import { DbStorage } from "./db-storage.js";
|
||||
import { StorageService } from "./storage-service.js";
|
||||
import { Cron } from "../../cron/cron.js";
|
||||
import { HistoryService } from "./history-service.js";
|
||||
import { HistoryEntity } from "../entity/history.js";
|
||||
import { HistoryLogEntity } from "../entity/history-log.js";
|
||||
import { HistoryLogService } from "./history-log-service.js";
|
||||
import { EmailService } from "../../basic/service/email-service.js";
|
||||
import { UserService } from "../../sys/authority/service/user-service.js";
|
||||
import { CnameRecordService } from "../../cname/service/cname-record-service.js";
|
||||
import { CnameProxyService } from "./cname-proxy-service.js";
|
||||
import { PluginConfigGetter } from "../../plugin/service/plugin-config-getter.js";
|
||||
import dayjs from "dayjs";
|
||||
import { DbAdapter } from "../../db/index.js";
|
||||
import { isComm } from "@certd/plus-core";
|
||||
import { logger } from "@certd/basic";
|
||||
import { UrlService } from "./url-service.js";
|
||||
import { NotificationService } from "./notification-service.js";
|
||||
import { NotificationGetter } from "./notification-getter.js";
|
||||
import { UserSuiteEntity, UserSuiteService } from "@certd/commercial-core";
|
||||
import { CertInfoService } from "../../monitor/service/cert-info-service.js";
|
||||
|
||||
const runningTasks: Map<string | number, Executor> = new Map();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 证书申请
|
||||
*/
|
||||
|
@ -191,7 +193,10 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
await this.registerTriggerById(bean.id);
|
||||
|
||||
//保存域名信息到certInfo表
|
||||
await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains);
|
||||
if(bean.from !== 'cert_upload'){
|
||||
await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
@ -478,8 +483,10 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
const serviceContainer = {
|
||||
CertInfoService: this.certInfoService
|
||||
}
|
||||
const serviceGetter = (name: string) => {
|
||||
return serviceContainer[name]
|
||||
const serviceGetter = {
|
||||
get:(name: string) => {
|
||||
return serviceContainer[name]
|
||||
}
|
||||
}
|
||||
const executor = new Executor({
|
||||
user,
|
||||
|
@ -684,4 +691,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { CertInfo ,CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
|
||||
@IsTaskPlugin({
|
||||
|
@ -21,7 +21,7 @@ export class AliyunDeployCertToALB extends AbstractTaskPlugin {
|
|||
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { optionsUtils } from '@certd/basic/dist/utils/util.options.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToAliyunCDN',
|
||||
title: '阿里云-部署证书至CDN',
|
||||
|
@ -36,7 +36,7 @@ export class DeployCertToAliyunCDN extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
|||
import dayjs from 'dayjs';
|
||||
import { AliyunAccess, AliyunClient, createCertDomainGetterInputDefine } from '@certd/plugin-lib';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToAliyunDCDN',
|
||||
title: '阿里云-部署证书至DCDN',
|
||||
|
@ -21,7 +21,7 @@ export class DeployCertToAliyunDCDN extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipel
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { AliyunAccess, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AliyunDeployCertToFC',
|
||||
title: '阿里云-部署至阿里云FC(3.0)',
|
||||
|
@ -22,7 +22,7 @@ export class AliyunDeployCertToFC extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择证书申请任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AliyunDeployCertToNLB',
|
||||
title: '阿里云-部署至NLB(网络负载均衡)',
|
||||
|
@ -21,7 +21,7 @@ export class AliyunDeployCertToNLB extends AbstractTaskPlugin {
|
|||
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AliyunAccess } from '@certd/plugin-lib';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToAliyunOSS',
|
||||
title: '阿里云-部署证书至OSS',
|
||||
|
@ -81,7 +82,7 @@ export class DeployCertToAliyunOSS extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { AliyunAccess, AliyunClient, AliyunSslClient, CasCertInfo, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AliyunDeployCertToSLB',
|
||||
title: '阿里云-部署至SLB(传统负载均衡)',
|
||||
|
@ -21,7 +21,7 @@ export class AliyunDeployCertToSLB extends AbstractTaskPlugin {
|
|||
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipel
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { AliyunAccess, AliyunClient, AliyunSslClient, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AliyunDeployCertToWaf',
|
||||
title: '阿里云-部署至阿里云WAF',
|
||||
|
@ -22,7 +22,7 @@ export class AliyunDeployCertToWaf extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'uploadCertToAliyun'],
|
||||
from: [...CertApplyPluginNames, 'uploadCertToAliyun'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
|
||||
import { AliyunAccess } from '@certd/plugin-lib';
|
||||
import { AliyunSslClient } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
/**
|
||||
* 华东1(杭州) cn-hangzhou cas.aliyuncs.com cas-vpc.cn-hangzhou.aliyuncs.com
|
||||
* 马来西亚(吉隆坡) ap-southeast-3 cas.ap-southeast-3.aliyuncs.com cas-vpc.ap-southeast-3.aliyuncs.com
|
||||
|
@ -57,7 +57,7 @@ export class UploadCertToAliyun extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@ import { AwsAcmClient } from '../libs/aws-acm-client.js';
|
|||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { optionsUtils } from '@certd/basic/dist/utils/util.options.js';
|
||||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AwsDeployToCloudFront',
|
||||
title: 'AWS-部署证书到CloudFront',
|
||||
|
@ -25,7 +25,7 @@ export class AwsDeployToCloudFront extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'AwsUploadToACM'],
|
||||
from: [...CertApplyPluginNames, 'AwsUploadToACM'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput,
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { AwsAccess, AwsRegions } from '../access.js';
|
||||
import { AwsAcmClient } from '../libs/aws-acm-client.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'AwsUploadToACM',
|
||||
title: 'AWS-上传证书到ACM',
|
||||
|
@ -21,7 +21,7 @@ export class AwsUploadToACM extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { CacheflyAccess } from '../access.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'CacheFly',
|
||||
title: 'CacheFly-部署证书到CacheFly',
|
||||
|
@ -20,7 +20,7 @@ export class CacheFlyPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
|||
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { optionsUtils } from '@certd/basic/dist/utils/util.options.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
//命名规范,插件名称+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名
|
||||
name: 'DemoTest',
|
||||
|
@ -97,7 +97,7 @@ export class DemoTest extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
// required: true, // 必填
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { DogeClient } from '../../lib/index.js';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DogeCloudDeployToCDN',
|
||||
title: '多吉云-部署到多吉云CDN',
|
||||
|
@ -27,7 +27,7 @@ export class DogeCloudDeployToCDNPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { GcoreAccess } from '../access.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'Gcoreflush',
|
||||
title: 'Gcore-刷新Gcore证书',
|
||||
|
@ -30,7 +30,7 @@ export class GcoreflushPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { GcoreAccess } from '../access.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'Gcoreupload',
|
||||
title: 'Gcore-部署证书到Gcore',
|
||||
|
@ -26,7 +26,7 @@ export class GcoreuploadPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { CertInfo, CertReader } from '@certd/plugin-cert';
|
|||
import * as fs from 'fs';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
import path from 'path';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'CopyToLocal',
|
||||
title: '主机-复制到本机',
|
||||
|
@ -22,7 +22,7 @@ export class CopyCertToLocalPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { SshClient } from '@certd/plugin-lib';
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'hostShellExecute',
|
||||
title: '主机-执行远程主机脚本命令',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput,
|
|||
import { CertInfo, CertReader, CertReaderHandleContext } from '@certd/plugin-cert';
|
||||
import dayjs from 'dayjs';
|
||||
import { SshAccess, SshClient } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'uploadCertToHost',
|
||||
title: '主机-部署证书到SSH主机',
|
||||
|
@ -21,7 +21,7 @@ export class UploadCertToHostPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { HuaweiAccess } from '../../access/index.js';
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { resetLogConfigure } from '@certd/basic';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'HauweiDeployCertToCDN',
|
||||
title: '华为云-部署证书至CDN',
|
||||
|
@ -22,7 +22,7 @@ export class HauweiDeployCertToCDN extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskInstanceContext } from '@certd/pipeline';
|
||||
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
export type CustomScriptContext = {
|
||||
CertReader: typeof CertReader;
|
||||
self: CustomScriptPlugin;
|
||||
|
@ -37,7 +37,7 @@ export class CustomScriptPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: false,
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { CertInfo } from '@certd/plugin-cert';
|
|||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
import { ProxmoxAccess } from '../access.js';
|
||||
import { createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
//命名规范,插件名称+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名
|
||||
name: 'ProxmoxUploadCert',
|
||||
|
@ -27,7 +27,7 @@ export class ProxmoxUploadCert extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
// required: true, // 必填
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
|||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine, QiniuAccess, QiniuClient } from '@certd/plugin-lib';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { optionsUtils } from '@certd/basic/dist/utils/util.options.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'QiniuDeployCertToCDN',
|
||||
title: '七牛云-部署证书至CDN',
|
||||
|
@ -21,7 +21,7 @@ export class QiniuDeployCertToCDN extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书,或者上传到七牛云的证书id',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'QiniuCertUpload'],
|
||||
from: [...CertApplyPluginNames, 'QiniuCertUpload'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { QiniuAccess, QiniuClient } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'QiniuCertUpload',
|
||||
title: '七牛云-上传证书到七牛云',
|
||||
|
@ -26,7 +26,7 @@ export class QiniuCertUpload extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -4,7 +4,7 @@ import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
|||
import { tmpdir } from 'node:os';
|
||||
import fs from 'fs';
|
||||
import { SshAccess, SshClient } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'QnapDeploy',
|
||||
title: '威联通-部署证书到威联通',
|
||||
|
@ -25,7 +25,7 @@ export class QnapDeploy extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { TencentAccess, TencentSslClient } from '@certd/plugin-lib';
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'TencentDeployCertToCDNv2',
|
||||
title: '腾讯云-部署到CDN-v2',
|
||||
|
@ -41,7 +42,7 @@ export class TencentDeployCertToCDNv2 extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'UploadCertToTencent'],
|
||||
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { TencentAccess } from '@certd/plugin-lib';
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToTencentCDN',
|
||||
title: '腾讯云-部署到CDN(废弃)',
|
||||
|
@ -19,7 +20,7 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import dayjs from 'dayjs';
|
||||
import { TencentAccess } from '@certd/plugin-lib';
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToTencentCLB',
|
||||
title: '腾讯云-部署到CLB',
|
||||
|
@ -81,7 +82,7 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { createRemoteSelectInputDefine, TencentSslClient } from '@certd/plugin-lib';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToTencentCosPlugin',
|
||||
title: '腾讯云-部署证书到COS',
|
||||
|
@ -90,7 +90,7 @@ export class DeployCertToTencentCosPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'UploadCertToTencent'],
|
||||
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { TencentAccess } from '@certd/plugin-lib';
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { TencentAccess } from "@certd/plugin-lib";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToTencentEO',
|
||||
title: '腾讯云-部署到腾讯云EO',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipel
|
|||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { createRemoteSelectInputDefine, TencentAccess, TencentSslClient } from '@certd/plugin-lib';
|
||||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'TencentDeployCertToLive',
|
||||
title: '腾讯云-部署到腾讯云直播',
|
||||
|
@ -43,7 +43,7 @@ export class TencentDeployCertToLive extends AbstractPlusTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书,或者选择前置任务“上传证书到腾讯云”任务的证书ID',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego', 'UploadCertToTencent'],
|
||||
from: [...CertApplyPluginNames, 'UploadCertToTencent'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { utils } from '@certd/basic';
|
|||
|
||||
import dayjs from 'dayjs';
|
||||
import { AbstractPlusTaskPlugin } from '@certd/plugin-plus';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'DeployCertToTencentTKEIngress',
|
||||
title: '腾讯云-部署到TKE-ingress',
|
||||
|
@ -95,7 +95,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractPlusTaskPlugin
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
mergeScript: `
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { AbstractTaskPlugin } from '@certd/pipeline';
|
||||
import { TencentAccess } from '@certd/plugin-lib';
|
||||
import { createRemoteSelectInputDefine } from '@certd/plugin-lib';
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { createRemoteSelectInputDefine, TencentAccess } from "@certd/plugin-lib";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'TencentActionInstancesPlugin',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'UploadCertToTencent',
|
||||
title: '腾讯云-上传证书到腾讯云',
|
||||
|
@ -33,7 +33,7 @@ export class UploadCertToTencent extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { WoaiAccess } from '../access.js';
|
||||
|
||||
import { CertApplyPluginNames} from '@certd/plugin-cert';
|
||||
@IsTaskPlugin({
|
||||
name: 'WoaiCDN',
|
||||
title: '我爱云-部署证书到我爱云CDN',
|
||||
|
@ -34,7 +34,7 @@ export class WoaiCdnPlugin extends AbstractTaskPlugin {
|
|||
helper: '请选择前置任务输出的域名证书',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: ['CertApply', 'CertApplyLego'],
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue