mirror of
https://github.com/certd/certd.git
synced 2026-04-24 04:17:25 +08:00
refactor: pipeline run log
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
import { AbstractRegistrable } from "../registry";
|
||||
import { Logger } from "log4js";
|
||||
import { logger } from "../utils/util.log";
|
||||
import { IAccessService } from "../access/access-service";
|
||||
import { IContext } from "../core/context";
|
||||
import { PluginDefine, TaskInput, TaskOutput, TaskPlugin } from "./api";
|
||||
|
||||
export abstract class AbstractPlugin extends AbstractRegistrable<PluginDefine> implements TaskPlugin {
|
||||
logger: Logger = logger;
|
||||
logger!: Logger;
|
||||
// @ts-ignore
|
||||
accessService: IAccessService;
|
||||
// @ts-ignore
|
||||
@@ -14,10 +13,11 @@ export abstract class AbstractPlugin extends AbstractRegistrable<PluginDefine> i
|
||||
// @ts-ignore
|
||||
userContext: IContext;
|
||||
|
||||
async doInit(options: { accessService: IAccessService; pipelineContext: IContext; userContext: IContext }) {
|
||||
async doInit(options: { accessService: IAccessService; pipelineContext: IContext; userContext: IContext; logger: Logger }) {
|
||||
this.accessService = options.accessService;
|
||||
this.pipelineContext = options.pipelineContext;
|
||||
this.userContext = options.userContext;
|
||||
this.logger = options.logger;
|
||||
await this.onInit();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
// @ts-ignore
|
||||
import * as acme from "@certd/acme-client";
|
||||
import _ from "lodash";
|
||||
import { logger } from "../../../utils/util.log";
|
||||
import { AbstractDnsProvider } from "../../../dns-provider/abstract-dns-provider";
|
||||
import { IContext } from "../../../core/context";
|
||||
import { IDnsProvider } from "../../../dns-provider";
|
||||
import { Challenge } from "@certd/acme-client/types/rfc8555";
|
||||
console.log("acme", acme);
|
||||
import { Logger } from "log4js";
|
||||
export class AcmeService {
|
||||
userContext: IContext;
|
||||
constructor(options: { userContext: IContext }) {
|
||||
logger: Logger;
|
||||
constructor(options: { userContext: IContext; logger: Logger }) {
|
||||
this.userContext = options.userContext;
|
||||
this.logger = options.logger;
|
||||
acme.setLogger((text: string) => {
|
||||
logger.info(text);
|
||||
this.logger.info(text);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,27 +65,27 @@ export class AcmeService {
|
||||
}
|
||||
|
||||
async challengeCreateFn(authz: any, challenge: any, keyAuthorization: string, dnsProvider: IDnsProvider) {
|
||||
logger.info("Triggered challengeCreateFn()");
|
||||
this.logger.info("Triggered challengeCreateFn()");
|
||||
|
||||
/* http-01 */
|
||||
if (challenge.type === "http-01") {
|
||||
const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
|
||||
const fileContents = keyAuthorization;
|
||||
|
||||
logger.info(`Creating challenge response for ${authz.identifier.value} at path: ${filePath}`);
|
||||
this.logger.info(`Creating challenge response for ${authz.identifier.value} at path: ${filePath}`);
|
||||
|
||||
/* Replace this */
|
||||
logger.info(`Would write "${fileContents}" to path "${filePath}"`);
|
||||
this.logger.info(`Would write "${fileContents}" to path "${filePath}"`);
|
||||
// await fs.writeFileAsync(filePath, fileContents);
|
||||
} else if (challenge.type === "dns-01") {
|
||||
/* dns-01 */
|
||||
const dnsRecord = `_acme-challenge.${authz.identifier.value}`;
|
||||
const recordValue = keyAuthorization;
|
||||
|
||||
logger.info(`Creating TXT record for ${authz.identifier.value}: ${dnsRecord}`);
|
||||
this.logger.info(`Creating TXT record for ${authz.identifier.value}: ${dnsRecord}`);
|
||||
|
||||
/* Replace this */
|
||||
logger.info(`Would create TXT record "${dnsRecord}" with value "${recordValue}"`);
|
||||
this.logger.info(`Would create TXT record "${dnsRecord}" with value "${recordValue}"`);
|
||||
|
||||
return await dnsProvider.createRecord({
|
||||
fullRecord: dnsRecord,
|
||||
@@ -106,25 +107,25 @@ export class AcmeService {
|
||||
*/
|
||||
|
||||
async challengeRemoveFn(authz: any, challenge: any, keyAuthorization: string, recordItem: any, dnsProvider: IDnsProvider) {
|
||||
logger.info("Triggered challengeRemoveFn()");
|
||||
this.logger.info("Triggered challengeRemoveFn()");
|
||||
|
||||
/* http-01 */
|
||||
if (challenge.type === "http-01") {
|
||||
const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
|
||||
|
||||
logger.info(`Removing challenge response for ${authz.identifier.value} at path: ${filePath}`);
|
||||
this.logger.info(`Removing challenge response for ${authz.identifier.value} at path: ${filePath}`);
|
||||
|
||||
/* Replace this */
|
||||
logger.info(`Would remove file on path "${filePath}"`);
|
||||
this.logger.info(`Would remove file on path "${filePath}"`);
|
||||
// await fs.unlinkAsync(filePath);
|
||||
} else if (challenge.type === "dns-01") {
|
||||
const dnsRecord = `_acme-challenge.${authz.identifier.value}`;
|
||||
const recordValue = keyAuthorization;
|
||||
|
||||
logger.info(`Removing TXT record for ${authz.identifier.value}: ${dnsRecord}`);
|
||||
this.logger.info(`Removing TXT record for ${authz.identifier.value}: ${dnsRecord}`);
|
||||
|
||||
/* Replace this */
|
||||
logger.info(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`);
|
||||
this.logger.info(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`);
|
||||
await dnsProvider.removeRecord({
|
||||
fullRecord: dnsRecord,
|
||||
type: "TXT",
|
||||
@@ -169,9 +170,9 @@ export class AcmeService {
|
||||
csr: csr.toString(),
|
||||
};
|
||||
/* Done */
|
||||
logger.debug(`CSR:\n${cert.csr}`);
|
||||
logger.debug(`Certificate:\n${cert.crt}`);
|
||||
logger.info("证书申请成功");
|
||||
this.logger.debug(`CSR:\n${cert.csr}`);
|
||||
this.logger.debug(`Certificate:\n${cert.crt}`);
|
||||
this.logger.info("证书申请成功");
|
||||
return cert;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AbstractPlugin } from "../../abstract-plugin";
|
||||
import forge from "node-forge";
|
||||
import { ContextScope, IsTask, TaskInput, TaskOutput, TaskPlugin } from "../../api";
|
||||
import { IsTask, TaskInput, TaskOutput, TaskPlugin } from "../../api";
|
||||
import dayjs from "dayjs";
|
||||
import { dnsProviderRegistry } from "../../../dns-provider";
|
||||
import { AbstractDnsProvider } from "../../../dns-provider/abstract-dns-provider";
|
||||
@@ -39,53 +39,49 @@ export type CertInfo = {
|
||||
dnsProviderType: {
|
||||
title: "DNS提供商",
|
||||
component: {
|
||||
name: "a-select",
|
||||
name: "pi-dns-provider-selector",
|
||||
},
|
||||
helper: "请选择dns解析提供商",
|
||||
},
|
||||
dnsProviderAccess: {
|
||||
title: "DNS解析授权",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
name: "pi-access-selector",
|
||||
},
|
||||
helper: "请选择dns解析提供商授权",
|
||||
},
|
||||
renewDays: {
|
||||
title: "更新天数",
|
||||
value: 20,
|
||||
component: {
|
||||
name: "a-input-number",
|
||||
value: 20,
|
||||
},
|
||||
helper: "到期前多少天后更新证书",
|
||||
},
|
||||
forceUpdate: {
|
||||
title: "强制更新",
|
||||
value: false,
|
||||
component: {
|
||||
name: "a-switch",
|
||||
vModel: "checked",
|
||||
value: false,
|
||||
},
|
||||
helper: "强制重新申请证书",
|
||||
helper: "是否强制重新申请证书",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
cert: {
|
||||
key: "cert",
|
||||
type: "CertInfo",
|
||||
title: "证书",
|
||||
scope: ContextScope.pipeline,
|
||||
title: "域名证书",
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
export class CertPlugin extends AbstractPlugin implements TaskPlugin {
|
||||
export class CertApplyPlugin extends AbstractPlugin implements TaskPlugin {
|
||||
// @ts-ignore
|
||||
acme: AcmeService;
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
protected async onInit() {
|
||||
this.acme = new AcmeService({ userContext: this.userContext });
|
||||
this.acme = new AcmeService({ userContext: this.userContext, logger: this.logger });
|
||||
}
|
||||
|
||||
async execute(input: TaskInput): Promise<TaskOutput> {
|
||||
@@ -139,7 +135,7 @@ export class CertPlugin extends AbstractPlugin implements TaskPlugin {
|
||||
const access = await this.accessService.getById(dnsProviderAccessId);
|
||||
// @ts-ignore
|
||||
const dnsProvider: AbstractDnsProvider = new dnsProviderClass();
|
||||
dnsProvider.doInit({ access });
|
||||
dnsProvider.doInit({ access, logger: this.logger });
|
||||
|
||||
const cert = await this.acme.order({
|
||||
email,
|
||||
|
||||
@@ -10,33 +10,34 @@ import { CertInfo } from "../cert-plugin";
|
||||
return {
|
||||
name: "DeployCertToAliyunCDN",
|
||||
title: "部署证书至阿里云CDN",
|
||||
desc: "依赖证书申请前置任务,自动部署域名证书至阿里云CDN",
|
||||
input: {
|
||||
domainName: {
|
||||
title: "cdn加速域名",
|
||||
title: "CDN加速域名",
|
||||
component: {
|
||||
placeholder: "cdn加速域名",
|
||||
placeholder: "你在阿里云上配置的CDN加速域名,比如certd.docmirror.cn",
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
certName: {
|
||||
title: "证书名称",
|
||||
component: {
|
||||
placeholder: "上传后将以此名称作为前缀",
|
||||
placeholder: "上传后将以此名称作为前缀备注",
|
||||
},
|
||||
},
|
||||
cert: {
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
name: "pi-output-selector",
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
accessId: {
|
||||
title: "Access提供者",
|
||||
helper: "access授权",
|
||||
title: "Access授权",
|
||||
helper: "阿里云授权AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
name: "pi-access-selector",
|
||||
type: "aliyun",
|
||||
},
|
||||
required: true,
|
||||
@@ -46,16 +47,13 @@ import { CertInfo } from "../cert-plugin";
|
||||
};
|
||||
})
|
||||
export class DeployCertToAliyunCDN extends AbstractPlugin implements TaskPlugin {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async execute(input: TaskInput): Promise<TaskOutput> {
|
||||
console.log("开始部署证书到阿里云cdn");
|
||||
const access = (await this.accessService.getById(input.accessId)) as AliyunAccess;
|
||||
const client = this.getClient(access);
|
||||
const params = await this.buildParams(input);
|
||||
await this.doRequest(client, params);
|
||||
console.log("部署完成");
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -70,7 +68,7 @@ export class DeployCertToAliyunCDN extends AbstractPlugin implements TaskPlugin
|
||||
|
||||
async buildParams(input: TaskInput) {
|
||||
const { certName, domainName } = input;
|
||||
const CertName = certName + "-" + dayjs().format("YYYYMMDDHHmmss");
|
||||
const CertName = (certName ?? "certd") + "-" + dayjs().format("YYYYMMDDHHmmss");
|
||||
const cert = input.cert as CertInfo;
|
||||
return {
|
||||
RegionId: "cn-hangzhou",
|
||||
|
||||
@@ -4,12 +4,12 @@ import { IsTask, TaskInput, TaskOutput, TaskPlugin } from "../api";
|
||||
@IsTask(() => {
|
||||
return {
|
||||
name: "EchoPlugin",
|
||||
title: "测试插件回声",
|
||||
title: "测试插件【echo】",
|
||||
input: {
|
||||
cert: {
|
||||
title: "cert",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
name: "pi-output-selector",
|
||||
},
|
||||
helper: "输出选择",
|
||||
},
|
||||
@@ -20,7 +20,7 @@ import { IsTask, TaskInput, TaskOutput, TaskPlugin } from "../api";
|
||||
export class EchoPlugin extends AbstractPlugin implements TaskPlugin {
|
||||
async execute(input: TaskInput): Promise<TaskOutput> {
|
||||
for (const key in input) {
|
||||
console.log("input :", key, input[key]);
|
||||
this.logger.info("input :", key, input[key]);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user