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",