diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 269f1130..4c45b724 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -34,6 +34,7 @@ import ( providerTencentCloudCSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-css" providerTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn" providerTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo" + providerTencentCloudSSLDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy" providerUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn" providerUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3" providerVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn" @@ -387,7 +388,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger, return deployer, logger, err } - case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO: + case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO, domain.DeployProviderTypeTencentCloudSSLDeploy: { access := domain.AccessConfigForTencentCloud{} if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { @@ -450,6 +451,16 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger, }, logger) return deployer, logger, err + case domain.DeployProviderTypeTencentCloudSSLDeploy: + deployer, err := providerTencentCloudSSLDeploy.NewWithLogger(&providerTencentCloudSSLDeploy.TencentCloudSSLDeployDeployerConfig{ + SecretId: access.SecretId, + SecretKey: access.SecretKey, + Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), + ResourceType: maps.GetValueAsString(options.ProviderDeployConfig, "resourceType"), + ResourceIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }), + }, logger) + return deployer, logger, err + default: break } diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 8d192aaf..cfbe2d70 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -82,40 +82,41 @@ type DeployProviderType string NOTICE: If you add new constant, please keep ASCII order. */ const ( - DeployProviderTypeAliyunALB = DeployProviderType("aliyun-alb") - DeployProviderTypeAliyunCASDeploy = DeployProviderType("aliyun-cas-deploy") - DeployProviderTypeAliyunCDN = DeployProviderType("aliyun-cdn") - DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb") - DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn") - DeployProviderTypeAliyunESA = DeployProviderType("aliyun-esa") - DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live") - DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") - DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") - DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf") - DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront") - DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") - DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") - DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn") - DeployProviderTypeEdgioApplications = DeployProviderType("edgio-applications") - DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") - DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") - DeployProviderTypeKubernetesSecret = DeployProviderType("k8s-secret") - DeployProviderTypeLocal = DeployProviderType("local") - DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn") - DeployProviderTypeQiniuPili = DeployProviderType("qiniu-pili") - DeployProviderTypeSSH = DeployProviderType("ssh") - DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn") - DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb") - DeployProviderTypeTencentCloudCOS = DeployProviderType("tencentcloud-cos") - DeployProviderTypeTencentCloudCSS = DeployProviderType("tencentcloud-css") - DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") - DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") - DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn") - DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3") - DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") - DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb") - DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn") - DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live") - DeployProviderTypeVolcEngineTOS = DeployProviderType("volcengine-tos") - DeployProviderTypeWebhook = DeployProviderType("webhook") + DeployProviderTypeAliyunALB = DeployProviderType("aliyun-alb") + DeployProviderTypeAliyunCASDeploy = DeployProviderType("aliyun-casdeploy") + DeployProviderTypeAliyunCDN = DeployProviderType("aliyun-cdn") + DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb") + DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn") + DeployProviderTypeAliyunESA = DeployProviderType("aliyun-esa") + DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live") + DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") + DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") + DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf") + DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront") + DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") + DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") + DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn") + DeployProviderTypeEdgioApplications = DeployProviderType("edgio-applications") + DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") + DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") + DeployProviderTypeKubernetesSecret = DeployProviderType("k8s-secret") + DeployProviderTypeLocal = DeployProviderType("local") + DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn") + DeployProviderTypeQiniuPili = DeployProviderType("qiniu-pili") + DeployProviderTypeSSH = DeployProviderType("ssh") + DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn") + DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb") + DeployProviderTypeTencentCloudCOS = DeployProviderType("tencentcloud-cos") + DeployProviderTypeTencentCloudCSS = DeployProviderType("tencentcloud-css") + DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") + DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") + DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType("tencentcloud-ssldeploy") + DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn") + DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3") + DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") + DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb") + DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn") + DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live") + DeployProviderTypeVolcEngineTOS = DeployProviderType("volcengine-tos") + DeployProviderTypeWebhook = DeployProviderType("webhook") ) diff --git a/internal/pkg/core/deployer/providers/tencentcloud-clb/defines.go b/internal/pkg/core/deployer/providers/tencentcloud-clb/defines.go index 47eedfb0..7e7eace9 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-clb/defines.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-clb/defines.go @@ -4,7 +4,7 @@ type DeployResourceType string const ( // 资源类型:通过 SSL 服务部署到云资源实例。 - DEPLOY_RESOURCE_USE_SSLDEPLOY = DeployResourceType("ssl-deploy") + DEPLOY_RESOURCE_VIA_SSLDEPLOY = DeployResourceType("ssl-deploy") // 资源类型:部署到指定负载均衡器。 DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer") // 资源类型:部署到指定监听器。 diff --git a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go index d67eb383..e6982817 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb.go @@ -96,8 +96,8 @@ func (d *TencentCloudCLBDeployer) Deploy(ctx context.Context, certPem string, pr // 根据部署资源类型决定部署方式 switch d.config.ResourceType { - case DEPLOY_RESOURCE_USE_SSLDEPLOY: - if err := d.deployToInstanceUseSsl(ctx, upres.CertId); err != nil { + case DEPLOY_RESOURCE_VIA_SSLDEPLOY: + if err := d.deployViaSslService(ctx, upres.CertId); err != nil { return nil, err } @@ -123,7 +123,7 @@ func (d *TencentCloudCLBDeployer) Deploy(ctx context.Context, certPem string, pr return &deployer.DeployResult{}, nil } -func (d *TencentCloudCLBDeployer) deployToInstanceUseSsl(ctx context.Context, cloudCertId string) error { +func (d *TencentCloudCLBDeployer) deployViaSslService(ctx context.Context, cloudCertId string) error { if d.config.LoadbalancerId == "" { return errors.New("config `loadbalancerId` is required") } diff --git a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb_test.go b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb_test.go index 0af11dff..74a1e23e 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb_test.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-clb/tencentcloud_clb_test.go @@ -68,7 +68,7 @@ func TestDeploy(t *testing.T) { SecretId: fSecretId, SecretKey: fSecretKey, Region: fRegion, - ResourceType: provider.DEPLOY_RESOURCE_USE_SSLDEPLOY, + ResourceType: provider.DEPLOY_RESOURCE_VIA_SSLDEPLOY, LoadbalancerId: fLoadbalancerId, ListenerId: fListenerId, Domain: fDomain, diff --git a/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go b/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go new file mode 100644 index 00000000..37c00ea4 --- /dev/null +++ b/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go @@ -0,0 +1,156 @@ +package tencentcloudssldeploy + +import ( + "context" + "errors" + "fmt" + "time" + + xerrors "github.com/pkg/errors" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" + + "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" + "github.com/usual2970/certimate/internal/pkg/core/uploader" + uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" +) + +type TencentCloudSSLDeployDeployerConfig struct { + // 腾讯云 SecretId。 + SecretId string `json:"secretId"` + // 腾讯云 SecretKey。 + SecretKey string `json:"secretKey"` + // 腾讯云地域。 + Region string `json:"region"` + // 腾讯云云资源类型。 + ResourceType string `json:"resourceType"` + // 腾讯云云资源 ID 数组。 + ResourceIds []string `json:"resourceIds"` +} + +type TencentCloudSSLDeployDeployer struct { + config *TencentCloudSSLDeployDeployerConfig + logger logger.Logger + sdkClient *tcSsl.Client + sslUploader uploader.Uploader +} + +var _ deployer.Deployer = (*TencentCloudSSLDeployDeployer)(nil) + +func New(config *TencentCloudSSLDeployDeployerConfig) (*TencentCloudSSLDeployDeployer, error) { + return NewWithLogger(config, logger.NewNilLogger()) +} + +func NewWithLogger(config *TencentCloudSSLDeployDeployerConfig, logger logger.Logger) (*TencentCloudSSLDeployDeployer, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + if logger == nil { + return nil, errors.New("logger is nil") + } + + client, err := createSdkClient(config.SecretId, config.SecretKey, config.Region) + if err != nil { + return nil, xerrors.Wrap(err, "failed to create sdk client") + } + + uploader, err := uploaderp.New(&uploaderp.TencentCloudSSLUploaderConfig{ + SecretId: config.SecretId, + SecretKey: config.SecretKey, + }) + if err != nil { + return nil, xerrors.Wrap(err, "failed to create ssl uploader") + } + + return &TencentCloudSSLDeployDeployer{ + logger: logger, + config: config, + sdkClient: client, + sslUploader: uploader, + }, nil +} + +func (d *TencentCloudSSLDeployDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { + if d.config.ResourceType == "" { + return nil, errors.New("config `resourceType` is required") + } + if len(d.config.ResourceIds) == 0 { + return nil, errors.New("config `resourceIds` is required") + } + + // 上传证书到 SSL + upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) + if err != nil { + return nil, xerrors.Wrap(err, "failed to upload certificate file") + } + + d.logger.Logt("certificate file uploaded", upres) + + // 证书部署到云资源实例列表 + // REF: https://cloud.tencent.com/document/product/400/91667 + deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() + deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) + deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceType) + deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(d.config.ResourceIds) + deployCertificateInstanceReq.Status = common.Int64Ptr(1) + deployCertificateInstanceResp, err := d.sdkClient.DeployCertificateInstance(deployCertificateInstanceReq) + if err != nil { + return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'") + } else if deployCertificateInstanceResp.Response == nil || deployCertificateInstanceResp.Response.DeployRecordId == nil { + return nil, errors.New("failed to create deploy record") + } + + d.logger.Logt("已部署证书到云资源实例", deployCertificateInstanceResp.Response) + + // 循环获取部署任务详情,等待任务状态变更 + // REF: https://cloud.tencent.com.cn/document/api/400/91658 + for { + if ctx.Err() != nil { + return nil, ctx.Err() + } + + describeHostDeployRecordDetailReq := tcSsl.NewDescribeHostDeployRecordDetailRequest() + describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId)) + describeHostDeployRecordDetailReq.Limit = common.Uint64Ptr(100) + describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) + if err != nil { + return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail'") + } + + if describeHostDeployRecordDetailResp.Response.TotalCount == nil { + return nil, errors.New("部署任务状态异常") + } else { + acc := int64(0) + if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil { + acc += *describeHostDeployRecordDetailResp.Response.SuccessTotalCount + } + if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil { + acc += *describeHostDeployRecordDetailResp.Response.FailedTotalCount + } + + if acc == *describeHostDeployRecordDetailResp.Response.TotalCount { + d.logger.Logt("已获取部署任务详情", describeHostDeployRecordDetailResp) + break + } + } + + d.logger.Logt("部署任务未完成 ...") + time.Sleep(time.Second * 5) + } + + return &deployer.DeployResult{}, nil +} + +func createSdkClient(secretId, secretKey, region string) (*tcSsl.Client, error) { + credential := common.NewCredential(secretId, secretKey) + + client, err := tcSsl.NewClient(credential, region, profile.NewClientProfile()) + if err != nil { + return nil, err + } + + return client, nil +} diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 7d4f3dbd..fe03a6ab 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -43,6 +43,7 @@ import DeployNodeConfigFormTencentCloudCOSConfig from "./DeployNodeConfigFormTen import DeployNodeConfigFormTencentCloudCSSConfig from "./DeployNodeConfigFormTencentCloudCSSConfig.tsx"; import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTencentCloudECDNConfig.tsx"; import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx"; +import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig"; import DeployNodeConfigFormUCloudUCDNConfig from "./DeployNodeConfigFormUCloudUCDNConfig.tsx"; import DeployNodeConfigFormUCloudUS3Config from "./DeployNodeConfigFormUCloudUS3Config.tsx"; import DeployNodeConfigFormVolcEngineCDNConfig from "./DeployNodeConfigFormVolcEngineCDNConfig.tsx"; @@ -125,7 +126,7 @@ const DeployNodeConfigForm = forwardRef; - case DEPLOY_PROVIDERS.ALIYUN_CAS_DEPLOYMENT_JOB: + case DEPLOY_PROVIDERS.ALIYUN_CAS_DEPLOY: return ; case DEPLOY_PROVIDERS.ALIYUN_CLB: return ; @@ -179,6 +180,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOY_PROVIDERS.TENCENTCLOUD_EO: return ; + case DEPLOY_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY: + return ; case DEPLOY_PROVIDERS.UCLOUD_UCDN: return ; case DEPLOY_PROVIDERS.UCLOUD_US3: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx index dd6f6ead..2e7dc127 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx @@ -22,14 +22,14 @@ export type DeployNodeConfigFormTencentCloudCLBConfigProps = { onValuesChange?: (values: DeployNodeConfigFormTencentCloudCLBConfigFieldValues) => void; }; -const RESOURCE_TYPE_SSLDEPLOY = "ssl-deploy" as const; +const RESOURCE_TYPE_VIA_SSLDEPLOY = "ssl-deploy" as const; const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const; const RESOURCE_TYPE_LISTENER = "listener" as const; const RESOURCE_TYPE_RULEDOMAIN = "ruledomain" as const; const initFormModel = (): DeployNodeConfigFormTencentCloudCLBConfigFieldValues => { return { - resourceType: RESOURCE_TYPE_SSLDEPLOY, + resourceType: RESOURCE_TYPE_VIA_SSLDEPLOY, }; }; @@ -44,7 +44,7 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ const formSchema = z.object({ resourceType: z.union( - [z.literal(RESOURCE_TYPE_SSLDEPLOY), z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER), z.literal(RESOURCE_TYPE_RULEDOMAIN)], + [z.literal(RESOURCE_TYPE_VIA_SSLDEPLOY), z.literal(RESOURCE_TYPE_LOADBALANCER), z.literal(RESOURCE_TYPE_LISTENER), z.literal(RESOURCE_TYPE_RULEDOMAIN)], { message: t("workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder") } ), region: z @@ -62,7 +62,7 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ .trim() .nullish() .refine( - (v) => ![RESOURCE_TYPE_SSLDEPLOY, RESOURCE_TYPE_LISTENER, RESOURCE_TYPE_RULEDOMAIN].includes(fieldResourceType) || !!v?.trim(), + (v) => ![RESOURCE_TYPE_VIA_SSLDEPLOY, RESOURCE_TYPE_LISTENER, RESOURCE_TYPE_RULEDOMAIN].includes(fieldResourceType) || !!v?.trim(), t("workflow_node.deploy.form.tencentcloud_clb_listener_id.placeholder") ), domain: z @@ -89,7 +89,7 @@ const DeployNodeConfigFormTencentCloudCLBConfig = ({ > + + + } + > + + + { + formInst.setFieldValue("resourceIds", e.target.value); + }} + /> + + + + + } + onChange={(value) => { + formInst.setFieldValue("resourceIds", value); + }} + /> + + + + + } /> + + + ); +}; + +const ResourceIdsModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + resourceIds: z.array(z.string()).refine((v) => { + return v.every((e) => !e?.trim() || /^[A-Za-z0-9._-]+$/.test(e)); + }, t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid")), + }); + const formRule = createSchemaFieldRule(formSchema); + const { form: formInst, formProps } = useAntdForm({ + name: "workflowNodeDeployConfigFormTencentCloudSSLDeployResourceIdsModalInput", + initialValues: { resourceIds: value?.split(MULTIPLE_INPUT_DELIMITER) }, + onSubmit: (values) => { + onChange?.( + values.resourceIds + .map((e) => e.trim()) + .filter((e) => !!e) + .join(MULTIPLE_INPUT_DELIMITER) + ); + }, + }); + + return ( + + + + + + ); +}); + +export default DeployNodeConfigFormTencentCloudSSLDeployConfig; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 6e0758a1..2edf0531 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -176,7 +176,7 @@ export const applyDNSProvidersMap: Maphttps://console.tencentcloud.com/edgeone", + "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "TIPS: You need to go to the Tencent Cloud console to check the actual deployment results by yourself, because Tencent Cloud deployment tasks are running asynchronously.", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.label": "Tencent Cloud service region", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder": "Please enter Tencent Cloud service region (e.g. ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/36573", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.label": "Tencent Cloud resource IDs", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder": "Please enter Tencent Cloud resource IDs (separated by semicolons)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid": "Please enter a valid Tencent Cloud resource ID", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "For more information, see https://cloud.tencent.com.cn/document/product/400/91667", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "Change Tencent Cloud resource IDs", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "Please enter Tencent Cloud resouce ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "UCloud UCDN domain ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "Please enter UCloud UCDN domain ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "For more information, see https://console.ucloud-global.com/ucdn", diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json index bb0a2b50..06ee5f73 100644 --- a/ui/src/i18n/locales/zh/nls.common.json +++ b/ui/src/i18n/locales/zh/nls.common.json @@ -38,7 +38,7 @@ "common.provider.acmehttpreq": "Http Request (ACME Proxy)", "common.provider.aliyun": "阿里云", "common.provider.aliyun.alb": "阿里云 - 应用型负载均衡 ALB", - "common.provider.aliyun.cas-deploy": "阿里云 - 通过数字证书管理服务 CAS 创建部署任务", + "common.provider.aliyun.cas_deploy": "阿里云 - 通过数字证书管理服务 CAS 创建部署任务", "common.provider.aliyun.cdn": "阿里云 - 内容分发网络 CDN", "common.provider.aliyun.clb": "阿里云 - 传统型负载均衡 CLB", "common.provider.aliyun.dcdn": "阿里云 - 全站加速 DCDN", @@ -89,6 +89,7 @@ "common.provider.tencentcloud.dns": "腾讯云 - 云解析 DNS", "common.provider.tencentcloud.ecdn": "腾讯云 - 全站加速网络 ECDN", "common.provider.tencentcloud.eo": "腾讯云 - 边缘安全加速平台 EdgeOne", + "common.provider.tencentcloud.ssl_deploy": "腾讯云 - 通过 SSL 证书服务创建部署任务", "common.provider.ucloud": "优刻得", "common.provider.ucloud.ucdn": "优刻得 - 内容分发 UCDN", "common.provider.ucloud.us3": "优刻得 - 对象存储 US3", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 6a6732fd..a4436d4e 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -103,7 +103,7 @@ "workflow_node.deploy.form.aliyun_alb_snidomain.label": "阿里云 ALB 扩展域名(可选)", "workflow_node.deploy.form.aliyun_alb_snidomain.placeholder": "请输入阿里云 ALB 扩展域名", "workflow_node.deploy.form.aliyun_alb_snidomain.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/alb

