feat: add aliyun fc deployer

This commit is contained in:
Fu Diwei
2025-03-08 14:30:01 +08:00
parent 1e2e88e299
commit 1d4b88339e
26 changed files with 430 additions and 15 deletions

View File

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

View File

@@ -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")

View File

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

View File

@@ -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":

View File

@@ -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

View File

@@ -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),

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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)
})
}

View File

@@ -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

View File

@@ -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:

View File

@@ -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 "":

View File

@@ -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{

View File

@@ -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),

View File

@@ -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) {

View File

@@ -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":

View File

@@ -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