perf: 支持部署到阿里云vod

v2
xiaojunnuo 2025-07-10 21:40:35 +08:00
parent 8626b6d9f2
commit 98da4e1791
6 changed files with 223 additions and 3 deletions

View File

@ -204,4 +204,11 @@ export class CertReader {
domain = domain.replaceAll(".", "_").replaceAll("*", "_");
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
}
static appendTimeSuffix(name?: string) {
if (name == null) {
name = "certd";
}
return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS");
}
}

View File

@ -1,6 +1,5 @@
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
import { ILogger } from "@certd/basic";
export type AliyunClientV2Req = {
action: string;
version: string;

View File

@ -33,8 +33,10 @@ export type CasCertInfo = { certId: number; certName: string; certIdentifier: st
export class AliyunSslClient {
opts: AliyunSslClientOpts;
logger: ILogger;
constructor(opts: AliyunSslClientOpts) {
this.opts = opts;
this.logger = opts.logger;
}
checkRet(ret: any) {

View File

@ -0,0 +1,185 @@
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { AliyunAccess, createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
@IsTaskPlugin({
name: "AliyunDeployCertToVod",
title: "阿里云-部署至VOD",
icon: "svg:icon-aliyun",
group: pluginGroups.aliyun.key,
desc: "部署证书到阿里云视频点播vod",
needPlus: false,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
})
export class AliyunDeployCertToVod extends AbstractTaskPlugin {
@TaskInput({
title: "域名证书",
helper: "请选择证书申请任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames]
},
required: true
})
cert!: CertInfo;
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
// @TaskInput({
// title: "大区",
// value: "cn-hangzhou",
// component: {
// name: "a-auto-complete",
// vModel: "value",
// options: [
// { value: "cn-hangzhou", label: "华东1杭州" },
// { value: "ap-southeast-1", label: "新加坡" }
// ]
// },
// required: true
// })
// regionId!: string;
@TaskInput({
title: "证书接入点",
helper: "不会选就保持默认即可",
value: "cas.aliyuncs.com",
component: {
name: "a-select",
options: [
{ value: "cas.aliyuncs.com", label: "中国大陆" },
{ value: "cas.ap-southeast-1.aliyuncs.com", label: "新加坡" },
{ value: "cas.eu-central-1.aliyuncs.com", label: "德国(法兰克福)" }
]
},
required: true
})
casEndpoint!: string;
@TaskInput({
title: "Access授权",
helper: "阿里云授权AccessKeyId、AccessKeySecret",
component: {
name: "access-selector",
type: "aliyun"
},
required: true
})
accessId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: "加速域名",
helper: "请选择要部署证书的域名",
action: AliyunDeployCertToVod.prototype.onGetDomainList.name,
watches: ["accessId"],
pager: true,
search: true
})
)
domainList!: string[];
async onInstance() {
}
async execute(): Promise<void> {
this.logger.info("开始部署证书到阿里云VOD");
const access = await this.getAccess<AliyunAccess>(this.accessId);
const client = await this.getClient(access);
for (const siteId of this.domainList) {
/**
* let queries : {[key: string ]: any} = { };
* queries["DomainName"] = "324234234";
* queries["CertName"] = "ccccccc";
* queries["SSLProtocol"] = "on";
* queries["SSLPub"] = "cert";
* queries["SSLPri"] = "key";
* // runtime options
* let runtime = new $Util.RuntimeOptions({ });
* let request = new $OpenApi.OpenApiRequest({
* query: OpenApiUtil.query(queries),
* });
*/
const res = await client.doRequest({
action: "SetVodDomainCertificate",
version: "2017-03-21",
protocol: "HTTPS",
data: {
query: {
DomainName: siteId,
CertName: this.appendTimeSuffix("certd"),
SSLProtocol: "on",
SSLPub: this.cert.crt,
SSLPri: this.cert.key
}
}
});
this.logger.info(`部署站点[${siteId}]证书成功:${JSON.stringify(res)}`);
}
}
async getClient(access: AliyunAccess) {
const endpoint = `vod.cn-shanghai.aliyuncs.com`;
return access.getClient(endpoint);
}
async onGetDomainList(data: PageSearch) {
if (!this.accessId) {
throw new Error("请选择Access授权");
}
const access = await this.getAccess<AliyunAccess>(this.accessId);
/**
* let queries : {[key: string ]: any} = { };
* queries["PageSize"] = 50;
* queries["PageNumber"] = 1;
* queries["DomainName"] = "5555";
* // runtime options
* let runtime = new $Util.RuntimeOptions({ });
* let request = new $OpenApi.OpenApiRequest({
* query: OpenApiUtil.query(queries),
* });
*/
const client = await this.getClient(access);
const res = await client.doRequest({
action: "DescribeVodUserDomains",
version: "2017-03-21",
protocol: "HTTPS",
data: {
query: {
DomainName: data.searchKey,
PageNumber: data.pageNo,
PageSize: data.pageSize
}
}
});
const list = res?.Domains.PageData;
if (!list || list.length === 0) {
throw new Error("没有找到加速域名,请先在阿里云添加点播加速域名");
}
const options = list.map((item: any) => {
return {
label: item.DomainName,
value: item.DomainName,
domain: item.DomainName
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
}
}
new AliyunDeployCertToVod();

View File

@ -7,3 +7,4 @@ export * from './deploy-to-alb/index.js';
export * from './deploy-to-nlb/index.js';
export * from './deploy-to-slb/index.js';
export * from './deploy-to-fc/index.js';
export * from './deploy-to-vod/index.js';

View File

@ -1,4 +1,6 @@
import dayjs from 'dayjs';
import dayjs from "dayjs";
import { AliyunSslClient } from "@certd/plugin-lib";
import { CertInfo, CertReader } from "@certd/plugin-cert";
export const ZoneOptions = [{ value: 'cn-hangzhou' }];
export function appendTimeSuffix(name: string) {
@ -13,3 +15,27 @@ export function checkRet(ret: any) {
throw new Error('执行失败:' + ret.Message);
}
}
export async function getAliyunCertId(opts:{
cert: string | CertInfo,
sslClient: AliyunSslClient,
}) {
const { cert, sslClient } = opts;
let certId: any = cert;
let certName: any = CertReader.appendTimeSuffix("certd");
if (typeof cert === "object") {
const certReader = new CertReader(cert)
certName = certReader.buildCertName()
certId = await sslClient.uploadCert({
name: certName,
cert: cert,
});
sslClient.logger.info("上传证书成功", certId, certName);
}
return {
certId,
certName,
};
}