不填写时,将替换监听器的默认证书。", - "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:由于阿里云部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", + "workflow_node.deploy.form.aliyun_cas_deploy.guide": "小贴士:由于阿里云证书部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", "workflow_node.deploy.form.aliyun_cas_deploy_region.label": "阿里云 CAS 服务地域", "workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_deploy_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", @@ -360,6 +360,19 @@ "workflow_node.deploy.form.tencentcloud_eo_domain.label": "腾讯云 EdgeOne 加速域名", "workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "请输入腾讯云 EdgeOne 加速域名", "workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/edgeone", + "workflow_node.deploy.form.tencentcloud_ssl_deploy.guide": "小贴士:由于腾讯云证书部署任务是异步的,此节点若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.label": "腾讯云云产品地域", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.placeholder": "请输入腾讯云云产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com.cn/document/product/400/41659", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.label": "腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder": "请输入腾讯云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.tooltip": "这是什么?请参阅 https://cloud.tencent.com.cn/document/product/400/91667", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.label": "腾讯云云产品资源 ID", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder": "请输入腾讯云云产品资源 ID(多个值请用半角分号隔开)", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid": "请输入正确的腾讯云云产品资源 ID", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip": "这是什么?请参阅 https://cloud.tencent.com.cn/document/product/400/91667

注意与各产品本身的实例 ID 区分。", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title": "修改腾讯云云产品资源 ID", + "workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder": "请输入腾讯云云产品资源 ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "优刻得 UCDN 域名 ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "请输入优刻得 UCDN 域名 ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "这是什么?请参阅 https://console.ucloud.cn/ucdn",