mirror of https://github.com/certd/certd
perf: 支持部署到华为云obs
parent
5419b1439a
commit
9feb9d04b3
|
@ -82,6 +82,7 @@
|
|||
"cross-env": "^7.0.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"esdk-obs-nodejs": "^3.25.6",
|
||||
"form-data": "^4.0.0",
|
||||
"glob": "^11.0.0",
|
||||
"https-proxy-agent": "^7.0.5",
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { HuaweiAccess } from "../../access/index.js";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'HauweiDeployCertToOBS',
|
||||
title: '华为云-部署证书至OBS',
|
||||
icon: 'svg:icon-huawei',
|
||||
group: pluginGroups.huawei.key,
|
||||
desc: '',
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
})
|
||||
export class HauweiDeployCertToOBS extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: '域名证书',
|
||||
helper: '请选择前置任务输出的域名证书\n如果你选择使用ccm证书ID,则需要在[域名管理页面右上角开启SCM授权](https://console.huaweicloud.com/cdn/#/cdn/domain)',
|
||||
component: {
|
||||
name: 'output-selector',
|
||||
from: [...CertApplyPluginNames,'HauweiUploadToCCM'],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
cert!: CertInfo | string;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: 'Access授权',
|
||||
helper: '华为云授权AccessKeyId、AccessKeySecret',
|
||||
component: {
|
||||
name: 'access-selector',
|
||||
type: 'huawei',
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: '存储桶',
|
||||
helper: '请选择存储桶',
|
||||
action: HauweiDeployCertToOBS.prototype.onGetBucketList.name,
|
||||
})
|
||||
)
|
||||
bucketList!: string[];
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: '自定义域名',
|
||||
helper: '请选择自定义域名',
|
||||
action: HauweiDeployCertToOBS.prototype.onGetDomainList.name,
|
||||
watches: ['bucketList'],
|
||||
})
|
||||
)
|
||||
domainList!: string[];
|
||||
|
||||
|
||||
|
||||
async execute(): Promise<void> {
|
||||
if (!this.cert) {
|
||||
throw new Error('域名证书不能为空');
|
||||
}
|
||||
this.logger.info('开始部署证书到华为云obs');
|
||||
|
||||
for (const domainStr of this.domainList) {
|
||||
const [location, bucket,domain] = domainStr.split('_');
|
||||
|
||||
await this.setDomainCert({
|
||||
location,
|
||||
bucket,
|
||||
domain,
|
||||
cert: this.cert
|
||||
});
|
||||
}
|
||||
|
||||
this.logger.info('部署证书到华为云cdn完成');
|
||||
}
|
||||
|
||||
checkRet(ret: any){
|
||||
if (ret?.CommonMsg?.Status>300){
|
||||
|
||||
throw new Error(`【${ret?.CommonMsg?.Code}】${ret?.CommonMsg?.Message}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async getObsClient(opts:{region?:string,bucket?:string} = {}) {
|
||||
const { region,bucket } = opts;
|
||||
const regionStr = region? `${region}.`: 'cn-north-4.';
|
||||
const bucketStr = bucket? `${bucket}.` : '';
|
||||
const access = await this.getAccess<HuaweiAccess>(this.accessId);
|
||||
const sdk = await import('esdk-obs-nodejs');
|
||||
const obsClient = new sdk.default({
|
||||
// 推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险
|
||||
// 您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
|
||||
access_key_id: access.accessKeyId,
|
||||
secret_access_key: access.accessKeySecret,
|
||||
// 【可选】如果使用临时AK/SK和SecurityToken访问OBS,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK,也可以使用其他外部引入方式传入
|
||||
// security_token: process.env.SECURITY_TOKEN,
|
||||
// endpoint填写Bucket对应的Endpoint, 这里以华北-北京四为例,其他地区请按实际情况填写
|
||||
server: `https://${bucketStr}obs.${regionStr}myhuaweicloud.com`,
|
||||
});
|
||||
return obsClient
|
||||
}
|
||||
|
||||
async onGetBucketList(data: any) {
|
||||
const obsClient = await this.getObsClient();
|
||||
const res = await obsClient.listBuckets({
|
||||
QueryLocation:true
|
||||
})
|
||||
|
||||
this.checkRet(res)
|
||||
|
||||
const list = res.InterfaceResult?.Buckets
|
||||
|
||||
if (!list || list.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
return list.map(item => {
|
||||
return {
|
||||
value: `${item.Location}_${item.BucketName}`,
|
||||
label: `${item.BucketName}<${item.Location}>`,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async onGetDomainList(data:any) {
|
||||
if (!this.bucketList || this.bucketList.length === 0) {
|
||||
return []
|
||||
}
|
||||
const optionList = []
|
||||
for (const item of this.bucketList) {
|
||||
const [location,bucket] = item.split('_')
|
||||
|
||||
const obsClient = await this.getObsClient({region:location});
|
||||
const res = await obsClient.getBucketCustomDomain({
|
||||
Bucket: bucket,
|
||||
})
|
||||
this.checkRet(res)
|
||||
|
||||
const list = res.InterfaceResult?.Domains
|
||||
|
||||
if (!list || list.length === 0) {
|
||||
continue
|
||||
}
|
||||
const options= list.map(item => {
|
||||
return {
|
||||
value: `${location}_${bucket}_${item.DomainName}`,
|
||||
label: `${item.DomainName}<${bucket}_${location}>`,
|
||||
domain: item.DomainName,
|
||||
};
|
||||
});
|
||||
optionList.push(...options)
|
||||
}
|
||||
|
||||
return this.ctx.utils.options.buildGroupOptions( optionList,this.certDomains)
|
||||
}
|
||||
|
||||
async setDomainCert(opts:{location:string,bucket:string,domain:string,cert:string|CertInfo}){
|
||||
const {location,bucket,domain,cert} = opts
|
||||
const obsClient = await this.getObsClient({region:location});
|
||||
const params:any = {
|
||||
Bucket: bucket,
|
||||
DomainName: domain,
|
||||
Name: this.buildCertName( domain)
|
||||
};
|
||||
if (typeof cert === 'string'){
|
||||
params.CertificateId= cert
|
||||
}else{
|
||||
params.Certificate= cert.crt
|
||||
params.PrivateKey = cert.key
|
||||
}
|
||||
const res = await obsClient.setBucketCustomDomain(params)
|
||||
this.checkRet(res)
|
||||
}
|
||||
}
|
||||
new HauweiDeployCertToOBS();
|
|
@ -1,2 +1,3 @@
|
|||
export * from './deploy-to-cdn/index.js'
|
||||
export * from './upload-to-ccm/index.js'
|
||||
export * from './deploy-to-obs/index.js'
|
||||
|
|
|
@ -1602,6 +1602,9 @@ importers:
|
|||
dayjs:
|
||||
specifier: ^1.11.7
|
||||
version: 1.11.13
|
||||
esdk-obs-nodejs:
|
||||
specifier: ^3.25.6
|
||||
version: 3.25.6
|
||||
form-data:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.2
|
||||
|
@ -1629,9 +1632,6 @@ importers:
|
|||
koa-send:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
ksyun-sdk-node:
|
||||
specifier: ^1.2.4
|
||||
version: 1.2.4(encoding@0.1.13)
|
||||
kubernetes-client:
|
||||
specifier: ^9.0.0
|
||||
version: 9.0.0
|
||||
|
@ -7390,6 +7390,10 @@ packages:
|
|||
resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
esdk-obs-nodejs@3.25.6:
|
||||
resolution: {integrity: sha512-bDEznGBoSjqmFNjkL0PvkMzF6o50wa+1PSKQ1tT5CtBP/yw7Egx0c/kIVsu5Raqcip1SjKu7muzslG4xo/skew==}
|
||||
engines: {node: '>=0.12.7'}
|
||||
|
||||
eslint-config-prettier@8.10.0:
|
||||
resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==}
|
||||
hasBin: true
|
||||
|
@ -9189,9 +9193,6 @@ packages:
|
|||
kolorist@1.8.0:
|
||||
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
|
||||
|
||||
ksyun-sdk-node@1.2.4:
|
||||
resolution: {integrity: sha512-W/c1nhnZskadPP7ObmizMh+jJeHXWka0HkS8lcZfLWxwEH83B8iMFF0DrtSaDCjQRuBpgzwDLGbbp+U1D1rXlQ==}
|
||||
|
||||
kubernetes-client@9.0.0:
|
||||
resolution: {integrity: sha512-Qy8o42dZVHB9P+cIiKdWpQbz/65l/qW1fDYvlzzeSLftmL1Ne3HEiM+0TmKAwNuRW0pTJN2tRWhcccToclxJ8g==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
@ -21386,6 +21387,13 @@ snapshots:
|
|||
|
||||
escape-string-regexp@5.0.0: {}
|
||||
|
||||
esdk-obs-nodejs@3.25.6:
|
||||
dependencies:
|
||||
fast-xml-parser: 4.5.0
|
||||
log4js: 6.9.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-config-prettier@8.10.0(eslint@7.32.0):
|
||||
dependencies:
|
||||
eslint: 7.32.0
|
||||
|
@ -21527,13 +21535,13 @@ snapshots:
|
|||
resolve: 1.22.10
|
||||
semver: 6.3.1
|
||||
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
eslint: 7.32.0
|
||||
prettier: 2.8.8
|
||||
prettier-linter-helpers: 1.0.0
|
||||
optionalDependencies:
|
||||
eslint-config-prettier: 8.10.0(eslint@8.57.0)
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
|
||||
eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
|
@ -23518,17 +23526,6 @@ snapshots:
|
|||
|
||||
kolorist@1.8.0: {}
|
||||
|
||||
ksyun-sdk-node@1.2.4(encoding@0.1.13):
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
core-js: 3.42.0
|
||||
crypto-js: 4.2.0
|
||||
dayjs: 1.11.13
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
qs: 6.14.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
kubernetes-client@9.0.0:
|
||||
dependencies:
|
||||
'@kubernetes/client-node': 0.10.2
|
||||
|
@ -24252,7 +24249,7 @@ snapshots:
|
|||
eslint: 7.32.0
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
eslint-plugin-node: 11.1.0(eslint@7.32.0)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
execa: 5.1.1
|
||||
inquirer: 7.3.3
|
||||
json5: 2.2.3
|
||||
|
|
Loading…
Reference in New Issue