From 1d4b88339e3427d4ab5a7d7a9656a7397fc06985 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sat, 8 Mar 2025 14:30:01 +0800 Subject: [PATCH] feat: add aliyun fc deployer --- go.mod | 4 + go.sum | 10 + internal/deployer/providers.go | 13 +- internal/domain/provider.go | 2 + .../providers/aliyun-alb/aliyun_alb.go | 4 +- .../aliyun-cas-deploy/aliyun_cas_deploy.go | 2 +- .../providers/aliyun-clb/aliyun_clb.go | 2 +- .../providers/aliyun-esa/aliyun_esa.go | 2 +- .../providers/aliyun-esa/aliyun_esa_test.go | 2 +- .../deployer/providers/aliyun-fc/aliyun_fc.go | 191 ++++++++++++++++++ .../providers/aliyun-fc/aliyun_fc_test.go | 80 ++++++++ .../providers/aliyun-live/aliyun_live.go | 2 +- .../providers/aliyun-nlb/aliyun_nlb.go | 2 +- .../providers/aliyun-oss/aliyun_oss.go | 2 +- .../providers/aliyun-vod/aliyun_vod.go | 2 +- .../providers/aliyun-waf/aliyun_waf.go | 2 +- .../providers/aliyun-waf/aliyun_waf_test.go | 2 +- .../providers/aliyun-cas/aliyun_cas.go | 2 +- .../providers/aliyun-slb/aliyun_slb.go | 2 +- .../workflow/node/DeployNodeConfigForm.tsx | 3 + .../DeployNodeConfigFormAliyunFCConfig.tsx | 90 +++++++++ ui/src/domain/provider.ts | 4 + ui/src/i18n/locales/en/nls.provider.json | 2 + .../i18n/locales/en/nls.workflow.nodes.json | 8 + ui/src/i18n/locales/zh/nls.provider.json | 2 + .../i18n/locales/zh/nls.workflow.nodes.json | 8 + 26 files changed, 430 insertions(+), 15 deletions(-) create mode 100644 internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go create mode 100644 internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc_test.go create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx diff --git a/go.mod b/go.mod index d10a26f3..a3d1f2fb 100644 --- a/go.mod +++ b/go.mod @@ -66,6 +66,10 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect + github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 // indirect + github.com/alibabacloud-go/fc-20230330/v4 v4.1.7 // indirect + github.com/alibabacloud-go/fc-open-20210406 v1.1.14 // indirect + github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 // indirect github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect diff --git a/go.sum b/go.sum index d8160a1e..d62acef2 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,9 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82/go.mod h1:nLnM0KdK1CmygvjpDUO6m1TjSsiQtL61juhNsvV/JVI= github.com/alibabacloud-go/alb-20200616/v2 v2.2.8 h1:/6+1AqIiENG3u6RmEYWEQ/YZv3YgdFZkE6Xd9RZM6n0= github.com/alibabacloud-go/alb-20200616/v2 v2.2.8/go.mod h1:jU/K+GVb5b0vjiDpkf6E0dH77tsi1jTLGWm4ouCiRxk= +github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.6/go.mod h1:H0RPHXHP/ICfEQrKzQcCqXI15jcV4zaDPCOAmh3U9O8= +github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 h1:RDatRb9RG39HjkevgzTeiVoDDaamoB+12GHNairp3Ag= +github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7/go.mod h1:H0RPHXHP/ICfEQrKzQcCqXI15jcV4zaDPCOAmh3U9O8= github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA= github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= @@ -126,6 +129,7 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc= github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ= +github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.1/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.5/go.mod h1:kUe8JqFmoVU7lfBauaDD5taFaW7mBI+xVsyHutYtabg= github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE= @@ -146,6 +150,12 @@ github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9 github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= github.com/alibabacloud-go/esa-20240910/v2 v2.22.1 h1:Wmvb90nS6IxJjVe+fUWv7jtXFrJttSh/WkFQ2HIsQmQ= github.com/alibabacloud-go/esa-20240910/v2 v2.22.1/go.mod h1:P1w/+i7dE2xSXVHJznEOVImlLtqqrzUJQQk2AsyBJ6o= +github.com/alibabacloud-go/fc-20230330/v4 v4.1.7 h1:rQvPfzPaouL/WGNgMDMCplA4wDscmVFff7aLCUkjv4g= +github.com/alibabacloud-go/fc-20230330/v4 v4.1.7/go.mod h1:ssEfKO6MskPtq7QaQnyiOHGWLXOZcl7a8YIf8u56DGc= +github.com/alibabacloud-go/fc-open-20210406 v1.1.14 h1:avhpcxvdwexER2S1buxgnYoEq+/rWX3iMCgP3EZZz+E= +github.com/alibabacloud-go/fc-open-20210406 v1.1.14/go.mod h1:M3vmom/tsiVbnIBBZshm8JBXcniX9Ryek3NFX2Q95dg= +github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 h1:A3D8Mp6qf8DfR6Dt5MpS8aDVaWfS4N85T5CvGUvgrjM= +github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12/go.mod h1:F5c0E5UB3k8v6neTtw3FBcJ1YCNFzVoL1JPRHTe33u4= github.com/alibabacloud-go/live-20161101 v1.1.1 h1:rUGfA8RHmCMtQ5M3yMSyRde+yRXWqVecmiXBU3XrGJ8= github.com/alibabacloud-go/live-20161101 v1.1.1/go.mod h1:g84w6qeAodT0/IHdc0tEed2a8PyhQhYl7TAj3jGl4A4= github.com/alibabacloud-go/nlb-20220430/v2 v2.0.3 h1:LtyUVlgBEKyzWgQJurzXM6MXCt84sQr9cE5OKqYymko= diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go index 6c8cc650..35bc1c3f 100644 --- a/internal/deployer/providers.go +++ b/internal/deployer/providers.go @@ -14,6 +14,7 @@ import ( pAliyunCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-clb" pAliyunDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-dcdn" pAliyunESA "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-esa" + pAliyunFC "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-fc" pAliyunLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-live" pAliyunNLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-nlb" pAliyunOSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-oss" @@ -102,7 +103,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { } } - case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCASDeploy, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunESA, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunVOD, domain.DeployProviderTypeAliyunWAF: + case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCASDeploy, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunESA, domain.DeployProviderTypeAliyunFC, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunVOD, domain.DeployProviderTypeAliyunWAF: { access := domain.AccessConfigForAliyun{} if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { @@ -169,6 +170,16 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) { }) return deployer, err + case domain.DeployProviderTypeAliyunFC: + deployer, err := pAliyunFC.NewDeployer(&pAliyunFC.DeployerConfig{ + AccessKeyId: access.AccessKeyId, + AccessKeySecret: access.AccessKeySecret, + Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), + ServiceVersion: maps.GetValueAsString(options.ProviderDeployConfig, "serviceVersion"), + Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), + }) + return deployer, err + case domain.DeployProviderTypeAliyunLive: deployer, err := pAliyunLive.NewDeployer(&pAliyunLive.DeployerConfig{ AccessKeyId: access.AccessKeyId, diff --git a/internal/domain/provider.go b/internal/domain/provider.go index fcdffdd6..78c79d4a 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -116,6 +116,7 @@ const ( DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb") DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn") DeployProviderTypeAliyunESA = DeployProviderType("aliyun-esa") + DeployProviderTypeAliyunFC = DeployProviderType("aliyun-fc") DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live") DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") @@ -151,6 +152,7 @@ const ( DeployProviderTypeTencentCloudCSS = DeployProviderType("tencentcloud-css") DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") + DeployProviderTypeTencentCloudSCF = DeployProviderType("tencentcloud-scf") DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType("tencentcloud-ssldeploy") DeployProviderTypeTencentCloudVOD = DeployProviderType("tencentcloud-vod") DeployProviderTypeTencentCloudWAF = DeployProviderType("tencentcloud-waf") diff --git a/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go b/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go index 39600c7b..4388fbf0 100644 --- a/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go +++ b/internal/pkg/core/deployer/providers/aliyun-alb/aliyun_alb.go @@ -386,7 +386,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL } func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients, error) { - // 接入点一览 https://www.alibabacloud.com/help/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-albEndpoint + // 接入点一览 https://api.aliyun.com/product/Alb var albEndpoint string switch region { case "cn-hangzhou-finance": @@ -405,7 +405,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients return nil, err } - // 接入点一览 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints + // 接入点一览 https://api.aliyun.com/product/cas var casEndpoint string if !strings.HasPrefix(region, "cn-") { casEndpoint = "cas.ap-southeast-1.aliyuncs.com" diff --git a/internal/pkg/core/deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go b/internal/pkg/core/deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go index 1cc36c6f..fa045521 100644 --- a/internal/pkg/core/deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go +++ b/internal/pkg/core/deployer/providers/aliyun-cas-deploy/aliyun_cas_deploy.go @@ -151,7 +151,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州 } - // 接入点一览 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints + // 接入点一览 https://api.aliyun.com/product/cas var endpoint string switch region { case "cn-hangzhou": diff --git a/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go b/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go index 21a1e471..304a7131 100644 --- a/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go +++ b/internal/pkg/core/deployer/providers/aliyun-clb/aliyun_clb.go @@ -274,7 +274,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-endpoint + // 接入点一览 https://api.aliyun.com/product/Slb var endpoint string switch region { case diff --git a/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa.go b/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa.go index 1ccbdae5..5134d115 100644 --- a/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa.go +++ b/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa.go @@ -98,7 +98,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunEsa.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint + // 接入点一览 https://api.aliyun.com/product/ESA config := &aliyunOpen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), diff --git a/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa_test.go b/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa_test.go index c2d81aa3..9a2c4ca0 100644 --- a/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa_test.go +++ b/internal/pkg/core/deployer/providers/aliyun-esa/aliyun_esa_test.go @@ -39,7 +39,7 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_ALIYUNESA_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_ALIYUNESA_ACCESSKEYID="your-access-key-id" \ --CERTIMATE_DEPLOYER_ALIYUNESA_ACCESSKEYSECRET="your-access-key-secret" \ - --CERTIMATE_DEPLOYER_ALIYUNOSS_REGION="cn-hangzhou" \ + --CERTIMATE_DEPLOYER_ALIYUNESA_REGION="cn-hangzhou" \ --CERTIMATE_DEPLOYER_ALIYUNESA_SITEID="your-esa-site-id" */ func TestDeploy(t *testing.T) { diff --git a/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go new file mode 100644 index 00000000..d5567a99 --- /dev/null +++ b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc.go @@ -0,0 +1,191 @@ +package aliyunfc + +import ( + "context" + "fmt" + "time" + + aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" + aliyunFc3 "github.com/alibabacloud-go/fc-20230330/v4/client" + aliyunFc2 "github.com/alibabacloud-go/fc-open-20210406/v2/client" + "github.com/alibabacloud-go/tea/tea" + xerrors "github.com/pkg/errors" + + "github.com/usual2970/certimate/internal/pkg/core/deployer" + "github.com/usual2970/certimate/internal/pkg/core/logger" +) + +type DeployerConfig struct { + // 阿里云 AccessKeyId。 + AccessKeyId string `json:"accessKeyId"` + // 阿里云 AccessKeySecret。 + AccessKeySecret string `json:"accessKeySecret"` + // 阿里云地域。 + Region string `json:"region"` + // 服务版本。 + // 零值时默认为 "3.0"。 + ServiceVersion string `json:"serviceVersion"` + // 自定义域名(不支持泛域名)。 + Domain string `json:"domain"` +} + +type DeployerProvider struct { + config *DeployerConfig + logger logger.Logger + sdkClients *wSdkClients +} + +var _ deployer.Deployer = (*DeployerProvider)(nil) + +type wSdkClients struct { + fc2 *aliyunFc2.Client + fc3 *aliyunFc3.Client +} + +func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { + if config == nil { + panic("config is nil") + } + + clients, err := createSdkClients(config.AccessKeyId, config.AccessKeySecret, config.Region) + if err != nil { + return nil, xerrors.Wrap(err, "failed to create sdk clients") + } + + return &DeployerProvider{ + config: config, + logger: logger.NewNilLogger(), + sdkClients: clients, + }, 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) { + switch d.config.ServiceVersion { + case "", "3.0": + if err := d.deployToFC3(ctx, certPem, privkeyPem); err != nil { + return nil, err + } + + case "2.0": + if err := d.deployToFC2(ctx, certPem, privkeyPem); err != nil { + return nil, err + } + + default: + return nil, xerrors.Errorf("unsupported service version: %s", d.config.ServiceVersion) + } + + return &deployer.DeployResult{}, nil +} + +func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, privkeyPem string) error { + // 获取自定义域名 + // REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-getcustomdomain + getCustomDomainResp, err := d.sdkClients.fc3.GetCustomDomain(tea.String(d.config.Domain)) + if err != nil { + return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'") + } else { + d.logger.Logt("已获取自定义域名", getCustomDomainResp) + } + + // 更新自定义域名 + // REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-updatecustomdomain + updateCustomDomainReq := &aliyunFc3.UpdateCustomDomainRequest{ + Body: &aliyunFc3.UpdateCustomDomainInput{ + CertConfig: &aliyunFc3.CertConfig{ + CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), + 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, + }, + } + updateCustomDomainResp, err := d.sdkClients.fc3.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) + if err != nil { + return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'") + } else { + d.logger.Logt("已更新自定义域名", updateCustomDomainResp) + } + + return nil +} + +func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, privkeyPem string) error { + // 获取自定义域名 + // REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-getcustomdomain + getCustomDomainResp, err := d.sdkClients.fc2.GetCustomDomain(tea.String(d.config.Domain)) + if err != nil { + return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'") + } else { + d.logger.Logt("已获取自定义域名", getCustomDomainResp) + } + + // 更新自定义域名 + // REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-updatecustomdomain + updateCustomDomainReq := &aliyunFc2.UpdateCustomDomainRequest{ + CertConfig: &aliyunFc2.CertConfig{ + CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), + Certificate: tea.String(certPem), + PrivateKey: tea.String(privkeyPem), + }, + Protocol: getCustomDomainResp.Body.Protocol, + RouteConfig: getCustomDomainResp.Body.RouteConfig, + TlsConfig: getCustomDomainResp.Body.TlsConfig, + WafConfig: getCustomDomainResp.Body.WafConfig, + } + updateCustomDomainResp, err := d.sdkClients.fc2.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) + if err != nil { + return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'") + } else { + d.logger.Logt("已更新自定义域名", updateCustomDomainResp) + } + + return nil +} + +func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients, error) { + // 接入点一览 https://api.aliyun.com/product/FC-Open + var fc2Endpoint string + switch region { + case "cn-hangzhou-finance": + fc2Endpoint = fmt.Sprintf("%s.fc.aliyuncs.com", region) + default: + fc2Endpoint = fmt.Sprintf("fc.%s.aliyuncs.com", region) + } + + fc2Config := &aliyunOpen.Config{ + AccessKeyId: tea.String(accessKeyId), + AccessKeySecret: tea.String(accessKeySecret), + Endpoint: tea.String(fc2Endpoint), + } + fc2Client, err := aliyunFc2.NewClient(fc2Config) + if err != nil { + return nil, err + } + + // 接入点一览 https://api.aliyun.com/product/FC-Open + fc3Endpoint := fmt.Sprintf("fcv3.%s.aliyuncs.com", region) + fc3Config := &aliyunOpen.Config{ + AccessKeyId: tea.String(accessKeyId), + AccessKeySecret: tea.String(accessKeySecret), + Endpoint: tea.String(fc3Endpoint), + } + fc3Client, err := aliyunFc3.NewClient(fc3Config) + if err != nil { + return nil, err + } + + return &wSdkClients{ + fc2: fc2Client, + fc3: fc3Client, + }, nil +} diff --git a/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc_test.go b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc_test.go new file mode 100644 index 00000000..a8780285 --- /dev/null +++ b/internal/pkg/core/deployer/providers/aliyun-fc/aliyun_fc_test.go @@ -0,0 +1,80 @@ +package aliyunfc_test + +import ( + "context" + "flag" + "fmt" + "os" + "strings" + "testing" + + provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-fc" +) + +var ( + fInputCertPath string + fInputKeyPath string + fAccessKeyId string + fAccessKeySecret string + fRegion string + fSiteId int64 +) + +func init() { + argsPrefix := "CERTIMATE_DEPLOYER_ALIYUNFC_" + + flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") + flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") + flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "") + flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "") + flag.StringVar(&fRegion, argsPrefix+"REGION", "", "") + flag.Int64Var(&fSiteId, argsPrefix+"SITEID", "", "") +} + +/* +Shell command to run this test: + + go test -v ./aliyun_fc_test.go -args \ + --CERTIMATE_DEPLOYER_ALIYUNFC_INPUTCERTPATH="/path/to/your-input-cert.pem" \ + --CERTIMATE_DEPLOYER_ALIYUNFC_INPUTKEYPATH="/path/to/your-input-key.pem" \ + --CERTIMATE_DEPLOYER_ALIYUNFC_ACCESSKEYID="your-access-key-id" \ + --CERTIMATE_DEPLOYER_ALIYUNFC_ACCESSKEYSECRET="your-access-key-secret" \ + --CERTIMATE_DEPLOYER_ALIYUNFC_REGION="cn-hangzhou" \ + --CERTIMATE_DEPLOYER_ALIYUNFC_SITEID="your-fc-site-id" +*/ +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("ACCESSKEYID: %v", fAccessKeyId), + fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret), + fmt.Sprintf("REGION: %v", fRegion), + fmt.Sprintf("SITEID: %v", fSiteId), + }, "\n")) + + deployer, err := provider.NewDeployer(&provider.DeployerConfig{ + AccessKeyId: fAccessKeyId, + AccessKeySecret: fAccessKeySecret, + Region: fRegion, + SiteId: fSiteId, + }) + 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/aliyun-live/aliyun_live.go b/internal/pkg/core/deployer/providers/aliyun-live/aliyun_live.go index 5735da79..99b06aca 100644 --- a/internal/pkg/core/deployer/providers/aliyun-live/aliyun_live.go +++ b/internal/pkg/core/deployer/providers/aliyun-live/aliyun_live.go @@ -81,7 +81,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunLive.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/live/developer-reference/api-live-2016-11-01-endpoint + // 接入点一览 https://api.aliyun.com/product/live var endpoint string switch region { case diff --git a/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go b/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go index 0f1f1bca..8dc1b2e3 100644 --- a/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go +++ b/internal/pkg/core/deployer/providers/aliyun-nlb/aliyun_nlb.go @@ -211,7 +211,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunNlb.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-endpoint + // 接入点一览 https://api.aliyun.com/product/Nlb var endpoint string switch region { default: diff --git a/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go b/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go index 88adbf0b..3eba5c55 100644 --- a/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go +++ b/internal/pkg/core/deployer/providers/aliyun-oss/aliyun_oss.go @@ -81,7 +81,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*oss.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints + // 接入点一览 https://api.aliyun.com/product/Oss var endpoint string switch region { case "": diff --git a/internal/pkg/core/deployer/providers/aliyun-vod/aliyun_vod.go b/internal/pkg/core/deployer/providers/aliyun-vod/aliyun_vod.go index 740fbb56..77c2ebf0 100644 --- a/internal/pkg/core/deployer/providers/aliyun-vod/aliyun_vod.go +++ b/internal/pkg/core/deployer/providers/aliyun-vod/aliyun_vod.go @@ -77,7 +77,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunVod.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-endpoint + // 接入点一览 https://api.aliyun.com/product/vod endpoint := fmt.Sprintf("vod.%s.aliyuncs.com", region) config := &aliyunOpen.Config{ diff --git a/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf.go b/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf.go index 5747d23e..ccb9adc6 100644 --- a/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf.go +++ b/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf.go @@ -111,7 +111,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunWaf.Client, error) { - // 接入点一览:https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint + // 接入点一览:https://api.aliyun.com/product/waf-openapi config := &aliyunOpen.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), diff --git a/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf_test.go b/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf_test.go index 06a76c63..2668db47 100644 --- a/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf_test.go +++ b/internal/pkg/core/deployer/providers/aliyun-waf/aliyun_waf_test.go @@ -39,7 +39,7 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_ALIYUNWAF_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_ALIYUNWAF_ACCESSKEYID="your-access-key-id" \ --CERTIMATE_DEPLOYER_ALIYUNWAF_ACCESSKEYSECRET="your-access-key-secret" \ - --CERTIMATE_DEPLOYER_ALIYUNOSS_REGION="cn-hangzhou" \ + --CERTIMATE_DEPLOYER_ALIYUNWAF_REGION="cn-hangzhou" \ --CERTIMATE_DEPLOYER_ALIYUNWAF_INSTANCEID="your-waf-instance-id" */ func TestDeploy(t *testing.T) { diff --git a/internal/pkg/core/uploader/providers/aliyun-cas/aliyun_cas.go b/internal/pkg/core/uploader/providers/aliyun-cas/aliyun_cas.go index 202339c4..2b582409 100644 --- a/internal/pkg/core/uploader/providers/aliyun-cas/aliyun_cas.go +++ b/internal/pkg/core/uploader/providers/aliyun-cas/aliyun_cas.go @@ -143,7 +143,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州 } - // 接入点一览 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints + // 接入点一览 https://api.aliyun.com/product/cas var endpoint string switch region { case "cn-hangzhou": diff --git a/internal/pkg/core/uploader/providers/aliyun-slb/aliyun_slb.go b/internal/pkg/core/uploader/providers/aliyun-slb/aliyun_slb.go index c53eced2..d687822a 100644 --- a/internal/pkg/core/uploader/providers/aliyun-slb/aliyun_slb.go +++ b/internal/pkg/core/uploader/providers/aliyun-slb/aliyun_slb.go @@ -119,7 +119,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPem string, privkeyPe } func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Client, error) { - // 接入点一览 https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-endpoint + // 接入点一览 https://api.aliyun.com/product/Slb var endpoint string switch region { case diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index eb240de6..25e7e04b 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -23,6 +23,7 @@ import DeployNodeConfigFormAliyunCDNConfig from "./DeployNodeConfigFormAliyunCDN import DeployNodeConfigFormAliyunCLBConfig from "./DeployNodeConfigFormAliyunCLBConfig"; import DeployNodeConfigFormAliyunDCDNConfig from "./DeployNodeConfigFormAliyunDCDNConfig"; import DeployNodeConfigFormAliyunESAConfig from "./DeployNodeConfigFormAliyunESAConfig"; +import DeployNodeConfigFormAliyunFCConfig from "./DeployNodeConfigFormAliyunFCConfig"; import DeployNodeConfigFormAliyunLiveConfig from "./DeployNodeConfigFormAliyunLiveConfig"; import DeployNodeConfigFormAliyunNLBConfig from "./DeployNodeConfigFormAliyunNLBConfig"; import DeployNodeConfigFormAliyunOSSConfig from "./DeployNodeConfigFormAliyunOSSConfig"; @@ -156,6 +157,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOY_PROVIDERS.ALIYUN_ESA: return ; + case DEPLOY_PROVIDERS.ALIYUN_FC: + return ; case DEPLOY_PROVIDERS.ALIYUN_LIVE: return ; case DEPLOY_PROVIDERS.ALIYUN_NLB: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx new file mode 100644 index 00000000..87212953 --- /dev/null +++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunFCConfig.tsx @@ -0,0 +1,90 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input, Select } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { validDomainName } from "@/utils/validators"; + +type DeployNodeConfigFormAliyunFCConfigFieldValues = Nullish<{ + region: string; + serviceVersion: string; + domain: string; +}>; + +export type DeployNodeConfigFormAliyunFCConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormAliyunFCConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormAliyunFCConfigFieldValues) => void; +}; + +const initFormModel = (): DeployNodeConfigFormAliyunFCConfigFieldValues => { + return { + serviceVersion: "3.0", + }; +}; + +const DeployNodeConfigFormAliyunFCConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormAliyunFCConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + serviceVersion: z.union([z.literal("2.0"), z.literal("3.0")], { + message: t("workflow_node.deploy.form.aliyun_fc_service_version.placeholder"), + }), + region: z + .string({ message: t("workflow_node.deploy.form.aliyun_fc_region.placeholder") }) + .nonempty(t("workflow_node.deploy.form.aliyun_fc_region.placeholder")) + .trim(), + domain: z + .string({ message: t("workflow_node.deploy.form.aliyun_fc_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 DeployNodeConfigFormAliyunFCConfig; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 70e0ba7a..18fe0699 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -221,6 +221,7 @@ export const DEPLOY_PROVIDERS = Object.freeze({ ALIYUN_CLB: `${ACCESS_PROVIDERS.ALIYUN}-clb`, ALIYUN_DCDN: `${ACCESS_PROVIDERS.ALIYUN}-dcdn`, ALIYUN_ESA: `${ACCESS_PROVIDERS.ALIYUN}-esa`, + ALIYUN_FC: `${ACCESS_PROVIDERS.ALIYUN}-fc`, ALIYUN_LIVE: `${ACCESS_PROVIDERS.ALIYUN}-live`, ALIYUN_NLB: `${ACCESS_PROVIDERS.ALIYUN}-nlb`, ALIYUN_OSS: `${ACCESS_PROVIDERS.ALIYUN}-oss`, @@ -256,6 +257,7 @@ export const DEPLOY_PROVIDERS = Object.freeze({ TENCENTCLOUD_CSS: `${ACCESS_PROVIDERS.TENCENTCLOUD}-css`, TENCENTCLOUD_ECDN: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ecdn`, TENCENTCLOUD_EO: `${ACCESS_PROVIDERS.TENCENTCLOUD}-eo`, + TENCENTCLOUD_SCF: `${ACCESS_PROVIDERS.TENCENTCLOUD}-scf`, TENCENTCLOUD_SSL_DEPLOY: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ssldeploy`, TENCENTCLOUD_VOD: `${ACCESS_PROVIDERS.TENCENTCLOUD}-vod`, TENCENTCLOUD_WAF: `${ACCESS_PROVIDERS.TENCENTCLOUD}-waf`, @@ -313,6 +315,7 @@ export const deployProvidersMap: Maphttps://esa.console.aliyun.com/siteManage/list", + "workflow_node.deploy.form.aliyun_fc_region.label": "Alibaba Cloud FC region", + "workflow_node.deploy.form.aliyun_fc_region.placeholder": "Please enter Alibaba Cloud FC region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_fc_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/functioncompute/fc-3-0/product-overview/supported-regions", + "workflow_node.deploy.form.aliyun_fc_service_version.label": "Alibaba Cloud FC version", + "workflow_node.deploy.form.aliyun_fc_service_version.placeholder": "Please select Alibaba Cloud FC version", + "workflow_node.deploy.form.aliyun_fc_domain.label": "Alibaba Cloud FC domain", + "workflow_node.deploy.form.aliyun_fc_domain.placeholder": "Please enter Alibaba Cloud FC domain name", + "workflow_node.deploy.form.aliyun_fc_domain.tooltip": "For more information, see https://fcnext.console.aliyun.com", "workflow_node.deploy.form.aliyun_live_region.label": "Alibaba Cloud Live region", "workflow_node.deploy.form.aliyun_live_region.placeholder": "Please enter Alibaba Cloud Live region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_live_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/live/product-overview/supported-regions", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index 8ff1bdbd..f4eb79f9 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -10,6 +10,7 @@ "provider.aliyun.clb": "阿里云 - 传统型负载均衡 CLB", "provider.aliyun.dcdn": "阿里云 - 全站加速 DCDN", "provider.aliyun.esa": "阿里云 - 边缘安全加速 ESA", + "provider.aliyun.fc": "阿里云 - 函数计算 FC", "provider.aliyun.dns": "阿里云 - 云解析 DNS", "provider.aliyun.live": "阿里云 - 视频直播 Live", "provider.aliyun.nlb": "阿里云 - 网络型负载均衡 NLB", @@ -85,6 +86,7 @@ "provider.tencentcloud.dns": "腾讯云 - 云解析 DNS", "provider.tencentcloud.ecdn": "腾讯云 - 全站加速网络 ECDN", "provider.tencentcloud.eo": "腾讯云 - 边缘安全加速平台 EdgeOne", + "provider.tencentcloud.scf": "腾讯云 - 云函数 SCF", "provider.tencentcloud.ssl_deploy": "腾讯云 - 通过 SSL 证书服务创建部署任务", "provider.tencentcloud.vod": "腾讯云 - 云点播 VOD", "provider.tencentcloud.waf": "腾讯云 - Web 应用防火墙 WAF", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index f2d8c130..69ca762d 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -154,6 +154,14 @@ "workflow_node.deploy.form.aliyun_esa_site_id.label": "阿里云 ESA 站点 ID", "workflow_node.deploy.form.aliyun_esa_site_id.placeholder": "请输入阿里云 ESA 站点 ID", "workflow_node.deploy.form.aliyun_esa_site_id.tooltip": "这是什么?请参阅 https://esa.console.aliyun.com/siteManage/list", + "workflow_node.deploy.form.aliyun_fc_region.label": "阿里云 FC 服务地域", + "workflow_node.deploy.form.aliyun_fc_region.placeholder": "请输入阿里云 FC 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_fc_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/functioncompute/fc-3-0/product-overview/supported-regions", + "workflow_node.deploy.form.aliyun_fc_service_version.label": "阿里云 FC 服务版本", + "workflow_node.deploy.form.aliyun_fc_service_version.placeholder": "请选择阿里云 FC 服务版本", + "workflow_node.deploy.form.aliyun_fc_domain.label": "阿里云 FC 自定义域名", + "workflow_node.deploy.form.aliyun_fc_domain.placeholder": "请输入阿里云 FC 自定义域名", + "workflow_node.deploy.form.aliyun_fc_domain.tooltip": "这是什么?请参阅 see https://fcnext.console.aliyun.com/", "workflow_node.deploy.form.aliyun_live_region.label": "阿里云视频直播服务地域", "workflow_node.deploy.form.aliyun_live_region.placeholder": "请输入阿里云视频直播服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_live_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/live/product-overview/supported-regions",