mirror of https://github.com/certd/certd
perf: 添加部署证书至火山 Live
- 新增 VolcengineDeployToLive 插件,用于将证书部署到火山引擎视频直播 - 新增 VolcengineDeployToVOD 插件,用于将证书部署到火山引擎视频点播 - 更新 ve-client.ts,增加对 Live 和 VOD 服务的支持pull/409/head
parent
42dfe936b7
commit
abea80e3ab
|
@ -2,3 +2,4 @@ export * from './plugin-deploy-to-cdn.js'
|
|||
export * from './plugin-deploy-to-clb.js'
|
||||
export * from './plugin-upload-to-cert-center.js'
|
||||
export * from './plugin-deploy-to-alb.js'
|
||||
export * from './plugin-deploy-to-live.js'
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { VolcengineAccess } from "../access.js";
|
||||
import { VolcengineClient } from "../ve-client.js";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "VolcengineDeployToLive",
|
||||
title: "火山引擎-部署证书至Live",
|
||||
icon: "svg:icon-volcengine",
|
||||
group: pluginGroups.volcengine.key,
|
||||
desc: "部署至火山引擎视频直播",
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed
|
||||
}
|
||||
}
|
||||
})
|
||||
export class VolcengineDeployToLive extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames]
|
||||
},
|
||||
required: true
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
|
||||
@TaskInput({
|
||||
title: "Access授权",
|
||||
helper: "火山引擎AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "volcengine"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: "直播域名",
|
||||
helper: "选择要部署证书的直播域名",
|
||||
action: VolcengineDeployToLive.prototype.onGetDomainList.name,
|
||||
watches: ["certDomains", "accessId"],
|
||||
required: true
|
||||
})
|
||||
)
|
||||
domainList!: string | string[];
|
||||
|
||||
|
||||
async onInstance() {
|
||||
}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info("开始部署证书到火山引擎视频直播");
|
||||
const service = await this.getLiveService();
|
||||
let certId = await this.uploadCert(service);
|
||||
|
||||
|
||||
for (const item of this.domainList) {
|
||||
this.logger.info(`开始部署直播域名${item}证书`);
|
||||
await service.request({
|
||||
action: "BindCert",
|
||||
body: {
|
||||
Domain: item,
|
||||
HTTPS: true,
|
||||
ChainID: certId
|
||||
}
|
||||
});
|
||||
this.logger.info(`部署直播域名${item}证书成功`);
|
||||
}
|
||||
|
||||
this.logger.info("部署完成");
|
||||
}
|
||||
|
||||
|
||||
private async uploadCert(liveService: any) {
|
||||
const res = await liveService.request({
|
||||
action: "CreateCert",
|
||||
body: {
|
||||
Rsa: {
|
||||
Pubkey: this.cert.crt,
|
||||
Prikey: this.cert.key
|
||||
},
|
||||
UseWay: "https"
|
||||
}
|
||||
});
|
||||
|
||||
const certId = res.Result.ChainID;
|
||||
this.logger.info("证书上传成功", certId);
|
||||
return certId;
|
||||
}
|
||||
|
||||
|
||||
private async getLiveService() {
|
||||
const access = await this.getAccess<VolcengineAccess>(this.accessId);
|
||||
|
||||
const client = new VolcengineClient({
|
||||
logger: this.logger,
|
||||
access,
|
||||
http: this.http
|
||||
});
|
||||
|
||||
return await client.getLiveService();
|
||||
}
|
||||
|
||||
async onGetDomainList(data: any) {
|
||||
if (!this.accessId) {
|
||||
throw new Error("请选择Access授权");
|
||||
}
|
||||
const service = await this.getLiveService();
|
||||
|
||||
const res = await service.request({
|
||||
action: "ListDomainDetail",
|
||||
body: {
|
||||
"PageNum": 1,
|
||||
"PageSize": 100
|
||||
}
|
||||
});
|
||||
|
||||
const list = res.Result?.DomainList;
|
||||
if (!list || list.length === 0) {
|
||||
throw new Error("找不到直播域名,您也可以手动输入域名");
|
||||
}
|
||||
const options = list.map((item: any) => {
|
||||
return {
|
||||
value: item.Domain,
|
||||
label: `${item.Domain}<${item.Type}>`,
|
||||
domain: item.Domain
|
||||
};
|
||||
});
|
||||
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
|
||||
}
|
||||
}
|
||||
|
||||
new VolcengineDeployToLive();
|
|
@ -0,0 +1,199 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { VolcengineAccess } from "../access.js";
|
||||
import { VolcengineClient } from "../ve-client.js";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "VolcengineDeployToVOD",
|
||||
title: "火山引擎-部署证书至VOD",
|
||||
icon: "svg:icon-volcengine",
|
||||
group: pluginGroups.volcengine.key,
|
||||
desc: "部署至火山引擎视频点播(暂不可用)",
|
||||
deprecated:"暂时缺少部署ssl接口",
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed
|
||||
}
|
||||
}
|
||||
})
|
||||
export class VolcengineDeployToVOD extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames, "VolcengineUploadToCertCenter"]
|
||||
},
|
||||
required: true
|
||||
})
|
||||
cert!: CertInfo | string;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
|
||||
@TaskInput({
|
||||
title: "Access授权",
|
||||
helper: "火山引擎AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "volcengine"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
|
||||
@TaskInput(
|
||||
// createRemoteSelectInputDefine({
|
||||
// title: "空间名称",
|
||||
// helper: "选择要部署证书的监听器\n需要在监听器中选择证书中心,进行跨服务访问授权",
|
||||
// action: VolcengineDeployToVOD.prototype.onGetSpaceList.name,
|
||||
// watches: ["certDomains", "accessId", "regionId"],
|
||||
// required: true
|
||||
// })
|
||||
{
|
||||
title: "空间名称",
|
||||
required: true
|
||||
}
|
||||
)
|
||||
spaceName!: string;
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: "点播域名",
|
||||
helper: "选择要部署证书的点播域名\n需要先在域名管理页面进行证书中心访问授权(即点击去配置SSL证书)",
|
||||
action: VolcengineDeployToVOD.prototype.onGetDomainList.name,
|
||||
watches: ["certDomains", "accessId", "spaceName"],
|
||||
required: true
|
||||
})
|
||||
)
|
||||
domainList!: string | string[];
|
||||
|
||||
|
||||
async onInstance() {
|
||||
}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info("开始部署证书到火山引擎VOD");
|
||||
const access = await this.getAccess<VolcengineAccess>(this.accessId);
|
||||
let certId = await this.uploadOrGetCertId(access);
|
||||
|
||||
const service = await this.getVodService();
|
||||
for (const item of this.domainList) {
|
||||
this.logger.info(`开始部署点播域名${item}证书`);
|
||||
await service.request({
|
||||
action: "ModifyListenerAttributes",
|
||||
query: {
|
||||
ListenerId: item,
|
||||
CertificateSource: "cert_center",
|
||||
CertCenterCertificateId: certId
|
||||
}
|
||||
});
|
||||
this.logger.info(`部署点播域名${item}证书成功`);
|
||||
}
|
||||
|
||||
this.logger.info("部署完成");
|
||||
}
|
||||
|
||||
|
||||
private async uploadOrGetCertId(access: VolcengineAccess) {
|
||||
const certService = await this.getCertService(access);
|
||||
let certId = this.cert;
|
||||
if (typeof certId !== "string") {
|
||||
const certInfo = this.cert as CertInfo;
|
||||
this.logger.info(`开始上传证书`);
|
||||
certId = await certService.ImportCertificate({
|
||||
certName: this.appendTimeSuffix("certd"),
|
||||
cert: certInfo
|
||||
});
|
||||
this.logger.info(`上传证书成功:${certId}`);
|
||||
} else {
|
||||
this.logger.info(`使用已有证书ID:${certId}`);
|
||||
}
|
||||
return certId;
|
||||
}
|
||||
|
||||
private async getCertService(access: VolcengineAccess) {
|
||||
const client = new VolcengineClient({
|
||||
logger: this.logger,
|
||||
access,
|
||||
http: this.http
|
||||
});
|
||||
|
||||
return await client.getCertCenterService();
|
||||
}
|
||||
|
||||
|
||||
private async getVodService(req?: { version?: string }) {
|
||||
const access = await this.getAccess<VolcengineAccess>(this.accessId);
|
||||
|
||||
const client = new VolcengineClient({
|
||||
logger: this.logger,
|
||||
access,
|
||||
http: this.http
|
||||
});
|
||||
|
||||
return await client.getVodService(req);
|
||||
}
|
||||
|
||||
// async onGetSpaceList(data: any) {
|
||||
// if (!this.accessId) {
|
||||
// throw new Error("请选择Access授权");
|
||||
// }
|
||||
// const service = await this.getVodService();
|
||||
//
|
||||
// const res = await service.request({
|
||||
// action: "ListSpace",
|
||||
// method: "GET",
|
||||
// query: {
|
||||
// PageSize: 100,
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// const list = res.Result;
|
||||
// if (!list || list.length === 0) {
|
||||
// throw new Error("找不到空间,您可以手动填写");
|
||||
// }
|
||||
// return list.map((item: any) => {
|
||||
// return {
|
||||
// value: item.SpaceName,
|
||||
// label: `${item.SpaceName}`
|
||||
// };
|
||||
// });
|
||||
// }
|
||||
|
||||
async onGetDomainList(data: any) {
|
||||
if (!this.accessId) {
|
||||
throw new Error("请选择Access授权");
|
||||
}
|
||||
const service = await this.getVodService();
|
||||
|
||||
const res = await service.request({
|
||||
action: "ListDomain",
|
||||
body: {
|
||||
SpaceName: this.spaceName,
|
||||
Offset: 100
|
||||
}
|
||||
});
|
||||
|
||||
const instances = res.Result?.PlayInstanceInfo?.ByteInstances;
|
||||
if (!instances || instances.length === 0) {
|
||||
throw new Error("找不到点播域名,您也可以手动输入点播域名");
|
||||
}
|
||||
const list = []
|
||||
for (const item of instances) {
|
||||
for (const domain of item.Domains) {
|
||||
list.push({
|
||||
value: item.Domain,
|
||||
label: item.Domain,
|
||||
domain: domain.Domain
|
||||
});
|
||||
}
|
||||
}
|
||||
return this.ctx.utils.options.buildGroupOptions(list, this.certDomains);
|
||||
}
|
||||
}
|
||||
|
||||
new VolcengineDeployToVOD();
|
|
@ -28,7 +28,7 @@ export class VolcengineClient {
|
|||
|
||||
service.ImportCertificate = async (body: { certName: string, cert: any }) => {
|
||||
const { certName, cert } = body;
|
||||
const res = await service.request({
|
||||
const res = await service.request({
|
||||
action: "ImportCertificate",
|
||||
method: "POST",
|
||||
body: {
|
||||
|
@ -40,7 +40,7 @@ export class VolcengineClient {
|
|||
}
|
||||
}
|
||||
});
|
||||
return res.Result.InstanceId || res.Result.RepeatId
|
||||
return res.Result.InstanceId || res.Result.RepeatId;
|
||||
};
|
||||
return service;
|
||||
}
|
||||
|
@ -59,6 +59,33 @@ export class VolcengineClient {
|
|||
return service;
|
||||
}
|
||||
|
||||
async getLiveService() {
|
||||
const CommonService = await this.getServiceCls();
|
||||
|
||||
const service = new CommonService({
|
||||
serviceName: "live",
|
||||
defaultVersion: "2023-01-01"
|
||||
});
|
||||
service.setAccessKeyId(this.opts.access.accessKeyId);
|
||||
service.setSecretKey(this.opts.access.secretAccessKey);
|
||||
service.setRegion("cn-north-1");
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
async getVodService(opts?: { version?: string }) {
|
||||
const CommonService = await this.getServiceCls();
|
||||
|
||||
const service = new CommonService({
|
||||
serviceName: "vod",
|
||||
defaultVersion: opts?.version || "2021-01-01"
|
||||
});
|
||||
service.setAccessKeyId(this.opts.access.accessKeyId);
|
||||
service.setSecretKey(this.opts.access.secretAccessKey);
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
async getAlbService(opts: { region?: string }) {
|
||||
const CommonService = await this.getServiceCls();
|
||||
|
||||
|
|
Loading…
Reference in New Issue