From c7ad61e3195c6fb711d8283122d0690965d099a8 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sat, 8 Mar 2025 14:58:40 +0800 Subject: [PATCH] feat: add tencentcloud scf deployer --- go.mod | 1 + go.sum | 2 + internal/deployer/providers.go | 12 +- .../deployer/providers/aliyun-fc/aliyun_fc.go | 13 +- .../deployer/providers/safeline/safeline.go | 2 +- .../tencentcloud-cos/tencentcloud_cos.go | 2 +- .../tencentcloud-scf/tencentcloud_scf.go | 114 ++++++++++++++++++ .../tencentcloud-scf/tencentcloud_scf_test.go | 80 ++++++++++++ .../tencentcloud-vod/tencentcloud_vod.go | 2 +- .../tencentcloud-vod/tencentcloud_vod_test.go | 5 - .../tencentcloud-waf/tencentcloud_waf.go | 2 +- .../provider/DeployProviderPicker.tsx | 1 + .../workflow/node/DeployNodeConfigForm.tsx | 3 + ...loyNodeConfigFormTencentCloudSCFConfig.tsx | 79 ++++++++++++ ui/src/domain/provider.ts | 5 +- ui/src/i18n/locales/en/nls.provider.json | 1 + .../i18n/locales/en/nls.workflow.nodes.json | 6 + ui/src/i18n/locales/zh/nls.provider.json | 3 +- .../i18n/locales/zh/nls.workflow.nodes.json | 6 + 19 files changed, 317 insertions(+), 22 deletions(-) create mode 100644 internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf.go create mode 100644 internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf_test.go create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx diff --git a/go.mod b/go.mod index a3d1f2fb..123c69ae 100644 --- a/go.mod +++ b/go.mod @@ -109,6 +109,7 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/technoweenie/multipartstreamer v1.0.1 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1115 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect diff --git a/go.sum b/go.sum index d62acef2..04555b1e 100644 --- a/go.sum +++ b/go.sum @@ -857,6 +857,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084 h1:kwc github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084/go.mod h1:qE67ApiBzeRvzeDsV+GxyIDbVIDemsKpHXllQATz/Vw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1115 h1:qy05kto0yI5AG6u0+BHwfUK9jJUJ92081ee+wvSkpk8= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1115/go.mod h1:BSeUvwz3WO7BbTan1OKC0+NDeiULVZVovrd93qCtWJM= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1115 h1:Qi7VWmJ0AQxEMlwKpbWfnsLA5QdNxekdcLJTBVdO85U= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1115/go.mod h1:P16nIMvmpSY+arTc2m2HyJmrYQP6CFnr48glz0+abyw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1115 h1:xAMIp4en0Wm4FAS4zo5ZXeYT4FMXms68Fc2COP4J/TM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1115/go.mod h1:3zCzHke2XQMBm6T2PIdnfTCXGxykV4uTTdRStpUdS0g= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1115 h1:3Xz/q/m9gl++KtPkrgaXvFCXjM1y9QmAbpG8qfLUm9M= diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 35bc1c3f..1efd9c96 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -50,6 +50,7 @@ import ( pTencentCloudCSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-css" pTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn" pTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo" + pTencentCloudSCF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-scf" pTencentCloudSSLDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy" pTencentCloudVOD "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-vod" pTencentCloudWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-waf" @@ -634,7 +635,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { return deployer, err } - case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO, domain.DeployProviderTypeTencentCloudSSLDeploy, domain.DeployProviderTypeTencentCloudVOD, domain.DeployProviderTypeTencentCloudWAF: + case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO, domain.DeployProviderTypeTencentCloudSCF, domain.DeployProviderTypeTencentCloudSSLDeploy, domain.DeployProviderTypeTencentCloudVOD, domain.DeployProviderTypeTencentCloudWAF: { access := domain.AccessConfigForTencentCloud{} if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { @@ -697,6 +698,15 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { }) return deployer, err + case domain.DeployProviderTypeTencentCloudSCF: + deployer, err := pTencentCloudSCF.NewDeployer(&pTencentCloudSCF.DeployerConfig{ + SecretId: access.SecretId, + SecretKey: access.SecretKey, + Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), + Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), + }) + return deployer, err + case domain.DeployProviderTypeTencentCloudSSLDeploy: deployer, err := pTencentCloudSSLDeploy.NewDeployer(&pTencentCloudSSLDeploy.DeployerConfig{ SecretId: access.SecretId, diff --git a/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go index d5567a99..e70931f8 100644 --- a/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go +++ b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go @@ -102,11 +102,8 @@ func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, priv Certificate: tea.String(certPem), PrivateKey: tea.String(privkeyPem), }, - Protocol: getCustomDomainResp.Body.Protocol, - AuthConfig: getCustomDomainResp.Body.AuthConfig, - RouteConfig: getCustomDomainResp.Body.RouteConfig, - TlsConfig: getCustomDomainResp.Body.TlsConfig, - WafConfig: getCustomDomainResp.Body.WafConfig, + Protocol: getCustomDomainResp.Body.Protocol, + TlsConfig: getCustomDomainResp.Body.TlsConfig, }, } updateCustomDomainResp, err := d.sdkClients.fc3.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) @@ -137,10 +134,8 @@ func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, priv Certificate: tea.String(certPem), PrivateKey: tea.String(privkeyPem), }, - Protocol: getCustomDomainResp.Body.Protocol, - RouteConfig: getCustomDomainResp.Body.RouteConfig, - TlsConfig: getCustomDomainResp.Body.TlsConfig, - WafConfig: getCustomDomainResp.Body.WafConfig, + Protocol: getCustomDomainResp.Body.Protocol, + TlsConfig: getCustomDomainResp.Body.TlsConfig, } updateCustomDomainResp, err := d.sdkClients.fc2.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) if err != nil { diff --git a/internal/pkg/core/deployer/providers/safeline/safeline.go b/internal/pkg/core/deployer/providers/safeline/safeline.go index 4766c364..d0186100 100644 --- a/internal/pkg/core/deployer/providers/safeline/safeline.go +++ b/internal/pkg/core/deployer/providers/safeline/safeline.go @@ -43,7 +43,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { client, err := createSdkClient(config.ApiUrl, config.ApiToken, config.AllowInsecureConnections) if err != nil { - return nil, xerrors.Wrap(err, "failed to create sdk clients") + return nil, xerrors.Wrap(err, "failed to create sdk client") } return &DeployerProvider{ diff --git a/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go b/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go index d3b3f881..becceab6 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-cos/tencentcloud_cos.go @@ -45,7 +45,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { client, err := createSdkClient(config.SecretId, config.SecretKey, config.Region) if err != nil { - return nil, xerrors.Wrap(err, "failed to create sdk clients") + return nil, xerrors.Wrap(err, "failed to create sdk client") } uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ diff --git a/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf.go b/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf.go new file mode 100644 index 00000000..3a3aeb82 --- /dev/null +++ b/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf.go @@ -0,0 +1,114 @@ +package tencentcloudscf + +import ( + "context" + + xerrors "github.com/pkg/errors" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tcScf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf/v20180416" + + "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" + "github.com/usual2970/certimate/internal/pkg/core/uploader" + uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl" +) + +type DeployerConfig struct { + // 腾讯云 SecretId。 + SecretId string `json:"secretId"` + // 腾讯云 SecretKey。 + SecretKey string `json:"secretKey"` + // 腾讯云地域。 + Region string `json:"region"` + // 自定义域名(不支持泛域名)。 + Domain string `json:"domain"` +} + +type DeployerProvider struct { + config *DeployerConfig + logger logger.Logger + sdkClient *tcScf.Client + sslUploader uploader.Uploader +} + +var _ deployer.Deployer = (*DeployerProvider)(nil) + +func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { + if config == nil { + panic("config 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 := uploadersp.NewUploader(&uploadersp.UploaderConfig{ + SecretId: config.SecretId, + SecretKey: config.SecretKey, + }) + if err != nil { + return nil, xerrors.Wrap(err, "failed to create ssl uploader") + } + + return &DeployerProvider{ + config: config, + logger: logger.NewNilLogger(), + sdkClient: client, + sslUploader: uploader, + }, nil +} + +func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider { + d.logger = logger + return d +} + +func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { + // 查看云函数自定义域名详情 + // REF: https://cloud.tencent.com/document/product/583/111924 + getCustomDomainReq := tcScf.NewGetCustomDomainRequest() + getCustomDomainReq.Domain = common.StringPtr(d.config.Domain) + getCustomDomainResp, err := d.sdkClient.GetCustomDomain(getCustomDomainReq) + if err != nil { + return nil, xerrors.Wrap(err, "failed to execute sdk request 'scf.GetCustomDomain'") + } else { + d.logger.Logt("已查看云函数自定义域名详情", getCustomDomainResp.Response) + } + + // 上传证书到 SSL + upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) + if err != nil { + return nil, xerrors.Wrap(err, "failed to upload certificate file") + } else { + d.logger.Logt("certificate file uploaded", upres) + } + + // 更新云函数自定义域名 + // REF: https://cloud.tencent.com/document/product/583/111922 + updateCustomDomainReq := tcScf.NewUpdateCustomDomainRequest() + updateCustomDomainReq.Domain = common.StringPtr(d.config.Domain) + updateCustomDomainReq.CertConfig = &tcScf.CertConf{ + CertificateId: common.StringPtr(upres.CertId), + } + updateCustomDomainReq.Protocol = getCustomDomainResp.Response.Protocol + updateCustomDomainResp, err := d.sdkClient.UpdateCustomDomain(updateCustomDomainReq) + if err != nil { + return nil, xerrors.Wrap(err, "failed to execute sdk request 'scf.UpdateCustomDomain'") + } else { + d.logger.Logt("已设置点播域名 HTTPS 证书", updateCustomDomainResp.Response) + } + + return &deployer.DeployResult{}, nil +} + +func createSdkClient(secretId, secretKey, region string) (*tcScf.Client, error) { + credential := common.NewCredential(secretId, secretKey) + client, err := tcScf.NewClient(credential, region, profile.NewClientProfile()) + if err != nil { + return nil, err + } + + return client, nil +} diff --git a/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf_test.go b/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf_test.go new file mode 100644 index 00000000..84a1ad79 --- /dev/null +++ b/internal/pkg/core/deployer/providers/tencentcloud-scf/tencentcloud_scf_test.go @@ -0,0 +1,80 @@ +package tencentcloudscf_test + +import ( + "context" + "flag" + "fmt" + "os" + "strings" + "testing" + + provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-scf" +) + +var ( + fInputCertPath string + fInputKeyPath string + fSecretId string + fSecretKey string + fRegion string + fDomain string +) + +func init() { + argsPrefix := "CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_" + + flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") + flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") + flag.StringVar(&fSecretId, argsPrefix+"SECRETID", "", "") + flag.StringVar(&fSecretKey, argsPrefix+"SECRETKEY", "", "") + flag.StringVar(&fRegion, argsPrefix+"REGION", "", "") + flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "") +} + +/* +Shell command to run this test: + + go test -v ./tencentcloud_scf_test.go -args \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_INPUTCERTPATH="/path/to/your-input-cert.pem" \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_INPUTKEYPATH="/path/to/your-input-key.pem" \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_SECRETID="your-secret-id" \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_SECRETKEY="your-secret-key" \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_REGION="ap-guangzhou" \ + --CERTIMATE_DEPLOYER_TENCENTCLOUDSCF_DOMAIN="example.com" +*/ +func TestDeploy(t *testing.T) { + flag.Parse() + + t.Run("Deploy", func(t *testing.T) { + t.Log(strings.Join([]string{ + "args:", + fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath), + fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), + fmt.Sprintf("SECRETID: %v", fSecretId), + fmt.Sprintf("SECRETKEY: %v", fSecretKey), + fmt.Sprintf("REGION: %v", fRegion), + fmt.Sprintf("DOMAIN: %v", fDomain), + }, "\n")) + + deployer, err := provider.NewDeployer(&provider.DeployerConfig{ + SecretId: fSecretId, + SecretKey: fSecretKey, + Region: fRegion, + Domain: fDomain, + }) + if err != nil { + t.Errorf("err: %+v", err) + return + } + + fInputCertData, _ := os.ReadFile(fInputCertPath) + fInputKeyData, _ := os.ReadFile(fInputKeyPath) + res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData)) + if err != nil { + t.Errorf("err: %+v", err) + return + } + + t.Logf("ok: %v", res) + }) +} diff --git a/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod.go b/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod.go index fbce8d6f..77177469 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod.go @@ -41,7 +41,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { client, err := createSdkClient(config.SecretId, config.SecretKey) if err != nil { - return nil, xerrors.Wrap(err, "failed to create sdk clients") + return nil, xerrors.Wrap(err, "failed to create sdk client") } uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ diff --git a/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod_test.go b/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod_test.go index 60871a31..ffd085cd 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod_test.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-vod/tencentcloud_vod_test.go @@ -16,7 +16,6 @@ var ( fInputKeyPath string fSecretId string fSecretKey string - fRegion string fDomain string fSubAppId int64 fInstanceId string @@ -29,7 +28,6 @@ func init() { flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fSecretId, argsPrefix+"SECRETID", "", "") flag.StringVar(&fSecretKey, argsPrefix+"SECRETKEY", "", "") - flag.StringVar(&fRegion, argsPrefix+"REGION", "", "") flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "") flag.Int64Var(&fSubAppId, argsPrefix+"SUBAPPID", 0, "") flag.StringVar(&fInstanceId, argsPrefix+"INSTANCEID", "", "") @@ -43,7 +41,6 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_SECRETID="your-secret-id" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_SECRETKEY="your-secret-key" \ - --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_REGION="ap-guangzhou" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_SUBAPPID="your-app-id" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDVOD_DOMAIN="example.com" */ @@ -57,7 +54,6 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("SECRETID: %v", fSecretId), fmt.Sprintf("SECRETKEY: %v", fSecretKey), - fmt.Sprintf("REGION: %v", fRegion), fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("INSTANCEID: %v", fInstanceId), }, "\n")) @@ -65,7 +61,6 @@ func TestDeploy(t *testing.T) { deployer, err := provider.NewDeployer(&provider.DeployerConfig{ SecretId: fSecretId, SecretKey: fSecretKey, - Region: fRegion, SubAppId: fSubAppId, Domain: fDomain, }) diff --git a/internal/pkg/core/deployer/providers/tencentcloud-waf/tencentcloud_waf.go b/internal/pkg/core/deployer/providers/tencentcloud-waf/tencentcloud_waf.go index 7919516c..c84067ce 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-waf/tencentcloud_waf.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-waf/tencentcloud_waf.go @@ -46,7 +46,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { client, err := createSdkClient(config.SecretId, config.SecretKey, config.Region) if err != nil { - return nil, xerrors.Wrap(err, "failed to create sdk clients") + return nil, xerrors.Wrap(err, "failed to create sdk client") } uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ diff --git a/ui/src/components/provider/DeployProviderPicker.tsx b/ui/src/components/provider/DeployProviderPicker.tsx index 57ba39a6..cc34ef16 100644 --- a/ui/src/components/provider/DeployProviderPicker.tsx +++ b/ui/src/components/provider/DeployProviderPicker.tsx @@ -64,6 +64,7 @@ const DeployProviderPicker = ({ className, style, autoFocus, placeholder, onSele DEPLOY_CATEGORIES.LOADBALANCE, DEPLOY_CATEGORIES.FIREWALL, DEPLOY_CATEGORIES.AV, + DEPLOY_CATEGORIES.SERVERLESS, DEPLOY_CATEGORIES.WEBSITE, DEPLOY_CATEGORIES.OTHER, ].map((key) => ({ diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 25e7e04b..4f05c1c8 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -58,6 +58,7 @@ import DeployNodeConfigFormTencentCloudCOSConfig from "./DeployNodeConfigFormTen import DeployNodeConfigFormTencentCloudCSSConfig from "./DeployNodeConfigFormTencentCloudCSSConfig.tsx"; import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTencentCloudECDNConfig.tsx"; import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx"; +import DeployNodeConfigFormTencentCloudSCFConfig from "./DeployNodeConfigFormTencentCloudSCFConfig"; import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig"; import DeployNodeConfigFormTencentCloudVODConfig from "./DeployNodeConfigFormTencentCloudVODConfig"; import DeployNodeConfigFormTencentCloudWAFConfig from "./DeployNodeConfigFormTencentCloudWAFConfig"; @@ -227,6 +228,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOY_PROVIDERS.TENCENTCLOUD_EO: return ; + case DEPLOY_PROVIDERS.TENCENTCLOUD_SCF: + return ; case DEPLOY_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY: return ; case DEPLOY_PROVIDERS.TENCENTCLOUD_VOD: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx new file mode 100644 index 00000000..6758ddbd --- /dev/null +++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudSCFConfig.tsx @@ -0,0 +1,79 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { validDomainName } from "@/utils/validators"; + +type DeployNodeConfigFormTencentCloudSCFConfigFieldValues = Nullish<{ + region: string; + domain: string; +}>; + +export type DeployNodeConfigFormTencentCloudSCFConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormTencentCloudSCFConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormTencentCloudSCFConfigFieldValues) => void; +}; + +const initFormModel = (): DeployNodeConfigFormTencentCloudSCFConfigFieldValues => { + return {}; +}; + +const DeployNodeConfigFormTencentCloudSCFConfig = ({ + form: formInst, + formName, + disabled, + initialValues, + onValuesChange, +}: DeployNodeConfigFormTencentCloudSCFConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + region: z + .string({ message: t("workflow_node.deploy.form.tencentcloud_scf_region.placeholder") }) + .nonempty(t("workflow_node.deploy.form.tencentcloud_scf_region.placeholder")) + .trim(), + domain: z + .string({ message: t("workflow_node.deploy.form.tencentcloud_scf_domain.placeholder") }) + .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + + + } + > + + +
+ ); +}; + +export default DeployNodeConfigFormTencentCloudSCFConfig; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 18fe0699..f3d6deb3 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -281,6 +281,7 @@ export const DEPLOY_CATEGORIES = Object.freeze({ LOADBALANCE: "loadbalance", FIREWALL: "firewall", AV: "av", + SERVERLESS: "serverless", WEBSITE: "website", OTHER: "other", } as const); @@ -315,7 +316,7 @@ export const deployProvidersMap: Maphttps://console.tencentcloud.com/edgeone", + "workflow_node.deploy.form.tencentcloud_scf_region.label": "Tencent Cloud SCF region", + "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "Please enter Tencent Cloud SCF region (e.g. ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/583/17299", + "workflow_node.deploy.form.tencentcloud_scf_domain.label": "Tencent Cloud SCF domain", + "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "Please enter Tencent Cloud SCF domain name", + "workflow_node.deploy.form.tencentcloud_scf_domain.tooltip": "For more information, see https://console.tencentcloud.com/scf", "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)", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index f4eb79f9..e8580e41 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -110,6 +110,7 @@ "provider.category.loadbalance": "负载均衡", "provider.category.firewall": "防火墙", "provider.category.av": "音视频", - "provider.category.website": "网站", + "provider.category.serverless": "Serverless", + "provider.category.website": "网站托管", "provider.category.other": "其他" } diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 69ca762d..2ba9e329 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -453,6 +453,12 @@ "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_scf_region.label": "腾讯云 SCF 产品地域", + "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "输入腾讯云 SCF 产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17299", + "workflow_node.deploy.form.tencentcloud_scf_domain.label": "腾讯云 SCF 自定义域名", + "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "输入腾讯云 SCF 自定义域名", + "workflow_node.deploy.form.tencentcloud_scf_domain.tooltip": "这是什么?请参阅 https://console.tencentcloud.com/scf", "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)",