diff --git a/packages/ui/certd-server/metadata/deploy_VolcengineDeployToALB.yaml b/packages/ui/certd-server/metadata/deploy_VolcengineDeployToALB.yaml index 497cf575c..4b5c4ef45 100644 --- a/packages/ui/certd-server/metadata/deploy_VolcengineDeployToALB.yaml +++ b/packages/ui/certd-server/metadata/deploy_VolcengineDeployToALB.yaml @@ -96,6 +96,19 @@ input: 选择要部署证书的监听器 需要在监听器中选择证书中心,进行跨服务访问授权 order: 0 + certType: + title: 证书部署类型 + helper: 选择部署默认证书还是扩展证书 + component: + name: a-select + options: + - label: 默认证书 + value: default + - label: 扩展证书 + value: extension + value: default + required: true + order: 0 output: {} pluginType: deploy type: builtIn diff --git a/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/delete-expiring-cert/index.ts b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/delete-expiring-cert/index.ts new file mode 100644 index 000000000..1cec2c5be --- /dev/null +++ b/packages/ui/certd-server/src/plugins/plugin-aliyun/plugin/delete-expiring-cert/index.ts @@ -0,0 +1,159 @@ +import { IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; +import { AbstractPlusTaskPlugin } from "@certd/plugin-plus"; +import dayjs from 'dayjs'; +import { AliyunAccess } from '../../../plugin-lib/aliyun/access/index.js'; +import { AliyunSslClient } from '../../../plugin-lib/aliyun/lib/index.js'; + +@IsTaskPlugin({ + name: 'AliyunDeleteExpiringCert', + title: '阿里云-删除即将过期证书', + icon: 'ant-design:aliyun-outlined', + group: pluginGroups.aliyun.key, + desc: '仅删除未使用的证书', + default: { + strategy: { + runStrategy: RunStrategy.AlwaysRun, + }, + }, + needPlus: true, +}) +export class AliyunDeleteExpiringCert extends AbstractPlusTaskPlugin { + @TaskInput({ + title: 'Access提供者', + helper: 'access 授权', + component: { + name: 'access-selector', + type: 'aliyun', + }, + required: true, + }) + accessId!: string; + + @TaskInput({ + title: '地域', + helper: '阿里云CAS证书服务地域', + component: { + name: 'a-select', + options: [ + { value: 'cas.aliyuncs.com', label: '中国大陆' }, + { value: 'cas.ap-southeast-1.aliyuncs.com', label: '新加坡' }, + ], + }, + required: true, + value: 'cas.aliyuncs.com', + }) + endpoint!: string; + + // @TaskInput({ + // title: '关键字筛选', + // helper: '仅匹配证书名称、域名包含关键字的证书,可以不填', + // required: false, + // component: { + // name: 'a-input', + // }, + // }) + // searchKey!: string; + + @TaskInput({ + title: '最大删除数量', + helper: '单次运行最大删除数量', + value: 100, + component: { + name: 'a-input-number', + vModel: 'value', + }, + required: true, + }) + maxCount!: number; + + @TaskInput({ + title: '即将过期天数', + helper: '仅删除有效期小于此天数的证书,0表示完全过期时才删除', + value: 0, + component: { + name: 'a-input-number', + vModel: 'value', + }, + required: true, + }) + expiringDays!: number; + + @TaskInput({ + title: '检查超时时间', + helper: '检查删除任务结果超时时间,单位分钟', + value: 10, + component: { + name: 'a-input-number', + vModel: 'value', + }, + required: true, + }) + checkTimeout!: number; + + async onInstance() {} + + async execute(): Promise { + const access = await this.getAccess(this.accessId); + const sslClient = new AliyunSslClient({ + access, + logger: this.logger, + endpoint: this.endpoint, + }); + + const params = { + ShowSize: 100, + CurrentPage: 1, + // Keyword: this.searchKey, + }; + const certificates: any[] = []; + while(true){ + const res = await sslClient.doRequest('ListCertificates', params, { + method: 'POST', + }); + let list = res?.CertificateList; + if (!list || list.length === 0) { + break; + } + this.logger.info(`查询第${params.CurrentPage}页,每页${params.ShowSize}个证书,当前页共${list.length}个证书`); + + const lastDay = dayjs().add(this.expiringDays, 'day'); + list = list.filter((item: any) => { + const notAfter = item.NotAfter; + const usingProducts = item.UsingProductList; + return dayjs(notAfter).isBefore(lastDay) && (!usingProducts || usingProducts.length === 0); + }); + for (const item of list) { + this.logger.info(`证书ID:${item.CertificateId}, 过期时间:${item.NotAfter},名称:${item.CertificateName},证书域名:${item.Domain}`); + certificates.push(item); + } + params.CurrentPage++; + } + + this.logger.info(`即将过期的证书数量:${certificates.length}`); + if (certificates.length === 0) { + this.logger.info('没有即将过期的证书, 无需删除'); + return; + } + this.logger.info(`开始删除证书,共${certificates.length}个证书`); + let successCount = 0; + let failedCount = 0; + + for (const certificate of certificates) { + try { + const deleteRes = await sslClient.doRequest('DeleteUserCertificate', { + CertId: certificate.CertificateId, + }, { method: 'POST' }); + this.logger.info(`删除证书成功,证书ID:${certificate.CertificateId}, 名称:${certificate.CertificateName}, requestId:${deleteRes?.RequestId}`); + successCount++; + + } catch (error: any) { + this.logger.error(`删除证书失败,证书ID:${certificate.CertificateId}, 名称:${certificate.CertificateName}, 错误:${error.message}`); + failedCount++; + } + } + + this.logger.info(`证书删除完成,成功:${successCount}, 失败:${failedCount}`); + } +} + +new AliyunDeleteExpiringCert(); \ No newline at end of file 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 a1f43b4e2..8080cb96d 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 @@ -13,4 +13,5 @@ export * from './deploy-to-vod/index.js'; export * from './deploy-to-apigateway/index.js'; export * from './deploy-to-apig/index.js'; export * from './deploy-to-ack/index.js'; -export * from './deploy-to-all/index.js'; \ No newline at end of file +export * from './deploy-to-all/index.js'; +export * from './delete-expiring-cert/index.js'; \ No newline at end of file