mirror of https://github.com/certd/certd
perf: 支持多吉云cdn证书部署
parent
6e344140c6
commit
65ef685729
|
@ -67,7 +67,7 @@ jobs:
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
context: ./packages/ui/
|
context: ./packages/ui/
|
||||||
tags: |
|
tags: |
|
||||||
|
|
|
@ -21,5 +21,6 @@ export const pluginGroups = {
|
||||||
huawei: new PluginGroup("huawei", "华为云", 3),
|
huawei: new PluginGroup("huawei", "华为云", 3),
|
||||||
tencent: new PluginGroup("tencent", "腾讯云", 4),
|
tencent: new PluginGroup("tencent", "腾讯云", 4),
|
||||||
host: new PluginGroup("host", "主机", 5),
|
host: new PluginGroup("host", "主机", 5),
|
||||||
|
cdn: new PluginGroup("cdn", "CDN", 6),
|
||||||
other: new PluginGroup("other", "其他", 7),
|
other: new PluginGroup("other", "其他", 7),
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
"nanoid": "^4.0.0",
|
"nanoid": "^4.0.0",
|
||||||
"nodemailer": "^6.9.3",
|
"nodemailer": "^6.9.3",
|
||||||
"pg": "^8.12.0",
|
"pg": "^8.12.0",
|
||||||
|
"querystring": "^0.2.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"ssh2": "^1.15.0",
|
"ssh2": "^1.15.0",
|
||||||
"strip-ansi": "^7.1.0",
|
"strip-ansi": "^7.1.0",
|
||||||
|
|
|
@ -7,3 +7,4 @@ export * from './plugin-huawei/index.js';
|
||||||
export * from './plugin-demo/index.js';
|
export * from './plugin-demo/index.js';
|
||||||
export * from './plugin-other/index.js';
|
export * from './plugin-other/index.js';
|
||||||
export * from './plugin-west/index.js';
|
export * from './plugin-west/index.js';
|
||||||
|
export * from './plugin-doge/index.js';
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { IsAccess, AccessInput } from '@certd/pipeline';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这个注解将注册一个授权配置
|
||||||
|
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||||
|
*/
|
||||||
|
@IsAccess({
|
||||||
|
name: 'dogecloud',
|
||||||
|
title: '多吉云',
|
||||||
|
desc: '',
|
||||||
|
})
|
||||||
|
export class DogeCloudAccess {
|
||||||
|
/**
|
||||||
|
* 授权属性配置
|
||||||
|
*/
|
||||||
|
@AccessInput({
|
||||||
|
title: 'AccessKey',
|
||||||
|
component: {
|
||||||
|
placeholder: 'AccessKey',
|
||||||
|
},
|
||||||
|
helper: '请前往[多吉云-密钥管理](https://console.dogecloud.com/user/keys)获取',
|
||||||
|
required: true,
|
||||||
|
encrypt: false,
|
||||||
|
})
|
||||||
|
accessKey = '';
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: 'SecretKey',
|
||||||
|
component: {
|
||||||
|
placeholder: 'SecretKey',
|
||||||
|
},
|
||||||
|
helper: '请前往[多吉云-密钥管理](https://console.dogecloud.com/user/keys)获取',
|
||||||
|
required: true,
|
||||||
|
encrypt: true,
|
||||||
|
})
|
||||||
|
secretKey = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
new DogeCloudAccess();
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from './access.js';
|
||||||
|
export * from './lib/index.js';
|
||||||
|
export * from './plugins/index.js';
|
|
@ -0,0 +1,42 @@
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import querystring from 'querystring';
|
||||||
|
import { DogeCloudAccess } from '../access.js';
|
||||||
|
import { AxiosInstance } from 'axios';
|
||||||
|
|
||||||
|
export class DogeClient {
|
||||||
|
accessKey: string;
|
||||||
|
secretKey: string;
|
||||||
|
http: AxiosInstance;
|
||||||
|
constructor(access: DogeCloudAccess, http: AxiosInstance) {
|
||||||
|
this.accessKey = access.accessKey;
|
||||||
|
this.secretKey = access.secretKey;
|
||||||
|
this.http = http;
|
||||||
|
}
|
||||||
|
|
||||||
|
async request(apiPath: string, data: any = {}, jsonMode = false) {
|
||||||
|
// 这里替换为你的多吉云永久 AccessKey 和 SecretKey,可在用户中心 - 密钥管理中查看
|
||||||
|
// 请勿在客户端暴露 AccessKey 和 SecretKey,那样恶意用户将获得账号完全控制权
|
||||||
|
|
||||||
|
const body = jsonMode ? JSON.stringify(data) : querystring.encode(data);
|
||||||
|
const sign = crypto
|
||||||
|
.createHmac('sha1', this.secretKey)
|
||||||
|
.update(Buffer.from(apiPath + '\n' + body, 'utf8'))
|
||||||
|
.digest('hex');
|
||||||
|
const authorization = 'TOKEN ' + this.accessKey + ':' + sign;
|
||||||
|
const res: any = await this.http.request({
|
||||||
|
url: 'https://api.dogecloud.com' + apiPath,
|
||||||
|
method: 'POST',
|
||||||
|
data: body,
|
||||||
|
responseType: 'json',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': jsonMode ? 'application/json' : 'application/x-www-form-urlencoded',
|
||||||
|
Authorization: authorization,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.code !== 200) {
|
||||||
|
throw new Error('API Error: ' + res.msg);
|
||||||
|
}
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||||
|
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||||
|
import { DogeClient } from '../../lib/index.js';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
@IsTaskPlugin({
|
||||||
|
name: 'DogeCloudDeployToCDN',
|
||||||
|
title: '部署证书到多吉云CDN',
|
||||||
|
group: pluginGroups.cdn.key,
|
||||||
|
default: {
|
||||||
|
strategy: {
|
||||||
|
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export class DogeCloudDeployToCDNPlugin extends AbstractTaskPlugin {
|
||||||
|
@TaskInput({
|
||||||
|
title: '域名',
|
||||||
|
helper: 'CDN域名',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
domain!: string;
|
||||||
|
//证书选择,此项必须要有
|
||||||
|
@TaskInput({
|
||||||
|
title: '证书',
|
||||||
|
helper: '请选择前置任务输出的域名证书',
|
||||||
|
component: {
|
||||||
|
name: 'pi-output-selector',
|
||||||
|
from: 'CertApply',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
cert!: CertInfo;
|
||||||
|
|
||||||
|
//授权选择框
|
||||||
|
@TaskInput({
|
||||||
|
title: '多吉云授权',
|
||||||
|
helper: '多吉云AccessKey',
|
||||||
|
component: {
|
||||||
|
name: 'pi-access-selector',
|
||||||
|
type: 'dogecloud',
|
||||||
|
},
|
||||||
|
rules: [{ required: true, message: '此项必填' }],
|
||||||
|
})
|
||||||
|
accessId!: string;
|
||||||
|
|
||||||
|
dogeClient!: DogeClient;
|
||||||
|
|
||||||
|
async onInstance() {
|
||||||
|
const access = await this.accessService.getById(this.accessId);
|
||||||
|
this.dogeClient = new DogeClient(access, this.ctx.http);
|
||||||
|
}
|
||||||
|
async execute(): Promise<void> {
|
||||||
|
const certId: number = await this.updateCert();
|
||||||
|
await this.bindCert(certId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCert() {
|
||||||
|
const certReader = new CertReader(this.cert);
|
||||||
|
const data = await this.dogeClient.request('/cdn/cert/upload.json', {
|
||||||
|
note: 'certd-' + dayjs().format('YYYYMMDDHHmmss'),
|
||||||
|
cert: certReader.crt,
|
||||||
|
private: certReader.key,
|
||||||
|
});
|
||||||
|
return data.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async bindCert(certId: number) {
|
||||||
|
await this.dogeClient.request('/cdn/cert/bind.json', {
|
||||||
|
id: certId,
|
||||||
|
domain: this.domain,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new DogeCloudDeployToCDNPlugin();
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './deploy-to-cdn/index.js';
|
Loading…
Reference in New Issue