From 24e275fdb3d74240c02bfda5bbbd27443ac8441d Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 25 Mar 2025 13:44:41 +0800 Subject: [PATCH] feat: add volcengine certcenter deployer --- internal/deployer/providers.go | 11 ++- internal/domain/provider.go | 1 + .../volcengine_certcenter.go | 72 +++++++++++++++++++ .../workflow/node/DeployNodeConfigForm.tsx | 3 + ...deConfigFormVolcEngineCertCenterConfig.tsx | 59 +++++++++++++++ ui/src/domain/provider.ts | 2 + ui/src/i18n/locales/en/nls.provider.json | 1 + .../i18n/locales/en/nls.workflow.nodes.json | 8 ++- ui/src/i18n/locales/zh/nls.provider.json | 1 + .../i18n/locales/zh/nls.workflow.nodes.json | 8 ++- 10 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 internal/pkg/core/deployer/providers/volcengine-certcenter/volcengine_certcenter.go create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index c3578332..61d14613 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -67,6 +67,7 @@ import ( pUpyunCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/upyun-cdn" pVolcEngineALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-alb" pVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn" + pVolcEngineCertCenter "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-certcenter" pVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb" pVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn" pVolcEngineImageX "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-imagex" @@ -891,7 +892,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { } } - case domain.DeployProviderTypeVolcEngineALB, domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineImageX, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS: + case domain.DeployProviderTypeVolcEngineALB, domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCertCenter, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineImageX, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS: { access := domain.AccessConfigForVolcEngine{} if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { @@ -919,6 +920,14 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { }) return deployer, err + case domain.DeployProviderTypeVolcEngineCertCenter: + deployer, err := pVolcEngineCertCenter.NewDeployer(&pVolcEngineCertCenter.DeployerConfig{ + AccessKeyId: access.AccessKeyId, + AccessKeySecret: access.SecretAccessKey, + Region: maputil.GetString(options.ProviderDeployConfig, "region"), + }) + return deployer, err + case domain.DeployProviderTypeVolcEngineCLB: deployer, err := pVolcEngineCLB.NewDeployer(&pVolcEngineCLB.DeployerConfig{ AccessKeyId: access.AccessKeyId, diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 45326aac..029405d9 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -180,6 +180,7 @@ const ( DeployProviderTypeUpyunFile = DeployProviderType("upyun-file") DeployProviderTypeVolcEngineALB = DeployProviderType("volcengine-alb") DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") + DeployProviderTypeVolcEngineCertCenter = DeployProviderType("volcengine-certcenter") DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb") DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn") DeployProviderTypeVolcEngineImageX = DeployProviderType("volcengine-imagex") diff --git a/internal/pkg/core/deployer/providers/volcengine-certcenter/volcengine_certcenter.go b/internal/pkg/core/deployer/providers/volcengine-certcenter/volcengine_certcenter.go new file mode 100644 index 00000000..a8062641 --- /dev/null +++ b/internal/pkg/core/deployer/providers/volcengine-certcenter/volcengine_certcenter.go @@ -0,0 +1,72 @@ +package volcenginecertcenter + +import ( + "context" + "log/slog" + + xerrors "github.com/pkg/errors" + + "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/uploader" + uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/volcengine-certcenter" +) + +type DeployerConfig struct { + // 火山引擎 AccessKeyId。 + AccessKeyId string `json:"accessKeyId"` + // 火山引擎 AccessKeySecret。 + AccessKeySecret string `json:"accessKeySecret"` + // 火山引擎地域。 + Region string `json:"region"` +} + +type DeployerProvider struct { + config *DeployerConfig + logger *slog.Logger + sslUploader uploader.Uploader +} + +var _ deployer.Deployer = (*DeployerProvider)(nil) + +func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { + if config == nil { + panic("config is nil") + } + + uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + Region: config.Region, + }) + if err != nil { + return nil, xerrors.Wrap(err, "failed to create ssl uploader") + } + + return &DeployerProvider{ + config: config, + logger: slog.Default(), + sslUploader: uploader, + }, nil +} + +func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { + if logger == nil { + d.logger = slog.Default() + } else { + d.logger = logger + } + d.sslUploader.WithLogger(logger) + return d +} + +func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { + // 上传证书到证书中心 + upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) + if err != nil { + return nil, xerrors.Wrap(err, "failed to upload certificate file") + } else { + d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) + } + + return &deployer.DeployResult{}, nil +} diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index f1f6c6a0..8941432f 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -74,6 +74,7 @@ import DeployNodeConfigFormUpyunCDNConfig from "./DeployNodeConfigFormUpyunCDNCo import DeployNodeConfigFormUpyunFileConfig from "./DeployNodeConfigFormUpyunFileConfig.tsx"; import DeployNodeConfigFormVolcEngineALBConfig from "./DeployNodeConfigFormVolcEngineALBConfig.tsx"; import DeployNodeConfigFormVolcEngineCDNConfig from "./DeployNodeConfigFormVolcEngineCDNConfig.tsx"; +import DeployNodeConfigFormVolcEngineCertCenterConfig from "./DeployNodeConfigFormVolcEngineCertCenterConfig.tsx"; import DeployNodeConfigFormVolcEngineCLBConfig from "./DeployNodeConfigFormVolcEngineCLBConfig.tsx"; import DeployNodeConfigFormVolcEngineDCDNConfig from "./DeployNodeConfigFormVolcEngineDCDNConfig.tsx"; import DeployNodeConfigFormVolcEngineImageXConfig from "./DeployNodeConfigFormVolcEngineImageXConfig.tsx"; @@ -269,6 +270,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOY_PROVIDERS.VOLCENGINE_CDN: return ; + case DEPLOY_PROVIDERS.VOLCENGINE_CERTCENTER: + return ; case DEPLOY_PROVIDERS.VOLCENGINE_CLB: return ; case DEPLOY_PROVIDERS.VOLCENGINE_DCDN: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx new file mode 100644 index 00000000..21f4557f --- /dev/null +++ b/ui/src/components/workflow/node/DeployNodeConfigFormVolcEngineCertCenterConfig.tsx @@ -0,0 +1,59 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +type DeployNodeConfigFormVolcEngineCertCenterConfigFieldValues = Nullish<{ + region: string; +}>; + +export type DeployNodeConfigFormVolcEngineCertCenterConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormVolcEngineCertCenterConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormVolcEngineCertCenterConfigFieldValues) => void; +}; + +const initFormModel = (): DeployNodeConfigFormVolcEngineCertCenterConfigFieldValues => { + return {}; +}; + +const DeployNodeConfigFormVolcEngineCertCenterConfig = ({ + form: formInst, + formName, + disabled, + initialValues, + onValuesChange, +}: DeployNodeConfigFormVolcEngineCertCenterConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + region: z + .string({ message: t("workflow_node.deploy.form.volcengine_certcenter_region.placeholder") }) + .nonempty(t("workflow_node.deploy.form.volcengine_certcenter_region.placeholder")) + .trim(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ + + +
+ ); +}; + +export default DeployNodeConfigFormVolcEngineCertCenterConfig; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 301d8883..950c72cb 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -294,6 +294,7 @@ export const DEPLOY_PROVIDERS = Object.freeze({ UPYUN_FILE: `${ACCESS_PROVIDERS.UPYUN}-file`, VOLCENGINE_ALB: `${ACCESS_PROVIDERS.VOLCENGINE}-alb`, VOLCENGINE_CDN: `${ACCESS_PROVIDERS.VOLCENGINE}-cdn`, + VOLCENGINE_CERTCENTER: `${ACCESS_PROVIDERS.VOLCENGINE}-certcenter`, VOLCENGINE_CLB: `${ACCESS_PROVIDERS.VOLCENGINE}-clb`, VOLCENGINE_DCDN: `${ACCESS_PROVIDERS.VOLCENGINE}-dcdn`, VOLCENGINE_IMAGEX: `${ACCESS_PROVIDERS.VOLCENGINE}-imagex`, @@ -375,6 +376,7 @@ export const deployProvidersMap: Maphttps://console.volcengine.com/alb", - "workflow_node.deploy.form.volcengine_clb_snidomain.label": "VolcEngine CLB SNI domain (Optional)", - "workflow_node.deploy.form.volcengine_clb_snidomain.placeholder": "Please enter VolcEngine CLB SNI domain name", - "workflow_node.deploy.form.volcengine_clb_snidomain.tooltip": "For more information, see https://console.volcengine.com/alb", + "workflow_node.deploy.form.volcengine_alb_snidomain.label": "VolcEngine CLB SNI domain (Optional)", + "workflow_node.deploy.form.volcengine_alb_snidomain.placeholder": "Please enter VolcEngine CLB SNI domain name", + "workflow_node.deploy.form.volcengine_alb_snidomain.tooltip": "For more information, see https://console.volcengine.com/alb", "workflow_node.deploy.form.volcengine_cdn_domain.label": "VolcEngine CDN domain", "workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "Please enter VolcEngine CDN domain name", "workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "For more information, see https://console.volcengine.com/cdn/homepage", + "workflow_node.deploy.form.volcengine_certcenter_region.label": "VolcEngine Certificate Center region", + "workflow_node.deploy.form.volcengine_certcenter_region.placeholder": "Please enter VolcEngine Certificate Center region (e.g. cn-beijing)", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "Resource type", "workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.volcengine_clb_resource_type.option.loadbalancer.label": "CLB load balancer", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index fcd924f1..62806a9d 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -112,6 +112,7 @@ "provider.volcengine": "火山引擎", "provider.volcengine.alb": "火山引擎 - 应用型负载均衡 ALB", "provider.volcengine.cdn": "火山引擎 - 内容分发网络 CDN", + "provider.volcengine.certcenter": "火山引擎 - 上传到证书中心", "provider.volcengine.clb": "火山引擎 - 负载均衡 CLB", "provider.volcengine.dcdn": "火山引擎 - 全站加速 DCDN", "provider.volcengine.dns": "火山引擎 - 云解析 DNS", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 715efd41..b0fd81ad 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -573,12 +573,14 @@ "workflow_node.deploy.form.volcengine_alb_listener_id.label": "火山引擎 ALB 监听器 ID", "workflow_node.deploy.form.volcengine_alb_listener_id.placeholder": "请输入火山引擎 ALB 监听器 ID", "workflow_node.deploy.form.volcengine_alb_listener_id.tooltip": "这是什么?请参阅 https://console.volcengine.com/alb", - "workflow_node.deploy.form.volcengine_clb_snidomain.label": "火山引擎 ALB 扩展域名(可选)", - "workflow_node.deploy.form.volcengine_clb_snidomain.placeholder": "请输入火山引擎 ALB 扩展域名(支持泛域名)", - "workflow_node.deploy.form.volcengine_clb_snidomain.tooltip": "这是什么?请参阅 https://console.volcengine.com/alb

不填写时,将替换监听器的默认证书。", + "workflow_node.deploy.form.volcengine_alb_snidomain.label": "火山引擎 ALB 扩展域名(可选)", + "workflow_node.deploy.form.volcengine_alb_snidomain.placeholder": "请输入火山引擎 ALB 扩展域名(支持泛域名)", + "workflow_node.deploy.form.volcengine_alb_snidomain.tooltip": "这是什么?请参阅 https://console.volcengine.com/alb

不填写时,将替换监听器的默认证书。", "workflow_node.deploy.form.volcengine_cdn_domain.label": "火山引擎 CDN 加速域名", "workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "请输入火山引擎 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "这是什么?请参阅 https://console.volcengine.com/cdn/homepage", + "workflow_node.deploy.form.volcengine_certcenter_region.label": "火山引擎证书中心服务地域", + "workflow_node.deploy.form.volcengine_certcenter_region.placeholder": "请输入火山引擎证书中心服务地域(例如:cn-beijing)", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "证书替换方式", "workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "请选择证书替换方式", "workflow_node.deploy.form.volcengine_clb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听的证书",