From 98da4e1791ed8bb21daf2a9914fda875d14633c9 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Thu, 10 Jul 2025 21:40:35 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E5=88=B0=E9=98=BF=E9=87=8C=E4=BA=91vod?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugin/cert-plugin/cert-reader.ts | 7 + .../src/aliyun/access/aliyun-access.ts | 3 +- .../plugin-lib/src/aliyun/lib/ssl-client.ts | 2 + .../plugin/deploy-to-vod/index.ts | 185 ++++++++++++++++++ .../src/plugins/plugin-aliyun/plugin/index.ts | 1 + .../src/plugins/plugin-aliyun/utils/index.ts | 28 ++- 6 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts index 9eee841a..adcfe468 100644 --- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts +++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts @@ -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"); + } } diff --git a/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts b/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts index 364e9f32..f7c493b9 100644 --- a/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts +++ b/packages/plugins/plugin-lib/src/aliyun/access/aliyun-access.ts @@ -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; diff --git a/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts b/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts index 2cf090a0..112b858c 100644 --- a/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts +++ b/packages/plugins/plugin-lib/src/aliyun/lib/ssl-client.ts @@ -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) { diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts new file mode 100644 index 00000000..5eee547b --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/deploy-to-vod/index.ts @@ -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 { + this.logger.info("开始部署证书到阿里云VOD"); + const access = await this.getAccess(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(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(); diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts index ebb1db9e..0334b990 100644 --- a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/index.ts @@ -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'; diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts index 6ad771bd..b9832d14 100644 --- a/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/utils/index.ts @@ -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, + }; +}