diff --git a/packages/ui/certd-server/src/plugins/plugin-upyun/client.ts b/packages/ui/certd-server/src/plugins/plugin-upyun/client.ts new file mode 100644 index 00000000..500af726 --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-upyun/client.ts @@ -0,0 +1,77 @@ +import { UpyunAccess } from "./access.js"; +import { HttpClient, ILogger } from "@certd/basic"; +import { CertInfo } from "@certd/plugin-cert"; + +export type UpyunClientOptions = { + access: UpyunAccess + logger: ILogger; + http: HttpClient +} + +export class UpyunClient { + opts: UpyunClientOptions; + + constructor(opts: UpyunClientOptions) { + this.opts = opts; + } + + async uploadCert(cookie: string,cert:CertInfo) { + // https://console.upyun.com/api/https/certificate/ + const res = await this.doRequest({ + cookie: cookie, + url: "https://console.upyun.com/api/https/certificate/", + method: "POST", + data: { + certificate: cert.crt, + private_key: cert.key + } + }); + + return res.data.result.certificate_id; + } + + async getLoginToken() { + const access = this.opts.access + const http = this.opts.http; + const res = await http.request({ + url: "https://console.upyun.com/accounts/signin/", + method: "POST", + data: { + username: access.username, + password: access.password + }, + logRes: false, + returnResponse: true + }); + if (res.data?.errors?.length > 0) { + throw new Error(JSON.stringify(res.data.msg)); + } + const cookie = res.headers["set-cookie"]; + return cookie; + } + + async doRequest(req: { + cookie: string, + url: string, + method: string, + data: any + }) { + + const res = await this.opts.http.request({ + url: req.url, + method: req.method, + data: req.data, + headers: { + Cookie: req.cookie + } + }); + if (res.msg.errors.length > 0) { + throw new Error(JSON.stringify(res.msg)); + } + if(res.data?.error_code){ + throw new Error(res.data?.message); + } + return res; + } + +} diff --git a/packages/ui/certd-server/src/plugins/plugin-upyun/index.ts b/packages/ui/certd-server/src/plugins/plugin-upyun/index.ts index fdad254f..a5edb84e 100644 --- a/packages/ui/certd-server/src/plugins/plugin-upyun/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-upyun/index.ts @@ -1,2 +1,3 @@ export * from './plugins/index.js'; export * from './access.js'; +export * from './client.js'; diff --git a/packages/ui/certd-server/src/plugins/plugin-upyun/plugins/plugin-depoy-to-cdn.ts b/packages/ui/certd-server/src/plugins/plugin-upyun/plugins/plugin-depoy-to-cdn.ts index 17314c31..1442acea 100644 --- a/packages/ui/certd-server/src/plugins/plugin-upyun/plugins/plugin-depoy-to-cdn.ts +++ b/packages/ui/certd-server/src/plugins/plugin-upyun/plugins/plugin-depoy-to-cdn.ts @@ -1,35 +1,38 @@ -import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; -import { CertInfo } from '@certd/plugin-cert'; -import { AbstractPlusTaskPlugin } from '@certd/plugin-plus'; -import { UpyunAccess } from '../access.js'; -import {createCertDomainGetterInputDefine, createRemoteSelectInputDefine} from '@certd/plugin-lib'; -import { CertApplyPluginNames} from '@certd/plugin-cert'; -import {optionsUtils} from "@certd/basic/dist/utils/util.options.js"; +import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline"; +import { CertInfo } from "@certd/plugin-cert"; +import { AbstractPlusTaskPlugin } from "@certd/plugin-plus"; +import { UpyunAccess } from "../access.js"; +import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib"; +import { CertApplyPluginNames } from "@certd/plugin-cert"; +import { optionsUtils } from "@certd/basic/dist/utils/util.options.js"; +import { UpyunClient } from "../client.js"; + @IsTaskPlugin({ //命名规范,插件名称+功能(就是目录plugin-demo中的demo),大写字母开头,驼峰命名 - name: 'UpyunDeployToCdn', - title: '又拍云-部署证书到CDN', - icon: 'svg:icon-upyun', + name: "UpyunDeployToCdn", + title: "又拍云-部署证书到CDN", + icon: "svg:icon-upyun", + desc:"支持又拍云CDN,云存储", //插件分组 group: pluginGroups.cdn.key, needPlus: true, default: { //默认值配置照抄即可 strategy: { - runStrategy: RunStrategy.SkipWhenSucceed, - }, - }, + runStrategy: RunStrategy.SkipWhenSucceed + } + } }) //类名规范,跟上面插件名称(name)一致 export class UpyunDeployToCdn extends AbstractPlusTaskPlugin { //证书选择,此项必须要有 @TaskInput({ - title: '域名证书', - helper: '请选择前置任务输出的域名证书', + title: "域名证书", + helper: "请选择前置任务输出的域名证书", component: { - name: 'output-selector', - from: [...CertApplyPluginNames], - }, + name: "output-selector", + from: [...CertApplyPluginNames] + } // required: true, // 必填 }) cert!: CertInfo; @@ -38,142 +41,99 @@ export class UpyunDeployToCdn extends AbstractPlusTaskPlugin { certDomains!: string[]; //授权选择框 @TaskInput({ - title: 'Upyun授权', + title: "Upyun授权", component: { - name: 'access-selector', - type: 'upyun', //固定授权类型 + name: "access-selector", + type: "upyun" //固定授权类型 }, - required: true, //必填 + required: true //必填 }) accessId!: string; // @TaskInput( createRemoteSelectInputDefine({ - title: 'CDN加速域名', - helper: '选择CDN加速域名,可以手动输入', - typeName: 'UpyunDeployToCdn', + title: "加速域名", + helper: "选择加速域名,可以手动输入", + typeName: "UpyunDeployToCdn", action: UpyunDeployToCdn.prototype.onGetCdnList.name, - watches: ['accessId'], + watches: ["accessId"] }) ) cdnList!: string[]; //插件实例化时执行的方法 - async onInstance() {} + async onInstance() { + } //插件执行方法 async execute(): Promise { + const access = await this.accessService.getById(this.accessId); - const cookie = await this.getLoginToken(); + const upyunClient = new UpyunClient({ + access, + logger: this.logger, + http: this.ctx.http + }); + const cookie = await upyunClient.getLoginToken(); this.logger.info(`登录成功`); - const certId = await this.uploadCert(cookie); + const certId = await upyunClient.uploadCert(cookie, this.cert); this.logger.info(`上传证书成功:${certId}`); for (const item of this.cdnList) { this.logger.info(`开始部署证书:${item}`); - const res = await this.doRequest({ - cookie:cookie, - url: 'https://console.upyun.com/api/https/migrate/domain', - method: 'POST', - data:{ + const res = await upyunClient.doRequest({ + cookie: cookie, + url: "https://console.upyun.com/api/https/migrate/domain", + method: "POST", + data: { crt_id: certId, - domain_name : item + domain_name: item } - }) + }); this.logger.info(`部署成功:${JSON.stringify(res)}`); } - this.logger.info('部署成功'); + this.logger.info("部署成功"); } - async uploadCert(cookie:string){ - // https://console.upyun.com/api/https/certificate/ - const res = await this.doRequest({ - cookie:cookie, - url: 'https://console.upyun.com/api/https/certificate/', - method: 'POST', - data:{ - certificate: this.cert.crt, - private_key: this.cert.key - } - }) - - return res.data.result.certificate_id - } - - async getLoginToken(){ - const access = await this.accessService.getById(this.accessId) - const res = await this.http.request({ - url: 'https://console.upyun.com/accounts/signin/', - method: 'POST', - data:{ - username: access.username, - password: access.password - }, - logRes:false, - returnResponse:true - }); - if (res.data?.errors?.length>0) { - throw new Error(JSON.stringify(res.data.msg)); - } - const cookie = res.headers['set-cookie']; - return cookie; - } - - async doRequest(req:{ - cookie:string, - url:string, - method:string, - data:any - }){ - - const res = await this.http.request({ - url: req.url, - method: req.method, - data:req.data, - headers:{ - Cookie: req.cookie - } - }) - if (res.msg.errors.length>0) { - throw new Error(JSON.stringify(res.msg)); - } - return res - } async onGetCdnList() { - if(!this.accessId){ - throw new Error('accessId不能为空'); + if (!this.accessId) { + throw new Error("accessId不能为空"); } + const access = await this.accessService.getById(this.accessId); - const cookie = await this.getLoginToken(); + const upyunClient = new UpyunClient({ + access, + logger: this.logger, + http: this.ctx.http + }); + const cookie = await upyunClient.getLoginToken(); const req = { cookie, - url: 'https://console.upyun.com/api/v2/buckets/?bucket_name=&with_domains=true&business_type=file&perPage=100&page=1&tag=all&state=all&type=ucdn&security_cdn=false', - method: 'GET', - data:{} - } - const res = await this.doRequest(req); + url: "https://console.upyun.com/api/account/domains/?limit=15&business_type=file&security_cdn=false&websocket=false&key=&domain=", + method: "GET", + data: {} + }; + const res = await upyunClient.doRequest(req); - const buckets = res.data?.buckets; - if(!buckets || buckets.length === 0){ - throw new Error('没有找到CDN加速域名'); + const domains = res.data?.domains; + if (!domains || domains.length === 0) { + throw new Error("没有找到加速域名"); } - const list= [] - for (const item of buckets) { - for (const domain of item.domains) { - list.push({ - domain:domain.domain, - bucket:item.bucket_name - }); - } + const list = []; + for (const domain of domains) { + list.push({ + domain: domain.domain, + bucket: domain.bucket_name + }); } const options = list.map((item: any) => { return { value: item.domain, label: `${item.domain}<${item.bucket}>`, - domain: item.domain, + domain: item.domain }; }); return optionsUtils.buildGroupOptions(options, this.certDomains); @@ -181,5 +141,6 @@ export class UpyunDeployToCdn extends AbstractPlusTaskPlugin { } } + //实例化一下,注册插件 new UpyunDeployToCdn();