mirror of
https://github.com/certd/certd.git
synced 2026-05-16 13:17:29 +08:00
feat: 【破坏性更新】插件改为metadata加载模式,plugin-cert、plugin-lib包部分代码转移到certd-server中,影响自定义插件,需要修改相关import引用
ssh、aliyun、tencent、qiniu、oss等 access和client需要转移import
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: "yidunrcdn",
|
||||
title: "易盾rcdn授权",
|
||||
icon: "material-symbols:shield-outline",
|
||||
desc: "易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8)",
|
||||
})
|
||||
export class YidunRcdnAccess extends BaseAccess {
|
||||
@AccessInput({
|
||||
title: "账户",
|
||||
component: {
|
||||
placeholder: "手机号",
|
||||
},
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
username = "";
|
||||
|
||||
@AccessInput({
|
||||
title: "密码",
|
||||
component: {
|
||||
placeholder: "password",
|
||||
},
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
password = "";
|
||||
}
|
||||
|
||||
new YidunRcdnAccess();
|
||||
@@ -0,0 +1,36 @@
|
||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: "yfysms",
|
||||
title: "易发云短信",
|
||||
icon: "material-symbols:shield-outline",
|
||||
desc: "sms.yfyidc.cn/",
|
||||
})
|
||||
export class YfySmsAccess extends BaseAccess {
|
||||
@AccessInput({
|
||||
title: "KeyID",
|
||||
component: {
|
||||
placeholder: "api_key",
|
||||
},
|
||||
helper: "[获取密钥](http://sms.yfyidc.cn/user/index#)",
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
keyId = "";
|
||||
|
||||
@AccessInput({
|
||||
title: "KeySecret",
|
||||
component: {
|
||||
placeholder: "",
|
||||
},
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
keySecret = "";
|
||||
}
|
||||
|
||||
new YfySmsAccess();
|
||||
@@ -0,0 +1,37 @@
|
||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: "yidun",
|
||||
title: "易盾DCDN授权",
|
||||
icon: "material-symbols:shield-outline",
|
||||
desc: "https://user.yiduncdn.com",
|
||||
})
|
||||
export class YidunAccess extends BaseAccess {
|
||||
@AccessInput({
|
||||
title: "api_key",
|
||||
component: {
|
||||
placeholder: "api_key",
|
||||
},
|
||||
helper: "http://user.yiduncdn.com/console/index.html#/account/config/api,点击开启后获取",
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
apiKey = "";
|
||||
|
||||
@AccessInput({
|
||||
title: "api_secret",
|
||||
component: {
|
||||
placeholder: "api_secret",
|
||||
},
|
||||
helper: "http://user.yiduncdn.com/console/index.html#/account/config/api,点击开启后获取",
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
apiSecret = "";
|
||||
}
|
||||
|
||||
new YidunAccess();
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./plugins/index.js";
|
||||
export * from "./access.js";
|
||||
export * from "./access-rcdn.js";
|
||||
export * from "./access-sms.js";
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./plugin-deploy-to-cdn.js";
|
||||
export * from "./plugin-deploy-to-rcdn.js";
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "YidunDeployToCDN",
|
||||
title: "易盾-部署到易盾DCDN",
|
||||
icon: "material-symbols:shield-outline",
|
||||
group: pluginGroups.cdn.key,
|
||||
desc: "主要是防御,http://user.yiduncdn.com/",
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
needPlus: false,
|
||||
})
|
||||
export class YidunDeployToCDNPlugin extends AbstractTaskPlugin {
|
||||
//测试参数
|
||||
@TaskInput({
|
||||
title: "证书ID",
|
||||
component: {
|
||||
name: "a-input-number",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: "证书ID,在证书管理页面查看,每条记录都有证书id",
|
||||
})
|
||||
certId!: number;
|
||||
|
||||
@TaskInput({
|
||||
title: "网站域名",
|
||||
component: {
|
||||
name: "a-input",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: "网站域名和证书ID选填其中一个,填了证书ID,则忽略网站域名",
|
||||
})
|
||||
domain!: number;
|
||||
|
||||
//证书选择,此项必须要有
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
//授权选择框
|
||||
@TaskInput({
|
||||
title: "易盾授权",
|
||||
helper: "易盾CDN授权",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "yidun",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
async onInstance() {}
|
||||
async execute(): Promise<void> {
|
||||
const { domain, certId, cert } = this;
|
||||
if (!domain && !certId) {
|
||||
throw new Error("证书ID和网站域名必须填写一个");
|
||||
}
|
||||
|
||||
if (certId > 0) {
|
||||
await this.updateByCertId(cert, certId);
|
||||
} else {
|
||||
await this.updateByDomain(cert);
|
||||
}
|
||||
}
|
||||
|
||||
private async updateByCertId(cert: CertInfo, certId: number) {
|
||||
this.logger.info(`更新证书,证书ID:${certId}`);
|
||||
const url = `http://user.yiduncdn.com/v1/certs/${certId}`;
|
||||
await this.doRequest(url, "PUT", {
|
||||
cert: cert.crt,
|
||||
key: cert.key,
|
||||
});
|
||||
}
|
||||
|
||||
async doRequest(url: string, method: string, data: any) {
|
||||
const access = await this.getAccess(this.accessId);
|
||||
const { apiKey, apiSecret } = access;
|
||||
const http = this.ctx.http;
|
||||
const res: any = await http.request({
|
||||
url,
|
||||
method,
|
||||
headers: {
|
||||
"api-key": apiKey,
|
||||
"api-secret": apiSecret,
|
||||
},
|
||||
data,
|
||||
});
|
||||
if (res.code != 0) {
|
||||
throw new Error(res.msg);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private async updateByDomain(cert: CertInfo) {
|
||||
//查询站点
|
||||
const siteUrl = "http://user.yiduncdn.com/v1/sites";
|
||||
const res = await this.doRequest(siteUrl, "GET", { domain: this.domain });
|
||||
if (res.data.length === 0) {
|
||||
throw new Error(`未找到域名相关站点:${this.domain}`);
|
||||
}
|
||||
let site = null;
|
||||
for (const row of res.data) {
|
||||
if (row.domain === this.domain) {
|
||||
site = row;
|
||||
}
|
||||
}
|
||||
if (!site) {
|
||||
throw new Error(`未找到域名匹配的站点:${this.domain}`);
|
||||
}
|
||||
if (site.https_listen?.cert) {
|
||||
//有证书id
|
||||
const certId = site.https_listen.cert;
|
||||
await this.updateByCertId(cert, certId);
|
||||
} else {
|
||||
//创建证书
|
||||
this.logger.info(`创建证书,域名:${this.domain}`);
|
||||
const certUrl = `http://user.yiduncdn.com/v1/certs`;
|
||||
const name = this.domain + "_" + new Date().getTime();
|
||||
await this.doRequest(certUrl, "POST", {
|
||||
name,
|
||||
type: "custom",
|
||||
cert: cert.crt,
|
||||
key: cert.key,
|
||||
});
|
||||
|
||||
const certs: any = await this.doRequest(certUrl, "GET", {
|
||||
name,
|
||||
});
|
||||
const certId = certs.data[0].id;
|
||||
|
||||
const siteUrl = "http://user.yiduncdn.com/v1/sites";
|
||||
await this.doRequest(siteUrl, "PUT", { id: site.id, https_listen: { cert: certId } });
|
||||
}
|
||||
}
|
||||
}
|
||||
new YidunDeployToCDNPlugin();
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||
import { YidunRcdnAccess } from "../access-rcdn.js";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "YidunDeployToRCDN",
|
||||
title: "易盾-部署到易盾RCDN",
|
||||
icon: "material-symbols:shield-outline",
|
||||
group: pluginGroups.cdn.key,
|
||||
desc: "易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8)",
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
needPlus: false,
|
||||
})
|
||||
export class YidunDeployToRCDNPlugin extends AbstractTaskPlugin {
|
||||
//证书选择,此项必须要有
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
//授权选择框
|
||||
@TaskInput({
|
||||
title: "易盾RCDN授权",
|
||||
helper: "易盾RCDN授权",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "yidunrcdn",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: "域名列表",
|
||||
helper: "选择要部署证书的站点域名",
|
||||
typeName: "YidunDeployToRCDNPlugin",
|
||||
action: YidunDeployToRCDNPlugin.prototype.onGetDomainList.name,
|
||||
})
|
||||
)
|
||||
domains!: string[];
|
||||
|
||||
async onInstance() {}
|
||||
async execute(): Promise<void> {
|
||||
const access = await this.getAccess<YidunRcdnAccess>(this.accessId);
|
||||
const loginRes = await this.getLoginToken(access);
|
||||
|
||||
const curl = "https://rhcdn.yiduncdn.com/CdnDomainHttps/httpsConfiguration";
|
||||
for (const domain of this.domains) {
|
||||
// const data = {
|
||||
// doMainId: domain,
|
||||
// https: {
|
||||
// https_status: "off"
|
||||
// },
|
||||
// }
|
||||
// //先关闭https
|
||||
// const res = await this.doRequest(curl, loginRes, data);
|
||||
|
||||
const cert = this.cert;
|
||||
const update = {
|
||||
doMainId: domain,
|
||||
https: {
|
||||
https_status: "on",
|
||||
certificate_name: this.appendTimeSuffix("certd"),
|
||||
certificate_source: "0",
|
||||
certificate_value: cert.crt,
|
||||
private_key: cert.key,
|
||||
},
|
||||
};
|
||||
await this.doRequest(curl, loginRes, update);
|
||||
this.logger.info(`站点${domain}证书更新成功`);
|
||||
}
|
||||
}
|
||||
|
||||
async getLoginToken(access: YidunRcdnAccess) {
|
||||
const url = "https://rhcdn.yiduncdn.com/login/loginUser";
|
||||
const data = {
|
||||
userAccount: access.username,
|
||||
userPwd: access.password,
|
||||
remember: true,
|
||||
};
|
||||
const http = this.ctx.http;
|
||||
const res: any = await http.request({
|
||||
url,
|
||||
method: "POST",
|
||||
data,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
returnOriginRes: true,
|
||||
});
|
||||
if (!res.data?.success) {
|
||||
throw new Error(res.data?.message);
|
||||
}
|
||||
|
||||
const jsessionId = this.ctx.utils.request.getCookie(res, "JSESSIONID");
|
||||
const token = res.data?.data;
|
||||
return {
|
||||
jsessionId,
|
||||
token,
|
||||
};
|
||||
}
|
||||
|
||||
async getDomainList(loginRes: any) {
|
||||
const url = "https://rhcdn.yiduncdn.com/CdnDomain/queryForDatatables";
|
||||
const data = {
|
||||
draw: 1,
|
||||
start: 0,
|
||||
length: 1000,
|
||||
search: {
|
||||
value: "",
|
||||
regex: false,
|
||||
},
|
||||
};
|
||||
|
||||
const res = await this.doRequest(url, loginRes, data);
|
||||
return res.data?.data;
|
||||
}
|
||||
|
||||
private async doRequest(url: string, loginRes: any, data: any) {
|
||||
const http = this.ctx.http;
|
||||
const res: any = await http.request({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: {
|
||||
Cookie: `JSESSIONID=${loginRes.jsessionId};kuocai_cdn_token=${loginRes.token}`,
|
||||
},
|
||||
data,
|
||||
});
|
||||
if (!res.success) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async onGetDomainList(data: any) {
|
||||
if (!this.accessId) {
|
||||
throw new Error("请选择Access授权");
|
||||
}
|
||||
const access = await this.getAccess<YidunRcdnAccess>(this.accessId);
|
||||
|
||||
const loginRes = await this.getLoginToken(access);
|
||||
|
||||
const list = await this.getDomainList(loginRes);
|
||||
|
||||
if (!list || list.length === 0) {
|
||||
throw new Error("您账户下还没有站点域名,请先添加域名");
|
||||
}
|
||||
return list.map((item: any) => {
|
||||
return {
|
||||
label: `${item.domainName}<${item.id}>`,
|
||||
value: item.id,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
new YidunDeployToRCDNPlugin();
|
||||
Reference in New Issue
Block a user