From c846945905c20daf7ae32da6cfce905cb7323b1a Mon Sep 17 00:00:00 2001
From: Fu Diwei <fudiwei@sina.com>
Date: Fri, 20 Dec 2024 22:58:47 +0800
Subject: [PATCH] refactor(deployer): reimplement deploy service
---
internal/deployer/aliyun_alb.go | 281 --------------------
internal/deployer/aliyun_cdn.go | 88 -------
internal/deployer/aliyun_clb.go | 286 --------------------
internal/deployer/aliyun_dcdn.go | 95 -------
internal/deployer/aliyun_nlb.go | 245 -----------------
internal/deployer/aliyun_oss.go | 86 ------
internal/deployer/baiducloud_cdn.go | 80 ------
internal/deployer/byteplus_cdn.go | 116 --------
internal/deployer/deployer.go | 94 +++----
internal/deployer/dogecloud_cdn.go | 88 -------
internal/deployer/factory.go | 16 +-
internal/deployer/huaweicloud_cdn.go | 143 ----------
internal/deployer/huaweicloud_elb.go | 378 ---------------------------
internal/deployer/k8s_secret.go | 136 ----------
internal/deployer/local.go | 163 ------------
internal/deployer/qiniu_cdn.go | 113 --------
internal/deployer/ssh.go | 209 ---------------
internal/deployer/ssh_test.go | 12 -
internal/deployer/tencent_cdn.go | 194 --------------
internal/deployer/tencent_clb.go | 328 -----------------------
internal/deployer/tencent_cos.go | 107 --------
internal/deployer/tencent_ecdn.go | 154 -----------
internal/deployer/tencent_teo.go | 119 ---------
internal/deployer/volcengine_cdn.go | 116 --------
internal/deployer/volcengine_live.go | 148 -----------
internal/deployer/webhook.go | 66 -----
26 files changed, 48 insertions(+), 3813 deletions(-)
delete mode 100644 internal/deployer/aliyun_alb.go
delete mode 100644 internal/deployer/aliyun_cdn.go
delete mode 100644 internal/deployer/aliyun_clb.go
delete mode 100644 internal/deployer/aliyun_dcdn.go
delete mode 100644 internal/deployer/aliyun_nlb.go
delete mode 100644 internal/deployer/aliyun_oss.go
delete mode 100644 internal/deployer/baiducloud_cdn.go
delete mode 100644 internal/deployer/byteplus_cdn.go
delete mode 100644 internal/deployer/dogecloud_cdn.go
delete mode 100644 internal/deployer/huaweicloud_cdn.go
delete mode 100644 internal/deployer/huaweicloud_elb.go
delete mode 100644 internal/deployer/k8s_secret.go
delete mode 100644 internal/deployer/local.go
delete mode 100644 internal/deployer/qiniu_cdn.go
delete mode 100644 internal/deployer/ssh.go
delete mode 100644 internal/deployer/ssh_test.go
delete mode 100644 internal/deployer/tencent_cdn.go
delete mode 100644 internal/deployer/tencent_clb.go
delete mode 100644 internal/deployer/tencent_cos.go
delete mode 100644 internal/deployer/tencent_ecdn.go
delete mode 100644 internal/deployer/tencent_teo.go
delete mode 100644 internal/deployer/volcengine_cdn.go
delete mode 100644 internal/deployer/volcengine_live.go
delete mode 100644 internal/deployer/webhook.go
diff --git a/internal/deployer/aliyun_alb.go b/internal/deployer/aliyun_alb.go
deleted file mode 100644
index 2e05320e..00000000
--- a/internal/deployer/aliyun_alb.go
+++ /dev/null
@@ -1,281 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
-
- aliyunAlb "github.com/alibabacloud-go/alb-20200616/v2/client"
- aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- "github.com/alibabacloud-go/tea/tea"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderAliyunCas "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
-)
-
-type AliyunALBDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *aliyunAlb.Client
- sslUploader uploader.Uploader
-}
-
-func NewAliyunALBDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunALBDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- aliCasRegion := option.DeployConfig.GetConfigAsString("region")
- if aliCasRegion != "" {
- // 阿里云 CAS 服务接入点是独立于 ALB 服务的
- // 国内版接入点:华东一杭州
- // 国际版接入点:亚太东南一新加坡
- if !strings.HasPrefix(aliCasRegion, "cn-") {
- aliCasRegion = "ap-southeast-1"
- } else {
- aliCasRegion = "cn-hangzhou"
- }
- }
- uploader, err := uploaderAliyunCas.New(&uploaderAliyunCas.AliyunCASUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- AccessKeySecret: access.AccessKeySecret,
- Region: aliCasRegion,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &AliyunALBDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *AliyunALBDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunALBDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunALBDeployer) Deploy(ctx context.Context) error {
- switch d.option.DeployConfig.GetConfigAsString("resourceType") {
- case "loadbalancer":
- if err := d.deployToLoadbalancer(ctx); err != nil {
- return err
- }
- case "listener":
- if err := d.deployToListener(ctx); err != nil {
- return err
- }
- default:
- return errors.New("unsupported resource type")
- }
-
- return nil
-}
-
-func (d *AliyunALBDeployer) createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunAlb.Client, error) {
- if region == "" {
- region = "cn-hangzhou" // ALB 服务默认区域:华东一杭州
- }
-
- aConfig := &aliyunOpen.Config{
- AccessKeyId: tea.String(accessKeyId),
- AccessKeySecret: tea.String(accessKeySecret),
- }
-
- var endpoint string
- switch region {
- case "cn-hangzhou-finance":
- endpoint = "alb.cn-hangzhou.aliyuncs.com"
- default:
- endpoint = fmt.Sprintf("alb.%s.aliyuncs.com", region)
- }
- aConfig.Endpoint = tea.String(endpoint)
-
- client, err := aliyunAlb.NewClient(aConfig)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
-
-func (d *AliyunALBDeployer) deployToLoadbalancer(ctx context.Context) error {
- aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- if aliLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- aliListenerIds := make([]string, 0)
-
- // 查询负载均衡实例的详细信息
- // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getloadbalancerattribute
- getLoadBalancerAttributeReq := &aliyunAlb.GetLoadBalancerAttributeRequest{
- LoadBalancerId: tea.String(aliLoadbalancerId),
- }
- getLoadBalancerAttributeResp, err := d.sdkClient.GetLoadBalancerAttribute(getLoadBalancerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetLoadBalancerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 ALB 负载均衡实例", getLoadBalancerAttributeResp))
-
- // 查询 HTTPS 监听列表
- // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlisteners
- listListenersPage := 1
- listListenersLimit := int32(100)
- var listListenersToken *string = nil
- for {
- listListenersReq := &aliyunAlb.ListListenersRequest{
- MaxResults: tea.Int32(listListenersLimit),
- NextToken: listListenersToken,
- LoadBalancerIds: []*string{tea.String(aliLoadbalancerId)},
- ListenerProtocol: tea.String("HTTPS"),
- }
- listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'")
- }
-
- if listListenersResp.Body.Listeners != nil {
- for _, listener := range listListenersResp.Body.Listeners {
- aliListenerIds = append(aliListenerIds, *listener.ListenerId)
- }
- }
-
- if listListenersResp.Body.NextToken == nil {
- break
- } else {
- listListenersToken = listListenersResp.Body.NextToken
- listListenersPage += 1
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到 ALB 负载均衡实例下的全部 HTTPS 监听", aliListenerIds))
-
- // 查询 QUIC 监听列表
- // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlisteners
- listListenersPage = 1
- listListenersToken = nil
- for {
- listListenersReq := &aliyunAlb.ListListenersRequest{
- MaxResults: tea.Int32(listListenersLimit),
- NextToken: listListenersToken,
- LoadBalancerIds: []*string{tea.String(aliLoadbalancerId)},
- ListenerProtocol: tea.String("QUIC"),
- }
- listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'")
- }
-
- if listListenersResp.Body.Listeners != nil {
- for _, listener := range listListenersResp.Body.Listeners {
- aliListenerIds = append(aliListenerIds, *listener.ListenerId)
- }
- }
-
- if listListenersResp.Body.NextToken == nil {
- break
- } else {
- listListenersToken = listListenersResp.Body.NextToken
- listListenersPage += 1
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到 ALB 负载均衡实例下的全部 QUIC 监听", aliListenerIds))
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 批量更新监听证书
- var errs []error
- for _, aliListenerId := range aliListenerIds {
- if err := d.updateListenerCertificate(ctx, aliListenerId, upres.CertId); err != nil {
- errs = append(errs, err)
- }
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
-
- return nil
-}
-
-func (d *AliyunALBDeployer) deployToListener(ctx context.Context) error {
- aliListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- if aliListenerId == "" {
- return errors.New("`listenerId` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 更新监听
- if err := d.updateListenerCertificate(ctx, aliListenerId, upres.CertId); err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *AliyunALBDeployer) updateListenerCertificate(ctx context.Context, aliListenerId string, aliCertId string) error {
- // 查询监听的属性
- // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getlistenerattribute
- getListenerAttributeReq := &aliyunAlb.GetListenerAttributeRequest{
- ListenerId: tea.String(aliListenerId),
- }
- getListenerAttributeResp, err := d.sdkClient.GetListenerAttribute(getListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 ALB 监听配置", getListenerAttributeResp))
-
- // 修改监听的属性
- // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-updatelistenerattribute
- updateListenerAttributeReq := &aliyunAlb.UpdateListenerAttributeRequest{
- ListenerId: tea.String(aliListenerId),
- Certificates: []*aliyunAlb.UpdateListenerAttributeRequestCertificates{{
- CertificateId: tea.String(aliCertId),
- }},
- }
- updateListenerAttributeResp, err := d.sdkClient.UpdateListenerAttribute(updateListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'alb.UpdateListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已更新 ALB 监听配置", updateListenerAttributeResp))
-
- return nil
-}
diff --git a/internal/deployer/aliyun_cdn.go b/internal/deployer/aliyun_cdn.go
deleted file mode 100644
index a23ce8a5..00000000
--- a/internal/deployer/aliyun_cdn.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "time"
-
- aliyunCdn "github.com/alibabacloud-go/cdn-20180510/v5/client"
- aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- "github.com/alibabacloud-go/tea/tea"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
-)
-
-type AliyunCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *aliyunCdn.Client
-}
-
-func NewAliyunCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunCDNDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- return &AliyunCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- }, nil
-}
-
-func (d *AliyunCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunCDNDeployer) Deploy(ctx context.Context) error {
- // 设置 CDN 域名域名证书
- // REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-setcdndomainsslcertificate
- setCdnDomainSSLCertificateReq := &aliyunCdn.SetCdnDomainSSLCertificateRequest{
- DomainName: tea.String(d.option.DeployConfig.GetConfigAsString("domain")),
- CertRegion: tea.String(d.option.DeployConfig.GetConfigOrDefaultAsString("region", "cn-hangzhou")),
- CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
- CertType: tea.String("upload"),
- SSLProtocol: tea.String("on"),
- SSLPub: tea.String(d.option.Certificate.Certificate),
- SSLPri: tea.String(d.option.Certificate.PrivateKey),
- }
- setCdnDomainSSLCertificateResp, err := d.sdkClient.SetCdnDomainSSLCertificate(setCdnDomainSSLCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.SetCdnDomainSSLCertificate'")
- }
-
- d.infos = append(d.infos, toStr("已设置 CDN 域名证书", setCdnDomainSSLCertificateResp))
-
- return nil
-}
-
-func (d *AliyunCDNDeployer) createSdkClient(accessKeyId, accessKeySecret string) (*aliyunCdn.Client, error) {
- aConfig := &aliyunOpen.Config{
- AccessKeyId: tea.String(accessKeyId),
- AccessKeySecret: tea.String(accessKeySecret),
- Endpoint: tea.String("cdn.aliyuncs.com"),
- }
-
- client, err := aliyunCdn.NewClient(aConfig)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/aliyun_clb.go b/internal/deployer/aliyun_clb.go
deleted file mode 100644
index 95d32b5d..00000000
--- a/internal/deployer/aliyun_clb.go
+++ /dev/null
@@ -1,286 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
-
- aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- aliyunSlb "github.com/alibabacloud-go/slb-20140515/v4/client"
- "github.com/alibabacloud-go/tea/tea"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderAliyunSlb "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-slb"
-)
-
-type AliyunCLBDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *aliyunSlb.Client
- sslUploader uploader.Uploader
-}
-
-func NewAliyunCLBDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunCLBDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- uploader, err := uploaderAliyunSlb.New(&uploaderAliyunSlb.AliyunSLBUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- AccessKeySecret: access.AccessKeySecret,
- Region: option.DeployConfig.GetConfigAsString("region"),
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &AliyunCLBDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *AliyunCLBDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunCLBDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunCLBDeployer) Deploy(ctx context.Context) error {
- switch d.option.DeployConfig.GetConfigAsString("resourceType") {
- case "loadbalancer":
- if err := d.deployToLoadbalancer(ctx); err != nil {
- return err
- }
- case "listener":
- if err := d.deployToListener(ctx); err != nil {
- return err
- }
- default:
- return errors.New("unsupported resource type")
- }
-
- return nil
-}
-
-func (d *AliyunCLBDeployer) createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Client, error) {
- if region == "" {
- region = "cn-hangzhou" // CLB(SLB) 服务默认区域:华东一杭州
- }
-
- aConfig := &aliyunOpen.Config{
- AccessKeyId: tea.String(accessKeyId),
- AccessKeySecret: tea.String(accessKeySecret),
- }
-
- var endpoint string
- switch region {
- case
- "cn-hangzhou",
- "cn-hangzhou-finance",
- "cn-shanghai-finance-1",
- "cn-shenzhen-finance-1":
- endpoint = "slb.aliyuncs.com"
- default:
- endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region)
- }
- aConfig.Endpoint = tea.String(endpoint)
-
- client, err := aliyunSlb.NewClient(aConfig)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
-
-func (d *AliyunCLBDeployer) deployToLoadbalancer(ctx context.Context) error {
- aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- aliListenerPorts := make([]int32, 0)
- if aliLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- // 查询负载均衡实例的详细信息
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerattribute
- describeLoadBalancerAttributeReq := &aliyunSlb.DescribeLoadBalancerAttributeRequest{
- RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
- LoadBalancerId: tea.String(aliLoadbalancerId),
- }
- describeLoadBalancerAttributeResp, err := d.sdkClient.DescribeLoadBalancerAttribute(describeLoadBalancerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.DescribeLoadBalancerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 CLB 负载均衡实例", describeLoadBalancerAttributeResp))
-
- // 查询 HTTPS 监听列表
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerlisteners
- listListenersPage := 1
- listListenersLimit := int32(100)
- var listListenersToken *string = nil
- for {
- describeLoadBalancerListenersReq := &aliyunSlb.DescribeLoadBalancerListenersRequest{
- RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
- MaxResults: tea.Int32(listListenersLimit),
- NextToken: listListenersToken,
- LoadBalancerId: []*string{tea.String(aliLoadbalancerId)},
- ListenerProtocol: tea.String("https"),
- }
- describeLoadBalancerListenersResp, err := d.sdkClient.DescribeLoadBalancerListeners(describeLoadBalancerListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.DescribeLoadBalancerListeners'")
- }
-
- if describeLoadBalancerListenersResp.Body.Listeners != nil {
- for _, listener := range describeLoadBalancerListenersResp.Body.Listeners {
- aliListenerPorts = append(aliListenerPorts, *listener.ListenerPort)
- }
- }
-
- if describeLoadBalancerListenersResp.Body.NextToken == nil {
- break
- } else {
- listListenersToken = describeLoadBalancerListenersResp.Body.NextToken
- listListenersPage += 1
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到 CLB 负载均衡实例下的全部 HTTPS 监听", aliListenerPorts))
-
- // 上传证书到 SLB
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 批量更新监听证书
- var errs []error
- for _, aliListenerPort := range aliListenerPorts {
- if err := d.updateListenerCertificate(ctx, aliLoadbalancerId, aliListenerPort, upres.CertId); err != nil {
- errs = append(errs, err)
- }
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
-
- return nil
-}
-
-func (d *AliyunCLBDeployer) deployToListener(ctx context.Context) error {
- aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- if aliLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- aliListenerPort := d.option.DeployConfig.GetConfigAsInt32("listenerPort")
- if aliListenerPort == 0 {
- return errors.New("`listenerPort` is required")
- }
-
- // 上传证书到 SLB
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 更新监听
- if err := d.updateListenerCertificate(ctx, aliLoadbalancerId, aliListenerPort, upres.CertId); err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *AliyunCLBDeployer) updateListenerCertificate(ctx context.Context, aliLoadbalancerId string, aliListenerPort int32, aliCertId string) error {
- // 查询监听配置
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute
- describeLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.DescribeLoadBalancerHTTPSListenerAttributeRequest{
- LoadBalancerId: tea.String(aliLoadbalancerId),
- ListenerPort: tea.Int32(aliListenerPort),
- }
- describeLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.DescribeLoadBalancerHTTPSListenerAttribute(describeLoadBalancerHTTPSListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.DescribeLoadBalancerHTTPSListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 CLB HTTPS 监听配置", describeLoadBalancerHTTPSListenerAttributeResp))
-
- // 查询扩展域名
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions
- describeDomainExtensionsReq := &aliyunSlb.DescribeDomainExtensionsRequest{
- RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
- LoadBalancerId: tea.String(aliLoadbalancerId),
- ListenerPort: tea.Int32(aliListenerPort),
- }
- describeDomainExtensionsResp, err := d.sdkClient.DescribeDomainExtensions(describeDomainExtensionsReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.DescribeDomainExtensions'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 CLB 扩展域名", describeDomainExtensionsResp))
-
- // 遍历修改扩展域名
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setdomainextensionattribute
- //
- // 这里仅修改跟被替换证书一致的扩展域名
- if describeDomainExtensionsResp.Body.DomainExtensions != nil && describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension != nil {
- for _, domainExtension := range describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension {
- if *domainExtension.ServerCertificateId != *describeLoadBalancerHTTPSListenerAttributeResp.Body.ServerCertificateId {
- continue
- }
-
- setDomainExtensionAttributeReq := &aliyunSlb.SetDomainExtensionAttributeRequest{
- RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
- DomainExtensionId: tea.String(*domainExtension.DomainExtensionId),
- ServerCertificateId: tea.String(aliCertId),
- }
- _, err := d.sdkClient.SetDomainExtensionAttribute(setDomainExtensionAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.SetDomainExtensionAttribute'")
- }
- }
- }
-
- // 修改监听配置
- // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
- //
- // 注意修改监听配置要放在修改扩展域名之后
- setLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.SetLoadBalancerHTTPSListenerAttributeRequest{
- RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
- LoadBalancerId: tea.String(aliLoadbalancerId),
- ListenerPort: tea.Int32(aliListenerPort),
- ServerCertificateId: tea.String(aliCertId),
- }
- setLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.SetLoadBalancerHTTPSListenerAttribute(setLoadBalancerHTTPSListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已更新 CLB HTTPS 监听配置", setLoadBalancerHTTPSListenerAttributeResp))
-
- return nil
-}
diff --git a/internal/deployer/aliyun_dcdn.go b/internal/deployer/aliyun_dcdn.go
deleted file mode 100644
index 0f969787..00000000
--- a/internal/deployer/aliyun_dcdn.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
- "time"
-
- aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- aliyunDcdn "github.com/alibabacloud-go/dcdn-20180115/v3/client"
- "github.com/alibabacloud-go/tea/tea"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
-)
-
-type AliyunDCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *aliyunDcdn.Client
-}
-
-func NewAliyunDCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunDCDNDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- return &AliyunDCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- }, nil
-}
-
-func (d *AliyunDCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunDCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunDCDNDeployer) Deploy(ctx context.Context) error {
- // 支持泛解析域名,在 Aliyun DCDN 中泛解析域名表示为 .example.com
- domain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(domain, "*") {
- domain = strings.TrimPrefix(domain, "*")
- }
-
- // 配置域名证书
- // REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-setdcdndomainsslcertificate
- setDcdnDomainSSLCertificateReq := &aliyunDcdn.SetDcdnDomainSSLCertificateRequest{
- DomainName: tea.String(domain),
- CertRegion: tea.String(d.option.DeployConfig.GetConfigOrDefaultAsString("region", "cn-hangzhou")),
- CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
- CertType: tea.String("upload"),
- SSLProtocol: tea.String("on"),
- SSLPub: tea.String(d.option.Certificate.Certificate),
- SSLPri: tea.String(d.option.Certificate.PrivateKey),
- }
- setDcdnDomainSSLCertificateResp, err := d.sdkClient.SetDcdnDomainSSLCertificate(setDcdnDomainSSLCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'dcdn.SetDcdnDomainSSLCertificate'")
- }
-
- d.infos = append(d.infos, toStr("已配置 DCDN 域名证书", setDcdnDomainSSLCertificateResp))
-
- return nil
-}
-
-func (d *AliyunDCDNDeployer) createSdkClient(accessKeyId, accessKeySecret string) (*aliyunDcdn.Client, error) {
- aConfig := &aliyunOpen.Config{
- AccessKeyId: tea.String(accessKeyId),
- AccessKeySecret: tea.String(accessKeySecret),
- Endpoint: tea.String("dcdn.aliyuncs.com"),
- }
-
- client, err := aliyunDcdn.NewClient(aConfig)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/aliyun_nlb.go b/internal/deployer/aliyun_nlb.go
deleted file mode 100644
index bbaddd7b..00000000
--- a/internal/deployer/aliyun_nlb.go
+++ /dev/null
@@ -1,245 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
-
- aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
- aliyunNlb "github.com/alibabacloud-go/nlb-20220430/v2/client"
- "github.com/alibabacloud-go/tea/tea"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderAliyunCas "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
-)
-
-type AliyunNLBDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *aliyunNlb.Client
- sslUploader uploader.Uploader
-}
-
-func NewAliyunNLBDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunNLBDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- aliCasRegion := option.DeployConfig.GetConfigAsString("region")
- if aliCasRegion != "" {
- // 阿里云 CAS 服务接入点是独立于 NLB 服务的
- // 国内版接入点:华东一杭州
- // 国际版接入点:亚太东南一新加坡
- if !strings.HasPrefix(aliCasRegion, "cn-") {
- aliCasRegion = "ap-southeast-1"
- } else {
- aliCasRegion = "cn-hangzhou"
- }
- }
- uploader, err := uploaderAliyunCas.New(&uploaderAliyunCas.AliyunCASUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- AccessKeySecret: access.AccessKeySecret,
- Region: aliCasRegion,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &AliyunNLBDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *AliyunNLBDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunNLBDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunNLBDeployer) Deploy(ctx context.Context) error {
- switch d.option.DeployConfig.GetConfigAsString("resourceType") {
- case "loadbalancer":
- if err := d.deployToLoadbalancer(ctx); err != nil {
- return err
- }
- case "listener":
- if err := d.deployToListener(ctx); err != nil {
- return err
- }
- default:
- return errors.New("unsupported resource type")
- }
-
- return nil
-}
-
-func (d *AliyunNLBDeployer) createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunNlb.Client, error) {
- if region == "" {
- region = "cn-hangzhou" // NLB 服务默认区域:华东一杭州
- }
-
- aConfig := &aliyunOpen.Config{
- AccessKeyId: tea.String(accessKeyId),
- AccessKeySecret: tea.String(accessKeySecret),
- }
-
- var endpoint string
- switch region {
- default:
- endpoint = fmt.Sprintf("nlb.%s.aliyuncs.com", region)
- }
- aConfig.Endpoint = tea.String(endpoint)
-
- client, err := aliyunNlb.NewClient(aConfig)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
-
-func (d *AliyunNLBDeployer) deployToLoadbalancer(ctx context.Context) error {
- aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- if aliLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- aliListenerIds := make([]string, 0)
-
- // 查询负载均衡实例的详细信息
- // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getloadbalancerattribute
- getLoadBalancerAttributeReq := &aliyunNlb.GetLoadBalancerAttributeRequest{
- LoadBalancerId: tea.String(aliLoadbalancerId),
- }
- getLoadBalancerAttributeResp, err := d.sdkClient.GetLoadBalancerAttribute(getLoadBalancerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'nlb.GetLoadBalancerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 NLB 负载均衡实例", getLoadBalancerAttributeResp))
-
- // 查询 TCPSSL 监听列表
- // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-listlisteners
- listListenersPage := 1
- listListenersLimit := int32(100)
- var listListenersToken *string = nil
- for {
- listListenersReq := &aliyunNlb.ListListenersRequest{
- MaxResults: tea.Int32(listListenersLimit),
- NextToken: listListenersToken,
- LoadBalancerIds: []*string{tea.String(aliLoadbalancerId)},
- ListenerProtocol: tea.String("TCPSSL"),
- }
- listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'nlb.ListListeners'")
- }
-
- if listListenersResp.Body.Listeners != nil {
- for _, listener := range listListenersResp.Body.Listeners {
- aliListenerIds = append(aliListenerIds, *listener.ListenerId)
- }
- }
-
- if listListenersResp.Body.NextToken == nil {
- break
- } else {
- listListenersToken = listListenersResp.Body.NextToken
- listListenersPage += 1
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到 NLB 负载均衡实例下的全部 TCPSSL 监听", aliListenerIds))
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 批量更新监听证书
- var errs []error
- for _, aliListenerId := range aliListenerIds {
- if err := d.updateListenerCertificate(ctx, aliListenerId, upres.CertId); err != nil {
- errs = append(errs, err)
- }
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
-
- return nil
-}
-
-func (d *AliyunNLBDeployer) deployToListener(ctx context.Context) error {
- aliListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- if aliListenerId == "" {
- return errors.New("`listenerId` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 更新监听
- if err := d.updateListenerCertificate(ctx, aliListenerId, upres.CertId); err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *AliyunNLBDeployer) updateListenerCertificate(ctx context.Context, aliListenerId string, aliCertId string) error {
- // 查询监听的属性
- // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getlistenerattribute
- getListenerAttributeReq := &aliyunNlb.GetListenerAttributeRequest{
- ListenerId: tea.String(aliListenerId),
- }
- getListenerAttributeResp, err := d.sdkClient.GetListenerAttribute(getListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'nlb.GetListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 NLB 监听配置", getListenerAttributeResp))
-
- // 修改监听的属性
- // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-updatelistenerattribute
- updateListenerAttributeReq := &aliyunNlb.UpdateListenerAttributeRequest{
- ListenerId: tea.String(aliListenerId),
- CertificateIds: []*string{tea.String(aliCertId)},
- }
- updateListenerAttributeResp, err := d.sdkClient.UpdateListenerAttribute(updateListenerAttributeReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'nlb.UpdateListenerAttribute'")
- }
-
- d.infos = append(d.infos, toStr("已更新 NLB 监听配置", updateListenerAttributeResp))
-
- return nil
-}
diff --git a/internal/deployer/aliyun_oss.go b/internal/deployer/aliyun_oss.go
deleted file mode 100644
index d0045d89..00000000
--- a/internal/deployer/aliyun_oss.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
-
- "github.com/aliyun/aliyun-oss-go-sdk/oss"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
-)
-
-type AliyunOSSDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *oss.Client
-}
-
-func NewAliyunOSSDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.AliyunAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&AliyunOSSDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.AccessKeySecret,
- option.DeployConfig.GetConfigAsString("endpoint"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- return &AliyunOSSDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- }, nil
-}
-
-func (d *AliyunOSSDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *AliyunOSSDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *AliyunOSSDeployer) Deploy(ctx context.Context) error {
- aliBucket := d.option.DeployConfig.GetConfigAsString("bucket")
- if aliBucket == "" {
- return errors.New("`bucket` is required")
- }
-
- // 为存储空间绑定自定义域名
- // REF: https://help.aliyun.com/zh/oss/developer-reference/putcname
- err := d.sdkClient.PutBucketCnameWithCertificate(aliBucket, oss.PutBucketCname{
- Cname: d.option.DeployConfig.GetConfigAsString("domain"),
- CertificateConfiguration: &oss.CertificateConfiguration{
- Certificate: d.option.Certificate.Certificate,
- PrivateKey: d.option.Certificate.PrivateKey,
- Force: true,
- },
- })
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'oss.PutBucketCnameWithCertificate'")
- }
-
- return nil
-}
-
-func (d *AliyunOSSDeployer) createSdkClient(accessKeyId, accessKeySecret, endpoint string) (*oss.Client, error) {
- if endpoint == "" {
- endpoint = "oss.aliyuncs.com"
- }
-
- client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/baiducloud_cdn.go b/internal/deployer/baiducloud_cdn.go
deleted file mode 100644
index 31d789df..00000000
--- a/internal/deployer/baiducloud_cdn.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "time"
-
- bceCdn "github.com/baidubce/bce-sdk-go/services/cdn"
- bceCdnApi "github.com/baidubce/bce-sdk-go/services/cdn/api"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
-)
-
-type BaiduCloudCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *bceCdn.Client
-}
-
-func NewBaiduCloudCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.BaiduCloudAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&BaiduCloudCDNDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.SecretAccessKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- return &BaiduCloudCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- }, nil
-}
-
-func (d *BaiduCloudCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *BaiduCloudCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *BaiduCloudCDNDeployer) Deploy(ctx context.Context) error {
- // 修改域名证书
- // REF: https://cloud.baidu.com/doc/CDN/s/qjzuz2hp8
- putCertResp, err := d.sdkClient.PutCert(
- d.option.DeployConfig.GetConfigAsString("domain"),
- &bceCdnApi.UserCertificate{
- CertName: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()),
- ServerData: d.option.Certificate.Certificate,
- PrivateData: d.option.Certificate.PrivateKey,
- },
- "ON",
- )
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.PutCert'")
- }
-
- d.infos = append(d.infos, toStr("已修改域名证书", putCertResp))
-
- return nil
-}
-
-func (d *BaiduCloudCDNDeployer) createSdkClient(accessKeyId, secretAccessKey string) (*bceCdn.Client, error) {
- client, err := bceCdn.NewClient(accessKeyId, secretAccessKey, "")
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/byteplus_cdn.go b/internal/deployer/byteplus_cdn.go
deleted file mode 100644
index 17c51522..00000000
--- a/internal/deployer/byteplus_cdn.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- bytepluscdn "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/byteplus-cdn"
-
- "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn"
- xerrors "github.com/pkg/errors"
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
-)
-
-type ByteplusCDNDeployer struct {
- option *DeployerOption
- infos []string
- sdkClient *cdn.CDN
- sslUploader uploader.Uploader
-}
-
-func NewByteplusCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.ByteplusAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
- client := cdn.NewInstance()
- client.Client.SetAccessKey(access.AccessKey)
- client.Client.SetSecretKey(access.SecretKey)
- uploader, err := bytepluscdn.New(&bytepluscdn.ByteplusCDNUploaderConfig{
- AccessKey: access.AccessKey,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
- return &ByteplusCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *ByteplusCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *ByteplusCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *ByteplusCDNDeployer) Deploy(ctx context.Context) error {
- apiCtx := context.Background()
- // 上传证书
- upres, err := d.sslUploader.Upload(apiCtx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- domains := make([]string, 0)
- configDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(configDomain, "*.") {
- // 获取证书可以部署的域名
- // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-describecertconfig-9ea17
- describeCertConfigReq := &cdn.DescribeCertConfigRequest{
- CertId: upres.CertId,
- }
- describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertConfig'")
- }
- for i := range describeCertConfigResp.Result.CertNotConfig {
- // 当前未启用 HTTPS 的加速域名列表。
- domains = append(domains, describeCertConfigResp.Result.CertNotConfig[i].Domain)
- }
- for i := range describeCertConfigResp.Result.OtherCertConfig {
- // 已启用了 HTTPS 的加速域名列表。这些加速域名关联的证书不是您指定的证书。
- domains = append(domains, describeCertConfigResp.Result.OtherCertConfig[i].Domain)
- }
- for i := range describeCertConfigResp.Result.SpecifiedCertConfig {
- // 已启用了 HTTPS 的加速域名列表。这些加速域名关联了您指定的证书。
- d.infos = append(d.infos, fmt.Sprintf("%s域名已配置该证书", describeCertConfigResp.Result.SpecifiedCertConfig[i].Domain))
- }
- if len(domains) == 0 {
- if len(describeCertConfigResp.Result.SpecifiedCertConfig) > 0 {
- // 所有匹配的域名都配置了该证书,跳过部署
- return nil
- } else {
- return xerrors.Errorf("未查询到匹配的域名: %s", configDomain)
- }
- }
- } else {
- domains = append(domains, configDomain)
- }
- // 部署证书
- // REF: https://github.com/byteplus-sdk/byteplus-sdk-golang/blob/master/service/cdn/api_list.go#L306
- for i := range domains {
- batchDeployCertReq := &cdn.BatchDeployCertRequest{
- CertId: upres.CertId,
- Domain: domains[i],
- }
- batchDeployCertResp, err := d.sdkClient.BatchDeployCert(batchDeployCertReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.BatchDeployCert'")
- } else {
- d.infos = append(d.infos, toStr(fmt.Sprintf("%s域名的证书已修改", domains[i]), batchDeployCertResp))
- }
- }
-
- return nil
-}
diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go
index a467694d..c5013d9d 100644
--- a/internal/deployer/deployer.go
+++ b/internal/deployer/deployer.go
@@ -2,14 +2,13 @@ package deployer
import (
"context"
- "encoding/json"
- "errors"
"fmt"
"github.com/pocketbase/pocketbase/models"
"github.com/usual2970/certimate/internal/applicant"
"github.com/usual2970/certimate/internal/domain"
+ "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/repository"
)
@@ -79,7 +78,7 @@ func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error
}
for _, deployConfig := range deployConfigs {
- deployer, err := getWithDeployConfig(record, cert, deployConfig)
+ deployer, err := newWithDeployConfig(record, cert, deployConfig)
if err != nil {
return nil, err
}
@@ -91,10 +90,10 @@ func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error
}
func GetWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) {
- return getWithTypeAndOption(deployType, option)
+ return newWithTypeAndOption(deployType, option)
}
-func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) {
+func newWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) {
accessRepo := repository.NewAccessRepository()
access, err := accessRepo.GetById(context.Background(), deployConfig.Access)
if err != nil {
@@ -117,65 +116,38 @@ func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, dep
}
}
- return getWithTypeAndOption(deployConfig.Type, option)
+ return newWithTypeAndOption(deployConfig.Type, option)
}
-func getWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) {
- switch deployType {
- case targetAliyunOSS:
- return NewAliyunOSSDeployer(option)
- case targetAliyunCDN:
- return NewAliyunCDNDeployer(option)
- case targetAliyunDCDN:
- return NewAliyunDCDNDeployer(option)
- case targetAliyunCLB:
- return NewAliyunCLBDeployer(option)
- case targetAliyunALB:
- return NewAliyunALBDeployer(option)
- case targetAliyunNLB:
- return NewAliyunNLBDeployer(option)
- case targetTencentCloudCDN:
- return NewTencentCDNDeployer(option)
- case targetTencentCloudECDN:
- return NewTencentECDNDeployer(option)
- case targetTencentCloudCLB:
- return NewTencentCLBDeployer(option)
- case targetTencentCloudCOS:
- return NewTencentCOSDeployer(option)
- case targetTencentCloudEO:
- return NewTencentTEODeployer(option)
- case targetHuaweiCloudCDN:
- return NewHuaweiCloudCDNDeployer(option)
- case targetHuaweiCloudELB:
- return NewHuaweiCloudELBDeployer(option)
- case targetBaiduCloudCDN:
- return NewBaiduCloudCDNDeployer(option)
- case targetQiniuCDN:
- return NewQiniuCDNDeployer(option)
- case targetDogeCloudCDN:
- return NewDogeCloudCDNDeployer(option)
- case targetLocal:
- return NewLocalDeployer(option)
- case targetSSH:
- return NewSSHDeployer(option)
- case targetWebhook:
- return NewWebhookDeployer(option)
- case targetK8sSecret:
- return NewK8sSecretDeployer(option)
- case targetVolcEngineLive:
- return NewVolcengineLiveDeployer(option)
- case targetVolcEngineCDN:
- return NewVolcengineCDNDeployer(option)
- case targetBytePlusCDN:
- return NewByteplusCDNDeployer(option)
+func newWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) {
+ deployer, logger, err := createDeployer(deployType, option.AccessRecord.Config, option.DeployConfig.Config)
+ if err != nil {
+ return nil, err
}
- return nil, errors.New("unsupported deploy target")
+
+ return &proxyDeployer{
+ option: option,
+ logger: logger,
+ deployer: deployer,
+ }, nil
}
-func toStr(tag string, data any) string {
- if data == nil {
- return tag
- }
- byts, _ := json.Marshal(data)
- return tag + ":" + string(byts)
+// TODO: 暂时使用代理模式以兼容之前版本代码,后续重新实现此处逻辑
+type proxyDeployer struct {
+ option *DeployerOption
+ logger deployer.Logger
+ deployer deployer.Deployer
+}
+
+func (d *proxyDeployer) GetID() string {
+ return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
+}
+
+func (d *proxyDeployer) GetInfos() []string {
+ return d.logger.GetRecords()
+}
+
+func (d *proxyDeployer) Deploy(ctx context.Context) error {
+ _, err := d.deployer.Deploy(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
+ return err
}
diff --git a/internal/deployer/dogecloud_cdn.go b/internal/deployer/dogecloud_cdn.go
deleted file mode 100644
index 55e526c1..00000000
--- a/internal/deployer/dogecloud_cdn.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strconv"
-
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderDoge "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/dogecloud"
- doge "github.com/usual2970/certimate/internal/pkg/vendors/dogecloud-sdk"
-)
-
-type DogeCloudCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *doge.Client
- sslUploader uploader.Uploader
-}
-
-func NewDogeCloudCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.DogeCloudAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&DogeCloudCDNDeployer{}).createSdkClient(
- access.AccessKey,
- access.SecretKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- uploader, err := uploaderDoge.New(&uploaderDoge.DogeCloudUploaderConfig{
- AccessKey: access.AccessKey,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &DogeCloudCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *DogeCloudCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *DogeCloudCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *DogeCloudCDNDeployer) Deploy(ctx context.Context) error {
- // 上传证书到 CDN
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 绑定证书
- // REF: https://docs.dogecloud.com/cdn/api-cert-bind
- bindCdnCertId, _ := strconv.ParseInt(upres.CertId, 10, 64)
- bindCdnCertResp, err := d.sdkClient.BindCdnCertWithDomain(bindCdnCertId, d.option.DeployConfig.GetConfigAsString("domain"))
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.BindCdnCert'")
- }
-
- d.infos = append(d.infos, toStr("已绑定证书", bindCdnCertResp))
-
- return nil
-}
-
-func (d *DogeCloudCDNDeployer) createSdkClient(accessKey, secretKey string) (*doge.Client, error) {
- client := doge.NewClient(accessKey, secretKey)
- return client, nil
-}
diff --git a/internal/deployer/factory.go b/internal/deployer/factory.go
index d0ab4621..f4fde3e7 100644
--- a/internal/deployer/factory.go
+++ b/internal/deployer/factory.go
@@ -362,9 +362,23 @@ func createDeployer(target string, accessConfig string, deployConfig map[string]
return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err)
}
+ variables := make(map[string]string)
+ if deployConfig != nil {
+ value, ok := deployConfig["variables"]
+ if ok {
+ kvs := make([]domain.KV, 0)
+ bts, _ := json.Marshal(value)
+ if err := json.Unmarshal(bts, &kvs); err == nil {
+ for _, kv := range kvs {
+ variables[kv.Key] = kv.Value
+ }
+ }
+ }
+ }
+
deployer, err := providerWebhook.NewWithLogger(&providerWebhook.WebhookDeployerConfig{
Url: access.Url,
- Variables: nil, // TODO: 尚未实现
+ Variables: variables,
}, logger)
return deployer, logger, err
}
diff --git a/internal/deployer/huaweicloud_cdn.go b/internal/deployer/huaweicloud_cdn.go
deleted file mode 100644
index d3d4014f..00000000
--- a/internal/deployer/huaweicloud_cdn.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
-
- "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
- hcCdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2"
- hcCdnModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model"
- hcCdnRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/region"
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderHcScm "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-scm"
- "github.com/usual2970/certimate/internal/pkg/utils/cast"
- hcCdnEx "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-cdn-sdk"
-)
-
-type HuaweiCloudCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *hcCdnEx.Client
- sslUploader uploader.Uploader
-}
-
-func NewHuaweiCloudCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.HuaweiCloudAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&HuaweiCloudCDNDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.SecretAccessKey,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- uploader, err := uploaderHcScm.New(&uploaderHcScm.HuaweiCloudSCMUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- SecretAccessKey: access.SecretAccessKey,
- Region: "",
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &HuaweiCloudCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *HuaweiCloudCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *HuaweiCloudCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *HuaweiCloudCDNDeployer) Deploy(ctx context.Context) error {
- // 上传证书到 SCM
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 查询加速域名配置
- // REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html
- showDomainFullConfigReq := &hcCdnModel.ShowDomainFullConfigRequest{
- DomainName: d.option.DeployConfig.GetConfigAsString("domain"),
- }
- showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.ShowDomainFullConfig'")
- }
-
- d.infos = append(d.infos, toStr("已查询到加速域名配置", showDomainFullConfigResp))
-
- // 更新加速域名配置
- // REF: https://support.huaweicloud.com/api-cdn/UpdateDomainMultiCertificates.html
- // REF: https://support.huaweicloud.com/usermanual-cdn/cdn_01_0306.html
- updateDomainMultiCertificatesReqBodyContent := &hcCdnEx.UpdateDomainMultiCertificatesExRequestBodyContent{}
- updateDomainMultiCertificatesReqBodyContent.DomainName = d.option.DeployConfig.GetConfigAsString("domain")
- updateDomainMultiCertificatesReqBodyContent.HttpsSwitch = 1
- updateDomainMultiCertificatesReqBodyContent.CertificateType = cast.Int32Ptr(2)
- updateDomainMultiCertificatesReqBodyContent.SCMCertificateId = cast.StringPtr(upres.CertId)
- updateDomainMultiCertificatesReqBodyContent.CertName = cast.StringPtr(upres.CertName)
- updateDomainMultiCertificatesReqBodyContent = updateDomainMultiCertificatesReqBodyContent.MergeConfig(showDomainFullConfigResp.Configs)
- updateDomainMultiCertificatesReq := &hcCdnEx.UpdateDomainMultiCertificatesExRequest{
- Body: &hcCdnEx.UpdateDomainMultiCertificatesExRequestBody{
- Https: updateDomainMultiCertificatesReqBodyContent,
- },
- }
- updateDomainMultiCertificatesResp, err := d.sdkClient.UploadDomainMultiCertificatesEx(updateDomainMultiCertificatesReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.UploadDomainMultiCertificatesEx'")
- }
-
- d.infos = append(d.infos, toStr("已更新加速域名配置", updateDomainMultiCertificatesResp))
-
- return nil
-}
-
-func (d *HuaweiCloudCDNDeployer) createSdkClient(accessKeyId, secretAccessKey, region string) (*hcCdnEx.Client, error) {
- if region == "" {
- region = "cn-north-1" // CDN 服务默认区域:华北一北京
- }
-
- auth, err := global.NewCredentialsBuilder().
- WithAk(accessKeyId).
- WithSk(secretAccessKey).
- SafeBuild()
- if err != nil {
- return nil, err
- }
-
- hcRegion, err := hcCdnRegion.SafeValueOf(region)
- if err != nil {
- return nil, err
- }
-
- hcClient, err := hcCdn.CdnClientBuilder().
- WithRegion(hcRegion).
- WithCredential(auth).
- SafeBuild()
- if err != nil {
- return nil, err
- }
-
- client := hcCdnEx.NewClient(hcClient)
- return client, nil
-}
diff --git a/internal/deployer/huaweicloud_elb.go b/internal/deployer/huaweicloud_elb.go
deleted file mode 100644
index ccc6f9f5..00000000
--- a/internal/deployer/huaweicloud_elb.go
+++ /dev/null
@@ -1,378 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
-
- "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
- "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
- hcElb "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3"
- hcElbModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/model"
- hcElbRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/region"
- hcIam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
- hcIamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
- hcIamRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
- xerrors "github.com/pkg/errors"
- "golang.org/x/exp/slices"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderHcElb "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-elb"
- "github.com/usual2970/certimate/internal/pkg/utils/cast"
-)
-
-type HuaweiCloudELBDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *hcElb.ElbClient
- sslUploader uploader.Uploader
-}
-
-func NewHuaweiCloudELBDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.HuaweiCloudAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&HuaweiCloudELBDeployer{}).createSdkClient(
- access.AccessKeyId,
- access.SecretAccessKey,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- uploader, err := uploaderHcElb.New(&uploaderHcElb.HuaweiCloudELBUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- SecretAccessKey: access.SecretAccessKey,
- Region: option.DeployConfig.GetConfigAsString("region"),
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &HuaweiCloudELBDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *HuaweiCloudELBDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *HuaweiCloudELBDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *HuaweiCloudELBDeployer) Deploy(ctx context.Context) error {
- switch d.option.DeployConfig.GetConfigAsString("resourceType") {
- case "certificate":
- // 部署到指定证书
- if err := d.deployToCertificate(ctx); err != nil {
- return err
- }
- case "loadbalancer":
- // 部署到指定负载均衡器
- if err := d.deployToLoadbalancer(ctx); err != nil {
- return err
- }
- case "listener":
- // 部署到指定监听器
- if err := d.deployToListener(ctx); err != nil {
- return err
- }
- default:
- return errors.New("unsupported resource type")
- }
-
- return nil
-}
-
-func (d *HuaweiCloudELBDeployer) createSdkClient(accessKeyId, secretAccessKey, region string) (*hcElb.ElbClient, error) {
- if region == "" {
- region = "cn-north-4" // ELB 服务默认区域:华北四北京
- }
-
- projectId, err := (&HuaweiCloudELBDeployer{}).getSdkProjectId(
- accessKeyId,
- secretAccessKey,
- region,
- )
- if err != nil {
- return nil, err
- }
-
- auth, err := basic.NewCredentialsBuilder().
- WithAk(accessKeyId).
- WithSk(secretAccessKey).
- WithProjectId(projectId).
- SafeBuild()
- if err != nil {
- return nil, err
- }
-
- hcRegion, err := hcElbRegion.SafeValueOf(region)
- if err != nil {
- return nil, err
- }
-
- hcClient, err := hcElb.ElbClientBuilder().
- WithRegion(hcRegion).
- WithCredential(auth).
- SafeBuild()
- if err != nil {
- return nil, err
- }
-
- client := hcElb.NewElbClient(hcClient)
- return client, nil
-}
-
-func (u *HuaweiCloudELBDeployer) getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error) {
- if region == "" {
- region = "cn-north-4" // IAM 服务默认区域:华北四北京
- }
-
- auth, err := global.NewCredentialsBuilder().
- WithAk(accessKeyId).
- WithSk(secretAccessKey).
- SafeBuild()
- if err != nil {
- return "", err
- }
-
- hcRegion, err := hcIamRegion.SafeValueOf(region)
- if err != nil {
- return "", err
- }
-
- hcClient, err := hcIam.IamClientBuilder().
- WithRegion(hcRegion).
- WithCredential(auth).
- SafeBuild()
- if err != nil {
- return "", err
- }
-
- client := hcIam.NewIamClient(hcClient)
-
- request := &hcIamModel.KeystoneListProjectsRequest{
- Name: ®ion,
- }
- response, err := client.KeystoneListProjects(request)
- if err != nil {
- return "", err
- } else if response.Projects == nil || len(*response.Projects) == 0 {
- return "", errors.New("no project found")
- }
-
- return (*response.Projects)[0].Id, nil
-}
-
-func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context) error {
- hcCertId := d.option.DeployConfig.GetConfigAsString("certificateId")
- if hcCertId == "" {
- return errors.New("`certificateId` is required")
- }
-
- // 更新证书
- // REF: https://support.huaweicloud.com/api-elb/UpdateCertificate.html
- updateCertificateReq := &hcElbModel.UpdateCertificateRequest{
- CertificateId: hcCertId,
- Body: &hcElbModel.UpdateCertificateRequestBody{
- Certificate: &hcElbModel.UpdateCertificateOption{
- Certificate: cast.StringPtr(d.option.Certificate.Certificate),
- PrivateKey: cast.StringPtr(d.option.Certificate.PrivateKey),
- },
- },
- }
- updateCertificateResp, err := d.sdkClient.UpdateCertificate(updateCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.UpdateCertificate'")
- }
-
- d.infos = append(d.infos, toStr("已更新 ELB 证书", updateCertificateResp))
-
- return nil
-}
-
-func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error {
- hcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- if hcLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- hcListenerIds := make([]string, 0)
-
- // 查询负载均衡器详情
- // REF: https://support.huaweicloud.com/api-elb/ShowLoadBalancer.html
- showLoadBalancerReq := &hcElbModel.ShowLoadBalancerRequest{
- LoadbalancerId: hcLoadbalancerId,
- }
- showLoadBalancerResp, err := d.sdkClient.ShowLoadBalancer(showLoadBalancerReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.ShowLoadBalancer'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 ELB 负载均衡器", showLoadBalancerResp))
-
- // 查询监听器列表
- // REF: https://support.huaweicloud.com/api-elb/ListListeners.html
- listListenersLimit := int32(2000)
- var listListenersMarker *string = nil
- for {
- listListenersReq := &hcElbModel.ListListenersRequest{
- Limit: cast.Int32Ptr(listListenersLimit),
- Marker: listListenersMarker,
- Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"},
- LoadbalancerId: &[]string{showLoadBalancerResp.Loadbalancer.Id},
- }
- listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.ListListeners'")
- }
-
- if listListenersResp.Listeners != nil {
- for _, listener := range *listListenersResp.Listeners {
- hcListenerIds = append(hcListenerIds, listener.Id)
- }
- }
-
- if listListenersResp.Listeners == nil || len(*listListenersResp.Listeners) < int(listListenersLimit) {
- break
- } else {
- listListenersMarker = listListenersResp.PageInfo.NextMarker
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到 ELB 负载均衡器下的监听器", hcListenerIds))
-
- // 上传证书到 SCM
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 批量更新监听器证书
- var errs []error
- for _, hcListenerId := range hcListenerIds {
- if err := d.modifyListenerCertificate(ctx, hcListenerId, upres.CertId); err != nil {
- errs = append(errs, err)
- }
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
-
- return nil
-}
-
-func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context) error {
- hcListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- if hcListenerId == "" {
- return errors.New("`listenerId` is required")
- }
-
- // 上传证书到 SCM
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 更新监听器证书
- if err := d.modifyListenerCertificate(ctx, hcListenerId, upres.CertId); err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *HuaweiCloudELBDeployer) modifyListenerCertificate(ctx context.Context, hcListenerId string, hcCertId string) error {
- // 查询监听器详情
- // REF: https://support.huaweicloud.com/api-elb/ShowListener.html
- showListenerReq := &hcElbModel.ShowListenerRequest{
- ListenerId: hcListenerId,
- }
- showListenerResp, err := d.sdkClient.ShowListener(showListenerReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.ShowListener'")
- }
-
- d.infos = append(d.infos, toStr("已查询到 ELB 监听器", showListenerResp))
-
- // 更新监听器
- // REF: https://support.huaweicloud.com/api-elb/UpdateListener.html
- updateListenerReq := &hcElbModel.UpdateListenerRequest{
- ListenerId: hcListenerId,
- Body: &hcElbModel.UpdateListenerRequestBody{
- Listener: &hcElbModel.UpdateListenerOption{
- DefaultTlsContainerRef: cast.StringPtr(hcCertId),
- },
- },
- }
- if showListenerResp.Listener.SniContainerRefs != nil {
- if len(showListenerResp.Listener.SniContainerRefs) > 0 {
- // 如果开启 SNI,需替换同 SAN 的证书
- sniCertIds := make([]string, 0)
- sniCertIds = append(sniCertIds, hcCertId)
-
- listOldCertificateReq := &hcElbModel.ListCertificatesRequest{
- Id: &showListenerResp.Listener.SniContainerRefs,
- }
- listOldCertificateResp, err := d.sdkClient.ListCertificates(listOldCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.ListCertificates'")
- }
-
- showNewCertificateReq := &hcElbModel.ShowCertificateRequest{
- CertificateId: hcCertId,
- }
- showNewCertificateResp, err := d.sdkClient.ShowCertificate(showNewCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.ShowCertificate'")
- }
-
- for _, certificate := range *listOldCertificateResp.Certificates {
- oldCertificate := certificate
- newCertificate := showNewCertificateResp.Certificate
-
- if oldCertificate.SubjectAlternativeNames != nil && newCertificate.SubjectAlternativeNames != nil {
- if slices.Equal(*oldCertificate.SubjectAlternativeNames, *newCertificate.SubjectAlternativeNames) {
- continue
- }
- } else {
- if oldCertificate.Domain == newCertificate.Domain {
- continue
- }
- }
-
- sniCertIds = append(sniCertIds, certificate.Id)
- }
-
- updateListenerReq.Body.Listener.SniContainerRefs = &sniCertIds
- }
-
- if showListenerResp.Listener.SniMatchAlgo != "" {
- updateListenerReq.Body.Listener.SniMatchAlgo = cast.StringPtr(showListenerResp.Listener.SniMatchAlgo)
- }
- }
- updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'elb.UpdateListener'")
- }
-
- d.infos = append(d.infos, toStr("已更新 ELB 监听器", updateListenerResp))
-
- return nil
-}
diff --git a/internal/deployer/k8s_secret.go b/internal/deployer/k8s_secret.go
deleted file mode 100644
index 8a1c30ff..00000000
--- a/internal/deployer/k8s_secret.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
-
- xerrors "github.com/pkg/errors"
- k8sCore "k8s.io/api/core/v1"
- k8sMeta "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/clientcmd"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/utils/x509"
-)
-
-type K8sSecretDeployer struct {
- option *DeployerOption
- infos []string
-
- k8sClient *kubernetes.Clientset
-}
-
-func NewK8sSecretDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.KubernetesAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&K8sSecretDeployer{}).createK8sClient(access)
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create k8s client")
- }
-
- return &K8sSecretDeployer{
- option: option,
- infos: make([]string, 0),
- k8sClient: client,
- }, nil
-}
-
-func (d *K8sSecretDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *K8sSecretDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *K8sSecretDeployer) Deploy(ctx context.Context) error {
- namespace := d.option.DeployConfig.GetConfigAsString("namespace")
- secretName := d.option.DeployConfig.GetConfigAsString("secretName")
- secretDataKeyForCrt := d.option.DeployConfig.GetConfigOrDefaultAsString("secretDataKeyForCrt", "tls.crt")
- secretDataKeyForKey := d.option.DeployConfig.GetConfigOrDefaultAsString("secretDataKeyForKey", "tls.key")
- if namespace == "" {
- namespace = "default"
- }
- if secretName == "" {
- return errors.New("`secretName` is required")
- }
-
- certX509, err := x509.ParseCertificateFromPEM(d.option.Certificate.Certificate)
- if err != nil {
- return err
- }
-
- secretPayload := k8sCore.Secret{
- TypeMeta: k8sMeta.TypeMeta{
- Kind: "Secret",
- APIVersion: "v1",
- },
- ObjectMeta: k8sMeta.ObjectMeta{
- Name: secretName,
- Annotations: map[string]string{
- "certimate/domains": d.option.Domain,
- "certimate/alt-names": strings.Join(certX509.DNSNames, ","),
- "certimate/common-name": certX509.Subject.CommonName,
- "certimate/issuer-organization": strings.Join(certX509.Issuer.Organization, ","),
- },
- },
- Type: k8sCore.SecretType("kubernetes.io/tls"),
- }
- secretPayload.Data = make(map[string][]byte)
- secretPayload.Data[secretDataKeyForCrt] = []byte(d.option.Certificate.Certificate)
- secretPayload.Data[secretDataKeyForKey] = []byte(d.option.Certificate.PrivateKey)
-
- // 获取 Secret 实例
- _, err = d.k8sClient.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, k8sMeta.GetOptions{})
- if err != nil {
- _, err = d.k8sClient.CoreV1().Secrets(namespace).Create(context.TODO(), &secretPayload, k8sMeta.CreateOptions{})
- if err != nil {
- return xerrors.Wrap(err, "failed to create k8s secret")
- } else {
- d.infos = append(d.infos, toStr("Certificate has been created in K8s Secret", nil))
- return nil
- }
- }
-
- // 更新 Secret 实例
- _, err = d.k8sClient.CoreV1().Secrets(namespace).Update(context.TODO(), &secretPayload, k8sMeta.UpdateOptions{})
- if err != nil {
- return xerrors.Wrap(err, "failed to update k8s secret")
- }
-
- d.infos = append(d.infos, toStr("Certificate has been updated to K8s Secret", nil))
-
- return nil
-}
-
-func (d *K8sSecretDeployer) createK8sClient(access *domain.KubernetesAccess) (*kubernetes.Clientset, error) {
- var config *rest.Config
- var err error
- if access.KubeConfig == "" {
- config, err = rest.InClusterConfig()
- } else {
- kubeConfig, err := clientcmd.NewClientConfigFromBytes([]byte(access.KubeConfig))
- if err != nil {
- return nil, err
- }
- config, err = kubeConfig.ClientConfig()
- }
- if err != nil {
- return nil, err
- }
-
- client, err := kubernetes.NewForConfig(config)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/local.go b/internal/deployer/local.go
deleted file mode 100644
index 3c693d30..00000000
--- a/internal/deployer/local.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package deployer
-
-import (
- "bytes"
- "context"
- "errors"
- "fmt"
- "os/exec"
- "runtime"
-
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/pkg/utils/fs"
- "github.com/usual2970/certimate/internal/pkg/utils/x509"
-)
-
-type LocalDeployer struct {
- option *DeployerOption
- infos []string
-}
-
-const (
- certFormatPEM = "pem"
- certFormatPFX = "pfx"
- certFormatJKS = "jks"
-)
-
-const (
- shellEnvSh = "sh"
- shellEnvCmd = "cmd"
- shellEnvPowershell = "powershell"
-)
-
-func NewLocalDeployer(option *DeployerOption) (Deployer, error) {
- return &LocalDeployer{
- option: option,
- infos: make([]string, 0),
- }, nil
-}
-
-func (d *LocalDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *LocalDeployer) GetInfos() []string {
- return []string{}
-}
-
-func (d *LocalDeployer) Deploy(ctx context.Context) error {
- // 执行前置命令
- preCommand := d.option.DeployConfig.GetConfigAsString("preCommand")
- if preCommand != "" {
- stdout, stderr, err := d.execCommand(preCommand)
- if err != nil {
- return xerrors.Wrapf(err, "failed to run pre-command, stdout: %s, stderr: %s", stdout, stderr)
- }
-
- d.infos = append(d.infos, toStr("执行前置命令成功", stdout))
- }
-
- // 写入证书和私钥文件
- switch d.option.DeployConfig.GetConfigOrDefaultAsString("format", certFormatPEM) {
- case certFormatPEM:
- if err := fs.WriteFileString(d.option.DeployConfig.GetConfigAsString("certPath"), d.option.Certificate.Certificate); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("保存证书成功", nil))
-
- if err := fs.WriteFileString(d.option.DeployConfig.GetConfigAsString("keyPath"), d.option.Certificate.PrivateKey); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("保存私钥成功", nil))
-
- case certFormatPFX:
- pfxData, err := x509.TransformCertificateFromPEMToPFX(
- d.option.Certificate.Certificate,
- d.option.Certificate.PrivateKey,
- d.option.DeployConfig.GetConfigAsString("pfxPassword"),
- )
- if err != nil {
- return err
- }
-
- if err := fs.WriteFile(d.option.DeployConfig.GetConfigAsString("certPath"), pfxData); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("保存证书成功", nil))
-
- case certFormatJKS:
- jksData, err := x509.TransformCertificateFromPEMToJKS(
- d.option.Certificate.Certificate,
- d.option.Certificate.PrivateKey,
- d.option.DeployConfig.GetConfigAsString("jksAlias"),
- d.option.DeployConfig.GetConfigAsString("jksKeypass"),
- d.option.DeployConfig.GetConfigAsString("jksStorepass"),
- )
- if err != nil {
- return err
- }
-
- if err := fs.WriteFile(d.option.DeployConfig.GetConfigAsString("certPath"), jksData); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("保存证书成功", nil))
-
- default:
- return errors.New("unsupported format")
- }
-
- // 执行命令
- command := d.option.DeployConfig.GetConfigAsString("command")
- if command != "" {
- stdout, stderr, err := d.execCommand(command)
- if err != nil {
- return xerrors.Wrapf(err, "failed to run command, stdout: %s, stderr: %s", stdout, stderr)
- }
-
- d.infos = append(d.infos, toStr("执行命令成功", stdout))
- }
-
- return nil
-}
-
-func (d *LocalDeployer) execCommand(command string) (string, string, error) {
- var cmd *exec.Cmd
-
- switch d.option.DeployConfig.GetConfigAsString("shell") {
- case shellEnvSh:
- cmd = exec.Command("sh", "-c", command)
-
- case shellEnvCmd:
- cmd = exec.Command("cmd", "/C", command)
-
- case shellEnvPowershell:
- cmd = exec.Command("powershell", "-Command", command)
-
- case "":
- if runtime.GOOS == "windows" {
- cmd = exec.Command("cmd", "/C", command)
- } else {
- cmd = exec.Command("sh", "-c", command)
- }
-
- default:
- return "", "", errors.New("unsupported shell")
- }
-
- var stdoutBuf bytes.Buffer
- cmd.Stdout = &stdoutBuf
- var stderrBuf bytes.Buffer
- cmd.Stderr = &stderrBuf
-
- err := cmd.Run()
- if err != nil {
- return "", "", xerrors.Wrap(err, "failed to execute shell script")
- }
-
- return stdoutBuf.String(), stderrBuf.String(), nil
-}
diff --git a/internal/deployer/qiniu_cdn.go b/internal/deployer/qiniu_cdn.go
deleted file mode 100644
index bc638af9..00000000
--- a/internal/deployer/qiniu_cdn.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- xerrors "github.com/pkg/errors"
- "github.com/qiniu/go-sdk/v7/auth"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderQiniu "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/qiniu-sslcert"
- qiniuEx "github.com/usual2970/certimate/internal/pkg/vendors/qiniu-sdk"
-)
-
-type QiniuCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *qiniuEx.Client
- sslUploader uploader.Uploader
-}
-
-func NewQiniuCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.QiniuAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&QiniuCDNDeployer{}).createSdkClient(
- access.AccessKey,
- access.SecretKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk client")
- }
-
- uploader, err := uploaderQiniu.New(&uploaderQiniu.QiniuSSLCertUploaderConfig{
- AccessKey: access.AccessKey,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &QiniuCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *QiniuCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *QiniuCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *QiniuCDNDeployer) Deploy(ctx context.Context) error {
- // 上传证书
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 在七牛 CDN 中泛域名表示为 .example.com,需去除前缀星号
- domain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(domain, "*") {
- domain = strings.TrimPrefix(domain, "*")
- }
-
- // 获取域名信息
- // REF: https://developer.qiniu.com/fusion/4246/the-domain-name
- getDomainInfoResp, err := d.sdkClient.GetDomainInfo(domain)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.GetDomainInfo'")
- }
-
- d.infos = append(d.infos, toStr("已获取域名信息", getDomainInfoResp))
-
- // 判断域名是否已启用 HTTPS。如果已启用,修改域名证书;否则,启用 HTTPS
- // REF: https://developer.qiniu.com/fusion/4246/the-domain-name
- if getDomainInfoResp.Https != nil && getDomainInfoResp.Https.CertID != "" {
- modifyDomainHttpsConfResp, err := d.sdkClient.ModifyDomainHttpsConf(domain, upres.CertId, getDomainInfoResp.Https.ForceHttps, getDomainInfoResp.Https.Http2Enable)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.ModifyDomainHttpsConf'")
- }
-
- d.infos = append(d.infos, toStr("已修改域名证书", modifyDomainHttpsConfResp))
- } else {
- enableDomainHttpsResp, err := d.sdkClient.EnableDomainHttps(domain, upres.CertId, true, true)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.EnableDomainHttps'")
- }
-
- d.infos = append(d.infos, toStr("已将域名升级为 HTTPS", enableDomainHttpsResp))
- }
-
- return nil
-}
-
-func (u *QiniuCDNDeployer) createSdkClient(accessKey, secretKey string) (*qiniuEx.Client, error) {
- credential := auth.New(accessKey, secretKey)
- client := qiniuEx.NewClient(credential)
- return client, nil
-}
diff --git a/internal/deployer/ssh.go b/internal/deployer/ssh.go
deleted file mode 100644
index 96f8bdd2..00000000
--- a/internal/deployer/ssh.go
+++ /dev/null
@@ -1,209 +0,0 @@
-package deployer
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "os"
- "path/filepath"
-
- xerrors "github.com/pkg/errors"
- "github.com/pkg/sftp"
- "golang.org/x/crypto/ssh"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/utils/x509"
-)
-
-type SSHDeployer struct {
- option *DeployerOption
- infos []string
-}
-
-func NewSSHDeployer(option *DeployerOption) (Deployer, error) {
- return &SSHDeployer{
- option: option,
- infos: make([]string, 0),
- }, nil
-}
-
-func (d *SSHDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *SSHDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *SSHDeployer) Deploy(ctx context.Context) error {
- access := &domain.SSHAccess{}
- if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
- return err
- }
-
- // 连接
- client, err := d.createSshClient(access)
- if err != nil {
- return err
- }
- defer client.Close()
-
- d.infos = append(d.infos, toStr("SSH 连接成功", nil))
-
- // 执行前置命令
- preCommand := d.option.DeployConfig.GetConfigAsString("preCommand")
- if preCommand != "" {
- stdout, stderr, err := d.sshExecCommand(client, preCommand)
- if err != nil {
- return xerrors.Wrapf(err, "failed to run pre-command: stdout: %s, stderr: %s", stdout, stderr)
- }
-
- d.infos = append(d.infos, toStr("SSH 执行前置命令成功", stdout))
- }
-
- // 上传证书和私钥文件
- switch d.option.DeployConfig.GetConfigOrDefaultAsString("format", certFormatPEM) {
- case certFormatPEM:
- if err := d.writeSftpFileString(client, d.option.DeployConfig.GetConfigAsString("certPath"), d.option.Certificate.Certificate); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("SSH 上传证书成功", nil))
-
- if err := d.writeSftpFileString(client, d.option.DeployConfig.GetConfigAsString("keyPath"), d.option.Certificate.PrivateKey); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("SSH 上传私钥成功", nil))
-
- case certFormatPFX:
- pfxData, err := x509.TransformCertificateFromPEMToPFX(
- d.option.Certificate.Certificate,
- d.option.Certificate.PrivateKey,
- d.option.DeployConfig.GetConfigAsString("pfxPassword"),
- )
- if err != nil {
- return err
- }
-
- if err := d.writeSftpFile(client, d.option.DeployConfig.GetConfigAsString("certPath"), pfxData); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("SSH 上传证书成功", nil))
-
- case certFormatJKS:
- jksData, err := x509.TransformCertificateFromPEMToJKS(
- d.option.Certificate.Certificate,
- d.option.Certificate.PrivateKey,
- d.option.DeployConfig.GetConfigAsString("jksAlias"),
- d.option.DeployConfig.GetConfigAsString("jksKeypass"),
- d.option.DeployConfig.GetConfigAsString("jksStorepass"),
- )
- if err != nil {
- return err
- }
-
- if err := d.writeSftpFile(client, d.option.DeployConfig.GetConfigAsString("certPath"), jksData); err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("SSH 上传证书成功", nil))
-
- default:
- return errors.New("unsupported format")
- }
-
- // 执行命令
- command := d.option.DeployConfig.GetConfigAsString("command")
- if command != "" {
- stdout, stderr, err := d.sshExecCommand(client, command)
- if err != nil {
- return xerrors.Wrapf(err, "failed to run command, stdout: %s, stderr: %s", stdout, stderr)
- }
-
- d.infos = append(d.infos, toStr("SSH 执行命令成功", stdout))
- }
-
- return nil
-}
-
-func (d *SSHDeployer) createSshClient(access *domain.SSHAccess) (*ssh.Client, error) {
- var authMethod ssh.AuthMethod
-
- if access.Key != "" {
- var signer ssh.Signer
- var err error
-
- if access.KeyPassphrase != "" {
- signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(access.Key), []byte(access.KeyPassphrase))
- } else {
- signer, err = ssh.ParsePrivateKey([]byte(access.Key))
- }
-
- if err != nil {
- return nil, err
- }
- authMethod = ssh.PublicKeys(signer)
- } else {
- authMethod = ssh.Password(access.Password)
- }
-
- return ssh.Dial("tcp", fmt.Sprintf("%s:%s", access.Host, access.Port), &ssh.ClientConfig{
- User: access.Username,
- Auth: []ssh.AuthMethod{
- authMethod,
- },
- HostKeyCallback: ssh.InsecureIgnoreHostKey(),
- })
-}
-
-func (d *SSHDeployer) sshExecCommand(sshCli *ssh.Client, command string) (string, string, error) {
- session, err := sshCli.NewSession()
- if err != nil {
- return "", "", xerrors.Wrap(err, "failed to create ssh session")
- }
-
- defer session.Close()
- var stdoutBuf bytes.Buffer
- session.Stdout = &stdoutBuf
- var stderrBuf bytes.Buffer
- session.Stderr = &stderrBuf
- err = session.Run(command)
- if err != nil {
- return "", "", xerrors.Wrap(err, "failed to execute ssh script")
- }
-
- return stdoutBuf.String(), stderrBuf.String(), nil
-}
-
-func (d *SSHDeployer) writeSftpFileString(sshCli *ssh.Client, path string, content string) error {
- return d.writeSftpFile(sshCli, path, []byte(content))
-}
-
-func (d *SSHDeployer) writeSftpFile(sshCli *ssh.Client, path string, data []byte) error {
- sftpCli, err := sftp.NewClient(sshCli)
- if err != nil {
- return xerrors.Wrap(err, "failed to create sftp client")
- }
- defer sftpCli.Close()
-
- if err := sftpCli.MkdirAll(filepath.Dir(path)); err != nil {
- return xerrors.Wrap(err, "failed to create remote directory")
- }
-
- file, err := sftpCli.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
- if err != nil {
- return xerrors.Wrap(err, "failed to open remote file")
- }
- defer file.Close()
-
- _, err = file.Write(data)
- if err != nil {
- return xerrors.Wrap(err, "failed to write to remote file")
- }
-
- return nil
-}
diff --git a/internal/deployer/ssh_test.go b/internal/deployer/ssh_test.go
deleted file mode 100644
index c9b1e85a..00000000
--- a/internal/deployer/ssh_test.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package deployer
-
-import (
- "os"
- "path"
- "testing"
-)
-
-func TestPath(t *testing.T) {
- dir := path.Dir("./a/b/c")
- os.MkdirAll(dir, 0o755)
-}
diff --git a/internal/deployer/tencent_cdn.go b/internal/deployer/tencent_cdn.go
deleted file mode 100644
index f5230910..00000000
--- a/internal/deployer/tencent_cdn.go
+++ /dev/null
@@ -1,194 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- xerrors "github.com/pkg/errors"
- tcCdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
- tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
- "golang.org/x/exp/slices"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderTcSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
-)
-
-type TencentCDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClients *tencentCDNDeployerSdkClients
- sslUploader uploader.Uploader
-}
-
-type tencentCDNDeployerSdkClients struct {
- ssl *tcSsl.Client
- cdn *tcCdn.Client
-}
-
-func NewTencentCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.TencentAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- clients, err := (&TencentCDNDeployer{}).createSdkClients(
- access.SecretId,
- access.SecretKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk clients")
- }
-
- uploader, err := uploaderTcSsl.New(&uploaderTcSsl.TencentCloudSSLUploaderConfig{
- SecretId: access.SecretId,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &TencentCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClients: clients,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *TencentCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *TencentCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *TencentCDNDeployer) Deploy(ctx context.Context) error {
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 获取待部署的 CDN 实例
- // 如果是泛域名,根据证书匹配 CDN 实例
- tcInstanceIds := make([]string, 0)
- domain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(domain, "*") {
- domains, err := d.getDomainsByCertificateId(upres.CertId)
- if err != nil {
- return err
- }
-
- tcInstanceIds = domains
- } else {
- tcInstanceIds = append(tcInstanceIds, domain)
- }
-
- // 跳过已部署的 CDN 实例
- if len(tcInstanceIds) > 0 {
- deployedDomains, err := d.getDeployedDomainsByCertificateId(upres.CertId)
- if err != nil {
- return err
- }
-
- temp := make([]string, 0)
- for _, tcInstanceId := range tcInstanceIds {
- if !slices.Contains(deployedDomains, tcInstanceId) {
- temp = append(temp, tcInstanceId)
- }
- }
- tcInstanceIds = temp
- }
- if len(tcInstanceIds) == 0 {
- d.infos = append(d.infos, "已部署过或没有要部署的 CDN 实例")
- return nil
- }
-
- // 证书部署到 CDN 实例
- // REF: https://cloud.tencent.com/document/product/400/91667
- deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest()
- deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
- deployCertificateInstanceReq.ResourceType = common.StringPtr("cdn")
- deployCertificateInstanceReq.Status = common.Int64Ptr(1)
- deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(tcInstanceIds)
- deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
- }
-
- d.infos = append(d.infos, toStr("已部署证书到云资源实例", deployCertificateInstanceResp.Response))
-
- return nil
-}
-
-func (d *TencentCDNDeployer) createSdkClients(secretId, secretKey string) (*tencentCDNDeployerSdkClients, error) {
- credential := common.NewCredential(secretId, secretKey)
-
- sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- cdnClient, err := tcCdn.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- return &tencentCDNDeployerSdkClients{
- ssl: sslClient,
- cdn: cdnClient,
- }, nil
-}
-
-func (d *TencentCDNDeployer) getDomainsByCertificateId(tcCertId string) ([]string, error) {
- // 获取证书中的可用域名
- // REF: https://cloud.tencent.com/document/product/228/42491
- describeCertDomainsReq := tcCdn.NewDescribeCertDomainsRequest()
- describeCertDomainsReq.CertId = common.StringPtr(tcCertId)
- describeCertDomainsReq.Product = common.StringPtr("cdn")
- describeCertDomainsResp, err := d.sdkClients.cdn.DescribeCertDomains(describeCertDomainsReq)
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'")
- }
-
- domains := make([]string, 0)
- if describeCertDomainsResp.Response.Domains == nil {
- for _, domain := range describeCertDomainsResp.Response.Domains {
- domains = append(domains, *domain)
- }
- }
-
- return domains, nil
-}
-
-func (d *TencentCDNDeployer) getDeployedDomainsByCertificateId(tcCertId string) ([]string, error) {
- // 根据证书查询关联 CDN 域名
- // REF: https://cloud.tencent.com/document/product/400/62674
- describeDeployedResourcesReq := tcSsl.NewDescribeDeployedResourcesRequest()
- describeDeployedResourcesReq.CertificateIds = common.StringPtrs([]string{tcCertId})
- describeDeployedResourcesReq.ResourceType = common.StringPtr("cdn")
- describeDeployedResourcesResp, err := d.sdkClients.ssl.DescribeDeployedResources(describeDeployedResourcesReq)
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeDeployedResources'")
- }
-
- domains := make([]string, 0)
- if describeDeployedResourcesResp.Response.DeployedResources != nil {
- for _, deployedResource := range describeDeployedResourcesResp.Response.DeployedResources {
- for _, resource := range deployedResource.Resources {
- domains = append(domains, *resource)
- }
- }
- }
-
- return domains, nil
-}
diff --git a/internal/deployer/tencent_clb.go b/internal/deployer/tencent_clb.go
deleted file mode 100644
index c3feefc7..00000000
--- a/internal/deployer/tencent_clb.go
+++ /dev/null
@@ -1,328 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
-
- xerrors "github.com/pkg/errors"
- tcClb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
- tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderTcSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
-)
-
-type TencentCLBDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClients *tencentCLBDeployerSdkClients
- sslUploader uploader.Uploader
-}
-
-type tencentCLBDeployerSdkClients struct {
- ssl *tcSsl.Client
- clb *tcClb.Client
-}
-
-func NewTencentCLBDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.TencentAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- clients, err := (&TencentCLBDeployer{}).createSdkClients(
- access.SecretId,
- access.SecretKey,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk clients")
- }
-
- uploader, err := uploaderTcSsl.New(&uploaderTcSsl.TencentCloudSSLUploaderConfig{
- SecretId: access.SecretId,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &TencentCLBDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClients: clients,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *TencentCLBDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *TencentCLBDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *TencentCLBDeployer) Deploy(ctx context.Context) error {
- switch d.option.DeployConfig.GetConfigAsString("resourceType") {
- case "ssl-deploy":
- // 通过 SSL 服务部署到云资源实例
- err := d.deployToInstanceUseSsl(ctx)
- if err != nil {
- return err
- }
- case "loadbalancer":
- // 部署到指定负载均衡器
- if err := d.deployToLoadbalancer(ctx); err != nil {
- return err
- }
- case "listener":
- // 部署到指定监听器
- if err := d.deployToListener(ctx); err != nil {
- return err
- }
- case "ruledomain":
- // 部署到指定七层监听转发规则域名
- if err := d.deployToRuleDomain(ctx); err != nil {
- return err
- }
- default:
- return errors.New("unsupported resource type")
- }
-
- return nil
-}
-
-func (d *TencentCLBDeployer) createSdkClients(secretId, secretKey, region string) (*tencentCLBDeployerSdkClients, error) {
- credential := common.NewCredential(secretId, secretKey)
-
- sslClient, err := tcSsl.NewClient(credential, region, profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- clbClient, err := tcClb.NewClient(credential, region, profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- return &tencentCLBDeployerSdkClients{
- ssl: sslClient,
- clb: clbClient,
- }, nil
-}
-
-func (d *TencentCLBDeployer) deployToInstanceUseSsl(ctx context.Context) error {
- tcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- tcListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- tcDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if tcLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
- if tcListenerId == "" {
- return errors.New("`listenerId` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 证书部署到 CLB 实例
- // REF: https://cloud.tencent.com/document/product/400/91667
- deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest()
- deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
- deployCertificateInstanceReq.ResourceType = common.StringPtr("clb")
- deployCertificateInstanceReq.Status = common.Int64Ptr(1)
- if tcDomain == "" {
- // 未开启 SNI,只需指定到监听器
- deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s|%s", tcLoadbalancerId, tcListenerId)})
- } else {
- // 开启 SNI,需指定到域名(支持泛域名)
- deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s|%s|%s", tcLoadbalancerId, tcListenerId, tcDomain)})
- }
- deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
- }
-
- d.infos = append(d.infos, toStr("已部署证书到云资源实例", deployCertificateInstanceResp.Response))
-
- return nil
-}
-
-func (d *TencentCLBDeployer) deployToLoadbalancer(ctx context.Context) error {
- tcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- tcListenerIds := make([]string, 0)
- if tcLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
-
- // 查询负载均衡器详细信息
- // REF: https://cloud.tencent.com/document/api/214/46916
- describeLoadBalancersDetailReq := tcClb.NewDescribeLoadBalancersDetailRequest()
- describeLoadBalancersDetailResp, err := d.sdkClients.clb.DescribeLoadBalancersDetail(describeLoadBalancersDetailReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeLoadBalancersDetail'")
- }
-
- d.infos = append(d.infos, toStr("已查询到负载均衡详细信息", describeLoadBalancersDetailResp))
-
- // 查询监听器列表
- // REF: https://cloud.tencent.com/document/api/214/30686
- describeListenersReq := tcClb.NewDescribeListenersRequest()
- describeListenersReq.LoadBalancerId = common.StringPtr(tcLoadbalancerId)
- describeListenersResp, err := d.sdkClients.clb.DescribeListeners(describeListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'")
- } else {
- if describeListenersResp.Response.Listeners != nil {
- for _, listener := range describeListenersResp.Response.Listeners {
- if listener.Protocol == nil || (*listener.Protocol != "HTTPS" && *listener.Protocol != "TCP_SSL" && *listener.Protocol != "QUIC") {
- continue
- }
-
- tcListenerIds = append(tcListenerIds, *listener.ListenerId)
- }
- }
- }
-
- d.infos = append(d.infos, toStr("已查询到负载均衡器下的监听器", tcListenerIds))
-
- // 上传证书到 SCM
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 批量更新监听器证书
- var errs []error
- for _, tcListenerId := range tcListenerIds {
- if err := d.modifyListenerCertificate(ctx, tcLoadbalancerId, tcListenerId, upres.CertId); err != nil {
- errs = append(errs, err)
- }
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
-
- return nil
-}
-
-func (d *TencentCLBDeployer) deployToListener(ctx context.Context) error {
- tcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- tcListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- if tcLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
- if tcListenerId == "" {
- return errors.New("`listenerId` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 更新监听器证书
- if err := d.modifyListenerCertificate(ctx, tcLoadbalancerId, tcListenerId, upres.CertId); err != nil {
- return err
- }
-
- return nil
-}
-
-func (d *TencentCLBDeployer) deployToRuleDomain(ctx context.Context) error {
- tcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
- tcListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
- tcDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if tcLoadbalancerId == "" {
- return errors.New("`loadbalancerId` is required")
- }
- if tcListenerId == "" {
- return errors.New("`listenerId` is required")
- }
- if tcDomain == "" {
- return errors.New("`domain` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 修改负载均衡七层监听器转发规则的域名级别属性
- // REF: https://cloud.tencent.com/document/api/214/38092
- modifyDomainAttributesReq := tcClb.NewModifyDomainAttributesRequest()
- modifyDomainAttributesReq.LoadBalancerId = common.StringPtr(tcLoadbalancerId)
- modifyDomainAttributesReq.ListenerId = common.StringPtr(tcListenerId)
- modifyDomainAttributesReq.Domain = common.StringPtr(tcDomain)
- modifyDomainAttributesReq.Certificate = &tcClb.CertificateInput{
- SSLMode: common.StringPtr("UNIDIRECTIONAL"),
- CertId: common.StringPtr(upres.CertId),
- }
- modifyDomainAttributesResp, err := d.sdkClients.clb.ModifyDomainAttributes(modifyDomainAttributesReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyDomainAttributes'")
- }
-
- d.infos = append(d.infos, toStr("已修改七层监听器转发规则的域名级别属性", modifyDomainAttributesResp.Response))
-
- return nil
-}
-
-func (d *TencentCLBDeployer) modifyListenerCertificate(ctx context.Context, tcLoadbalancerId, tcListenerId, tcCertId string) error {
- // 查询监听器列表
- // REF: https://cloud.tencent.com/document/api/214/30686
- describeListenersReq := tcClb.NewDescribeListenersRequest()
- describeListenersReq.LoadBalancerId = common.StringPtr(tcLoadbalancerId)
- describeListenersReq.ListenerIds = common.StringPtrs([]string{tcListenerId})
- describeListenersResp, err := d.sdkClients.clb.DescribeListeners(describeListenersReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'")
- }
- if len(describeListenersResp.Response.Listeners) == 0 {
- d.infos = append(d.infos, toStr("未找到监听器", nil))
- return errors.New("listener not found")
- }
-
- d.infos = append(d.infos, toStr("已查询到监听器属性", describeListenersResp.Response))
-
- // 修改监听器属性
- // REF: https://cloud.tencent.com/document/product/214/30681
- modifyListenerReq := tcClb.NewModifyListenerRequest()
- modifyListenerReq.LoadBalancerId = common.StringPtr(tcLoadbalancerId)
- modifyListenerReq.ListenerId = common.StringPtr(tcListenerId)
- modifyListenerReq.Certificate = &tcClb.CertificateInput{CertId: common.StringPtr(tcCertId)}
- if describeListenersResp.Response.Listeners[0].Certificate != nil && describeListenersResp.Response.Listeners[0].Certificate.SSLMode != nil {
- modifyListenerReq.Certificate.SSLMode = describeListenersResp.Response.Listeners[0].Certificate.SSLMode
- modifyListenerReq.Certificate.CertCaId = describeListenersResp.Response.Listeners[0].Certificate.CertCaId
- } else {
- modifyListenerReq.Certificate.SSLMode = common.StringPtr("UNIDIRECTIONAL")
- }
- modifyListenerResp, err := d.sdkClients.clb.ModifyListener(modifyListenerReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyListener'")
- }
-
- d.infos = append(d.infos, toStr("已修改监听器属性", modifyListenerResp.Response))
-
- return nil
-}
diff --git a/internal/deployer/tencent_cos.go b/internal/deployer/tencent_cos.go
deleted file mode 100644
index bfcd7b7d..00000000
--- a/internal/deployer/tencent_cos.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
-
- xerrors "github.com/pkg/errors"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
- tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderTcSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
-)
-
-type TencentCOSDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClient *tcSsl.Client
- sslUploader uploader.Uploader
-}
-
-func NewTencentCOSDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.TencentAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- client, err := (&TencentCOSDeployer{}).createSdkClient(
- access.SecretId,
- access.SecretKey,
- option.DeployConfig.GetConfigAsString("region"),
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk clients")
- }
-
- uploader, err := uploaderTcSsl.New(&uploaderTcSsl.TencentCloudSSLUploaderConfig{
- SecretId: access.SecretId,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &TencentCOSDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *TencentCOSDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *TencentCOSDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *TencentCOSDeployer) Deploy(ctx context.Context) error {
- tcRegion := d.option.DeployConfig.GetConfigAsString("region")
- tcBucket := d.option.DeployConfig.GetConfigAsString("bucket")
- tcDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if tcBucket == "" {
- return errors.New("`bucket` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 证书部署到 COS 实例
- // REF: https://cloud.tencent.com/document/product/400/91667
- deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest()
- deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
- deployCertificateInstanceReq.ResourceType = common.StringPtr("cos")
- deployCertificateInstanceReq.Status = common.Int64Ptr(1)
- deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s#%s#%s", tcRegion, tcBucket, tcDomain)})
- deployCertificateInstanceResp, err := d.sdkClient.DeployCertificateInstance(deployCertificateInstanceReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
- }
-
- d.infos = append(d.infos, toStr("已部署证书到云资源实例", deployCertificateInstanceResp.Response))
-
- return nil
-}
-
-func (d *TencentCOSDeployer) createSdkClient(secretId, secretKey, region string) (*tcSsl.Client, error) {
- credential := common.NewCredential(secretId, secretKey)
- client, err := tcSsl.NewClient(credential, region, profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
diff --git a/internal/deployer/tencent_ecdn.go b/internal/deployer/tencent_ecdn.go
deleted file mode 100644
index a61c5680..00000000
--- a/internal/deployer/tencent_ecdn.go
+++ /dev/null
@@ -1,154 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- xerrors "github.com/pkg/errors"
- tcCdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
- tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderTcSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
-)
-
-type TencentECDNDeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClients *tencentECDNDeployerSdkClients
- sslUploader uploader.Uploader
-}
-
-type tencentECDNDeployerSdkClients struct {
- ssl *tcSsl.Client
- cdn *tcCdn.Client
-}
-
-func NewTencentECDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.TencentAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- clients, err := (&TencentECDNDeployer{}).createSdkClients(
- access.SecretId,
- access.SecretKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk clients")
- }
-
- uploader, err := uploaderTcSsl.New(&uploaderTcSsl.TencentCloudSSLUploaderConfig{
- SecretId: access.SecretId,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &TencentECDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClients: clients,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *TencentECDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *TencentECDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *TencentECDNDeployer) Deploy(ctx context.Context) error {
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 获取待部署的 ECDN 实例
- // 如果是泛域名,根据证书匹配 ECDN 实例
- aliInstanceIds := make([]string, 0)
- domain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(domain, "*") {
- domains, err := d.getDomainsByCertificateId(upres.CertId)
- if err != nil {
- return err
- }
-
- aliInstanceIds = domains
- } else {
- aliInstanceIds = append(aliInstanceIds, domain)
- }
- if len(aliInstanceIds) == 0 {
- d.infos = append(d.infos, "没有要部署的 ECDN 实例")
- return nil
- }
-
- // 证书部署到 ECDN 实例
- // REF: https://cloud.tencent.com/document/product/400/91667
- deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest()
- deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
- deployCertificateInstanceReq.ResourceType = common.StringPtr("ecdn")
- deployCertificateInstanceReq.Status = common.Int64Ptr(1)
- deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(aliInstanceIds)
- deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
- }
-
- d.infos = append(d.infos, toStr("已部署证书到云资源实例", deployCertificateInstanceResp.Response))
-
- return nil
-}
-
-func (d *TencentECDNDeployer) createSdkClients(secretId, secretKey string) (*tencentECDNDeployerSdkClients, error) {
- credential := common.NewCredential(secretId, secretKey)
-
- sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- cdnClient, err := tcCdn.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- return &tencentECDNDeployerSdkClients{
- ssl: sslClient,
- cdn: cdnClient,
- }, nil
-}
-
-func (d *TencentECDNDeployer) getDomainsByCertificateId(tcCertId string) ([]string, error) {
- // 获取证书中的可用域名
- // REF: https://cloud.tencent.com/document/product/228/42491
- describeCertDomainsReq := tcCdn.NewDescribeCertDomainsRequest()
- describeCertDomainsReq.CertId = common.StringPtr(tcCertId)
- describeCertDomainsReq.Product = common.StringPtr("ecdn")
- describeCertDomainsResp, err := d.sdkClients.cdn.DescribeCertDomains(describeCertDomainsReq)
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'")
- }
-
- domains := make([]string, 0)
- if describeCertDomainsResp.Response.Domains == nil {
- for _, domain := range describeCertDomainsResp.Response.Domains {
- domains = append(domains, *domain)
- }
- }
-
- return domains, nil
-}
diff --git a/internal/deployer/tencent_teo.go b/internal/deployer/tencent_teo.go
deleted file mode 100644
index 583089dd..00000000
--- a/internal/deployer/tencent_teo.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- xerrors "github.com/pkg/errors"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
- "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
- tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
- tcTeo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
-
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- uploaderTcSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
-)
-
-type TencentTEODeployer struct {
- option *DeployerOption
- infos []string
-
- sdkClients *tencentTEODeployerSdkClients
- sslUploader uploader.Uploader
-}
-
-type tencentTEODeployerSdkClients struct {
- ssl *tcSsl.Client
- teo *tcTeo.Client
-}
-
-func NewTencentTEODeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.TencentAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
-
- clients, err := (&TencentTEODeployer{}).createSdkClients(
- access.SecretId,
- access.SecretKey,
- )
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create sdk clients")
- }
-
- uploader, err := uploaderTcSsl.New(&uploaderTcSsl.TencentCloudSSLUploaderConfig{
- SecretId: access.SecretId,
- SecretKey: access.SecretKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
-
- return &TencentTEODeployer{
- option: option,
- infos: make([]string, 0),
- sdkClients: clients,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *TencentTEODeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *TencentTEODeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *TencentTEODeployer) Deploy(ctx context.Context) error {
- tcZoneId := d.option.DeployConfig.GetConfigAsString("zoneId")
- if tcZoneId == "" {
- return xerrors.New("`zoneId` is required")
- }
-
- // 上传证书到 SSL
- upres, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- // 配置域名证书
- // REF: https://cloud.tencent.com/document/product/1552/80764
- modifyHostsCertificateReq := tcTeo.NewModifyHostsCertificateRequest()
- modifyHostsCertificateReq.ZoneId = common.StringPtr(tcZoneId)
- modifyHostsCertificateReq.Mode = common.StringPtr("sslcert")
- modifyHostsCertificateReq.Hosts = common.StringPtrs(strings.Split(strings.ReplaceAll(d.option.Domain, "\r\n", "\n"), "\n"))
- modifyHostsCertificateReq.ServerCertInfo = []*tcTeo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}}
- modifyHostsCertificateResp, err := d.sdkClients.teo.ModifyHostsCertificate(modifyHostsCertificateReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'teo.ModifyHostsCertificate'")
- }
-
- d.infos = append(d.infos, toStr("已配置域名证书", modifyHostsCertificateResp.Response))
-
- return nil
-}
-
-func (d *TencentTEODeployer) createSdkClients(secretId, secretKey string) (*tencentTEODeployerSdkClients, error) {
- credential := common.NewCredential(secretId, secretKey)
-
- sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- teoClient, err := tcTeo.NewClient(credential, "", profile.NewClientProfile())
- if err != nil {
- return nil, err
- }
-
- return &tencentTEODeployerSdkClients{
- ssl: sslClient,
- teo: teoClient,
- }, nil
-}
diff --git a/internal/deployer/volcengine_cdn.go b/internal/deployer/volcengine_cdn.go
deleted file mode 100644
index 6ba8a23d..00000000
--- a/internal/deployer/volcengine_cdn.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- volcenginecdn "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/volcengine-cdn"
-
- xerrors "github.com/pkg/errors"
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- "github.com/volcengine/volc-sdk-golang/service/cdn"
-)
-
-type VolcengineCDNDeployer struct {
- option *DeployerOption
- infos []string
- sdkClient *cdn.CDN
- sslUploader uploader.Uploader
-}
-
-func NewVolcengineCDNDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.VolcEngineAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
- client := cdn.NewInstance()
- client.Client.SetAccessKey(access.AccessKeyId)
- client.Client.SetSecretKey(access.SecretAccessKey)
- uploader, err := volcenginecdn.New(&volcenginecdn.VolcEngineCDNUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- AccessKeySecret: access.SecretAccessKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
- return &VolcengineCDNDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *VolcengineCDNDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *VolcengineCDNDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *VolcengineCDNDeployer) Deploy(ctx context.Context) error {
- apiCtx := context.Background()
- // 上传证书
- upres, err := d.sslUploader.Upload(apiCtx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- domains := make([]string, 0)
- configDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(configDomain, "*.") {
- // 获取证书可以部署的域名
- // REF: https://www.volcengine.com/docs/6454/125711
- describeCertConfigReq := &cdn.DescribeCertConfigRequest{
- CertId: upres.CertId,
- }
- describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertConfig'")
- }
- for i := range describeCertConfigResp.Result.CertNotConfig {
- // 当前未启用 HTTPS 的加速域名列表。
- domains = append(domains, describeCertConfigResp.Result.CertNotConfig[i].Domain)
- }
- for i := range describeCertConfigResp.Result.OtherCertConfig {
- // 已启用了 HTTPS 的加速域名列表。这些加速域名关联的证书不是您指定的证书。
- domains = append(domains, describeCertConfigResp.Result.OtherCertConfig[i].Domain)
- }
- for i := range describeCertConfigResp.Result.SpecifiedCertConfig {
- // 已启用了 HTTPS 的加速域名列表。这些加速域名关联了您指定的证书。
- d.infos = append(d.infos, fmt.Sprintf("%s域名已配置该证书", describeCertConfigResp.Result.SpecifiedCertConfig[i].Domain))
- }
- if len(domains) == 0 {
- if len(describeCertConfigResp.Result.SpecifiedCertConfig) > 0 {
- // 所有匹配的域名都配置了该证书,跳过部署
- return nil
- } else {
- return xerrors.Errorf("未查询到匹配的域名: %s", configDomain)
- }
- }
- } else {
- domains = append(domains, configDomain)
- }
- // 部署证书
- // REF: https://www.volcengine.com/docs/6454/125712
- for i := range domains {
- batchDeployCertReq := &cdn.BatchDeployCertRequest{
- CertId: upres.CertId,
- Domain: domains[i],
- }
- batchDeployCertResp, err := d.sdkClient.BatchDeployCert(batchDeployCertReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'cdn.BatchDeployCert'")
- } else {
- d.infos = append(d.infos, toStr(fmt.Sprintf("%s域名的证书已修改", domains[i]), batchDeployCertResp))
- }
- }
-
- return nil
-}
diff --git a/internal/deployer/volcengine_live.go b/internal/deployer/volcengine_live.go
deleted file mode 100644
index 1795d79f..00000000
--- a/internal/deployer/volcengine_live.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package deployer
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "regexp"
- "strings"
-
- xerrors "github.com/pkg/errors"
- "github.com/usual2970/certimate/internal/domain"
- "github.com/usual2970/certimate/internal/pkg/core/uploader"
- volcenginelive "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/volcengine-live"
- "github.com/usual2970/certimate/internal/pkg/utils/cast"
- "github.com/volcengine/volc-sdk-golang/base"
- live "github.com/volcengine/volc-sdk-golang/service/live/v20230101"
-)
-
-type VolcengineLiveDeployer struct {
- option *DeployerOption
- infos []string
- sdkClient *live.Live
- sslUploader uploader.Uploader
-}
-
-func NewVolcengineLiveDeployer(option *DeployerOption) (Deployer, error) {
- access := &domain.VolcEngineAccess{}
- if err := json.Unmarshal([]byte(option.Access), access); err != nil {
- return nil, xerrors.Wrap(err, "failed to get access")
- }
- client := live.NewInstance()
- client.SetCredential(base.Credentials{
- AccessKeyID: access.AccessKeyId,
- SecretAccessKey: access.SecretAccessKey,
- })
- uploader, err := volcenginelive.New(&volcenginelive.VolcEngineLiveUploaderConfig{
- AccessKeyId: access.AccessKeyId,
- AccessKeySecret: access.SecretAccessKey,
- })
- if err != nil {
- return nil, xerrors.Wrap(err, "failed to create ssl uploader")
- }
- return &VolcengineLiveDeployer{
- option: option,
- infos: make([]string, 0),
- sdkClient: client,
- sslUploader: uploader,
- }, nil
-}
-
-func (d *VolcengineLiveDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *VolcengineLiveDeployer) GetInfos() []string {
- return d.infos
-}
-
-func (d *VolcengineLiveDeployer) Deploy(ctx context.Context) error {
- apiCtx := context.Background()
- // 上传证书
- upres, err := d.sslUploader.Upload(apiCtx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
- if err != nil {
- return err
- }
-
- d.infos = append(d.infos, toStr("已上传证书", upres))
-
- domains := make([]string, 0)
- configDomain := d.option.DeployConfig.GetConfigAsString("domain")
- if strings.HasPrefix(configDomain, "*.") {
- // 如果是泛域名,获取所有的域名并匹配
- matchDomains, err := d.getDomainsByWildcardDomain(apiCtx, configDomain)
- if err != nil {
- d.infos = append(d.infos, toStr("获取域名列表失败", upres))
- return xerrors.Wrap(err, "failed to execute sdk request 'live.ListDomainDetail'")
- }
- if len(matchDomains) == 0 {
- return xerrors.Errorf("未查询到匹配的域名: %s", configDomain)
- }
- domains = matchDomains
- } else {
- domains = append(domains, configDomain)
- }
-
- // 部署证书
- // REF: https://www.volcengine.com/docs/6469/1186278#%E7%BB%91%E5%AE%9A%E8%AF%81%E4%B9%A6d
- for i := range domains {
- bindCertReq := &live.BindCertBody{
- ChainID: upres.CertId,
- Domain: domains[i],
- HTTPS: cast.BoolPtr(true),
- }
- bindCertResp, err := d.sdkClient.BindCert(apiCtx, bindCertReq)
- if err != nil {
- return xerrors.Wrap(err, "failed to execute sdk request 'live.BindCert'")
- } else {
- d.infos = append(d.infos, toStr(fmt.Sprintf("%s域名的证书已修改", domains[i]), bindCertResp))
- }
- }
-
- return nil
-}
-
-func (d *VolcengineLiveDeployer) getDomainsByWildcardDomain(ctx context.Context, wildcardDomain string) ([]string, error) {
- pageNum := int32(1)
- searchTotal := 0
- domains := make([]string, 0)
- for {
- listDomainDetailReq := &live.ListDomainDetailBody{
- PageNum: pageNum,
- PageSize: 1000,
- }
- // 查询域名列表
- // REF: https://www.volcengine.com/docs/6469/1186277#%E6%9F%A5%E8%AF%A2%E5%9F%9F%E5%90%8D%E5%88%97%E8%A1%A8
- listDomainDetailResp, err := d.sdkClient.ListDomainDetail(ctx, listDomainDetailReq)
- if err != nil {
- return domains, err
- }
- if listDomainDetailResp.Result.DomainList != nil {
- for _, item := range listDomainDetailResp.Result.DomainList {
- if matchWildcardDomain(item.Domain, wildcardDomain) {
- domains = append(domains, item.Domain)
- }
- }
- }
- searchTotal += len(listDomainDetailResp.Result.DomainList)
- if int(listDomainDetailResp.Result.Total) > searchTotal {
- pageNum++
- } else {
- break
- }
- }
-
- return domains, nil
-}
-
-func matchWildcardDomain(domain, wildcardDomain string) bool {
- if strings.HasPrefix(wildcardDomain, "*.") {
- if "*."+domain == wildcardDomain {
- return true
- }
- regexPattern := "^([a-zA-Z0-9_-]+)\\." + regexp.QuoteMeta(wildcardDomain[2:]) + "$"
- regex := regexp.MustCompile(regexPattern)
- return regex.MatchString(domain)
- }
- return domain == wildcardDomain
-}
diff --git a/internal/deployer/webhook.go b/internal/deployer/webhook.go
deleted file mode 100644
index 35c37235..00000000
--- a/internal/deployer/webhook.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package deployer
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "net/http"
-
- xerrors "github.com/pkg/errors"
-
- "github.com/usual2970/certimate/internal/domain"
- xhttp "github.com/usual2970/certimate/internal/utils/http"
-)
-
-type WebhookDeployer struct {
- option *DeployerOption
- infos []string
-}
-
-func NewWebhookDeployer(option *DeployerOption) (Deployer, error) {
- return &WebhookDeployer{
- option: option,
- infos: make([]string, 0),
- }, nil
-}
-
-func (d *WebhookDeployer) GetID() string {
- return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
-}
-
-func (d *WebhookDeployer) GetInfos() []string {
- return d.infos
-}
-
-type webhookData struct {
- Domain string `json:"domain"`
- Certificate string `json:"certificate"`
- PrivateKey string `json:"privateKey"`
- Variables map[string]string `json:"variables"`
-}
-
-func (d *WebhookDeployer) Deploy(ctx context.Context) error {
- access := &domain.WebhookAccess{}
- if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
- return xerrors.Wrap(err, "failed to get access")
- }
-
- data := &webhookData{
- Domain: d.option.Domain,
- Certificate: d.option.Certificate.Certificate,
- PrivateKey: d.option.Certificate.PrivateKey,
- Variables: d.option.DeployConfig.GetConfigAsVariables(),
- }
- body, _ := json.Marshal(data)
- resp, err := xhttp.Req(access.Url, http.MethodPost, bytes.NewReader(body), map[string]string{
- "Content-Type": "application/json",
- })
- if err != nil {
- return xerrors.Wrap(err, "failed to send webhook request")
- }
-
- d.infos = append(d.infos, toStr("Webhook Response", string(resp)))
-
- return nil
-}