feat(provider): new purge provider: baiducloud cert

This commit is contained in:
Fu Diwei
2026-08-27 17:14:31 +08:00
parent c6e48816d0
commit 38099a79e1
7 changed files with 202 additions and 0 deletions
@@ -0,0 +1,25 @@
package purgers
import (
"fmt"
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/pkg/core"
pgrimpl "github.com/certimate-go/certimate/pkg/core/purger/providers/baiducloud-cert"
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
)
func init() {
Registries.MustRegister(domain.PurgeProviderTypeBaiduCloudCert, func(options *ProviderFactoryOptions) (core.Purger, error) {
credentials := domain.AccessConfigForBaiduCloud{}
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
provider, err := pgrimpl.NewPurger(&pgrimpl.PurgerConfig{
AccessKeyId: credentials.AccessKeyId,
SecretAccessKey: credentials.SecretAccessKey,
})
return provider, err
})
}
+1
View File
@@ -495,6 +495,7 @@ const (
PurgeProviderTypeAliyunCAS = PurgeProviderType(AccessProviderTypeAliyun + "-cas")
PurgeProviderTypeAliyunCLB = PurgeProviderType(AccessProviderTypeAliyun + "-clb")
PurgeProviderTypeAliyunESA = PurgeProviderType(AccessProviderTypeAliyun + "-esa")
PurgeProviderTypeBaiduCloudCert = PurgeProviderType(AccessProviderTypeBaiduCloud + "-cert")
PurgeProviderTypeHuaweiCloudELB = PurgeProviderType(AccessProviderTypeHuaweiCloud + "-elb")
PurgeProviderTypeHuaweiCloudSCM = PurgeProviderType(AccessProviderTypeHuaweiCloud + "-scm")
PurgeProviderTypeHuaweiCloudWAF = PurgeProviderType(AccessProviderTypeHuaweiCloud + "-waf")
@@ -0,0 +1,44 @@
//go:build tester
package baiducloudcert_test
import (
"testing"
"github.com/stretchr/testify/require"
tester "github.com/certimate-go/certimate/pkg/core/purger/providers-tester"
impl "github.com/certimate-go/certimate/pkg/core/purger/providers/baiducloud-cert"
)
var (
fp = tester.InitArgs("BAIDUCLOUDCERT_")
fAccessKeyId string
fSecretAccessKey string
)
func init() {
fp.DefineString(&fAccessKeyId, "ACCESSKEYID")
fp.DefineString(&fSecretAccessKey, "SECRETACCESSKEY")
}
/*
Shell command to run this test:
go test -tags=tester -v ./baiducloud_cert_test.go -args \
--BAIDUCLOUDCERT_ACCESSKEYID="your-access-key-id" \
--BAIDUCLOUDCERT_SECRETACCESSKEY="your-access-key-secret"
*/
func TestProvider(t *testing.T) {
fp.Parse()
t.Run("Purge", func(t *testing.T) {
provider, err := impl.NewPurger(&impl.PurgerConfig{
AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey,
})
require.NoError(t, err)
tester.Purge(t, provider, tester.PurgeInput{})
})
}
@@ -0,0 +1,128 @@
package baiducloudcert
import (
"context"
"fmt"
"log/slog"
"time"
"github.com/baidubce/bce-sdk-go/bce"
"github.com/certimate-go/certimate/pkg/core"
baiducert "github.com/certimate-go/certimate/pkg/sdk3rd/baiducloud/cert"
xloop "github.com/certimate-go/certimate/pkg/utils/loop"
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
)
type (
Provider = core.Purger
PurgeResult = core.PurgerPurgeResult
)
type PurgerConfig struct {
// 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
}
type Purger struct {
config *PurgerConfig
logger *slog.Logger
sdkClient *baiducert.Client
}
var _ Provider = (*Purger)(nil)
func NewPurger(config *PurgerConfig) (*Purger, error) {
if config == nil {
return nil, fmt.Errorf("the configuration of the purger provider is nil")
}
client, err := createSDKClient(config.AccessKeyId, config.SecretAccessKey)
if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}
return &Purger{
config: config,
logger: slog.Default(),
sdkClient: client,
}, nil
}
func (p *Purger) SetLogger(logger *slog.Logger) {
if logger == nil {
p.logger = slog.New(slog.DiscardHandler)
} else {
p.logger = logger
}
}
func (p *Purger) Purge(ctx context.Context, expiry time.Duration) (*PurgeResult, error) {
purgingCertIds := make([]string, 0)
// 查看证书列表
// REF: https://cloud.baidu.com/doc/Reference/s/Gjwvz27xu#34-%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E5%88%97%E8%A1%A8
listCertDetail, err := p.sdkClient.ListCertDetail()
p.logger.Debug("sdk request 'cert.ListCertDetail'", slog.Any("response", listCertDetail))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'cert.ListCertDetail': %w", err)
} else {
for _, certItem := range listCertDetail.Certs {
certNotAfter, err := time.ParseInLocation("2006-01-02T15:04:05Z", certItem.CertStopTime, time.FixedZone("CST", 8*60*60))
if err != nil {
continue
}
if time.Since(certNotAfter) >= expiry {
purgingCertIds = append(purgingCertIds, certItem.CertId)
}
}
}
// 删除证书
// REF: https://cloud.baidu.com/doc/Reference/s/Gjwvz27xu#37-%E5%88%A0%E9%99%A4%E8%AF%81%E4%B9%A6
purgedCount := 0
if len(purgingCertIds) > 0 {
p.logger.Info("found certificates to purge", slog.Any("certIds", purgingCertIds))
if err := xloop.ForRangeAllWithContext(ctx, purgingCertIds, func(ctx context.Context, certId string, i int) error {
if i > 0 {
if err := xwait.DelayWithContext(ctx, 1*time.Second); err != nil {
return err
}
}
err := p.sdkClient.DeleteCert(certId)
p.logger.Debug("sdk request 'cert.DeleteCert'", slog.String("params.certId", certId))
if err != nil {
if sdkErr, ok := err.(*bce.BceServiceError); ok {
if sdkErrCode := sdkErr.Code; sdkErrCode == "ResourceNotFoundException" || sdkErrCode == "OperationNotAllowedException" {
return nil
}
}
return fmt.Errorf("failed to execute sdk request 'cert.DeleteCert': %w", err)
}
purgedCount++
return nil
}); err != nil {
return nil, err
}
}
return &PurgeResult{
Count: purgedCount,
}, nil
}
func createSDKClient(accessKeyId, secretAccessKey string) (*baiducert.Client, error) {
client, err := baiducert.NewClient(accessKeyId, secretAccessKey, "")
if err != nil {
return nil, err
}
return client, nil
}
+2
View File
@@ -989,6 +989,7 @@ export const PURGE_PROVIDERS = Object.freeze(
ALIYUN_CAS: `${ACCESS_PROVIDERS.ALIYUN}-cas`,
ALIYUN_CLB: `${ACCESS_PROVIDERS.ALIYUN}-clb`,
ALIYUN_ESA: `${ACCESS_PROVIDERS.ALIYUN}-esa`,
BAIDUCLOUD_CERT: `${ACCESS_PROVIDERS.BAIDUCLOUD}-cert`,
HUAWEICLOUD_ELB: `${ACCESS_PROVIDERS.HUAWEICLOUD}-elb`,
HUAWEICLOUD_SCM: `${ACCESS_PROVIDERS.HUAWEICLOUD}-scm`,
HUAWEICLOUD_WAF: `${ACCESS_PROVIDERS.HUAWEICLOUD}-waf`,
@@ -1019,6 +1020,7 @@ export const purgeProvidersMap: Map<PurgeProvider["type"] | string, PurgeProvide
[PURGE_PROVIDERS.HUAWEICLOUD_SCM, "provider.huaweicloud_scm"],
[PURGE_PROVIDERS.HUAWEICLOUD_ELB, "provider.huaweicloud_elb"],
[PURGE_PROVIDERS.HUAWEICLOUD_WAF, "provider.huaweicloud_waf"],
[PURGE_PROVIDERS.BAIDUCLOUD_CERT, "provider.baiducloud_cert"],
[PURGE_PROVIDERS.UCLOUD_USSL, "provider.ucloud_ussl"],
] satisfies Array<[PurgeProviderType, string, "builtin"] | [PurgeProviderType, string]>
).map(([type, name]) => [
@@ -78,6 +78,7 @@
"baiducloud_appblb": "Baidu Cloud - AppBLB (Application Baidu Load Balancer)",
"baiducloud_blb": "Baidu Cloud - BLB (Load Balancer)",
"baiducloud_cdn": "Baidu Cloud - CDN (Content Delivery Network)",
"baiducloud_cert": "Baidu Cloud - SSL Certificate Service",
"baiducloud_cert_upload": "Baidu Cloud - Upload to SSL Certificate Service",
"baiducloud_dns": "Baidu Cloud - DNS",
"baishan": "Baishan",
@@ -78,6 +78,7 @@
"baiducloud_appblb": "百度智能云 - 应用型负载均衡 BLB",
"baiducloud_blb": "百度智能云 - 普通型负载均衡 BLB",
"baiducloud_cdn": "百度智能云 - 内容分发网络 CDN",
"baiducloud_cert": "百度智能云 - SSL 证书服务",
"baiducloud_cert_upload": "百度智能云 - 上传到 SSL 证书服务",
"baiducloud_dns": "百度智能云 - 智能云解析 DNS",
"baishan": "白山云",