feat: add aliyun cas uploader

This commit is contained in:
Fu Diwei
2024-10-21 00:35:16 +08:00
parent a4fc8dfc56
commit b031f00764
5 changed files with 205 additions and 14 deletions

View File

@@ -0,0 +1,165 @@
package impl
import (
"context"
"fmt"
"strings"
"time"
cas20200407 "github.com/alibabacloud-go/cas-20200407/v3/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
"github.com/usual2970/certimate/internal/pkg/utils/x509"
)
type AliyunCASUploaderConfig struct {
Region string `json:"region"`
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
}
type AliyunCASUploader struct {
config *AliyunCASUploaderConfig
sdkClient *cas20200407.Client
sdkRuntime *util.RuntimeOptions
}
func NewAliyunCASUploader(config *AliyunCASUploaderConfig) (*AliyunCASUploader, error) {
client, err := (&AliyunCASUploader{config: config}).createSdkClient()
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
return &AliyunCASUploader{
config: config,
sdkClient: client,
sdkRuntime: &util.RuntimeOptions{},
}, nil
}
func (u *AliyunCASUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
// 解析证书内容
certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil {
return nil, err
}
// 查询证书列表,避免重复上传
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listusercertificateorder
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getusercertificatedetail
listUserCertificateOrderPage := int64(1)
listUserCertificateOrderLimit := int64(50)
for {
listUserCertificateOrderReq := &cas20200407.ListUserCertificateOrderRequest{
CurrentPage: tea.Int64(listUserCertificateOrderPage),
ShowSize: tea.Int64(listUserCertificateOrderLimit),
OrderType: tea.String("CERT"),
}
listUserCertificateOrderResp, err := u.sdkClient.ListUserCertificateOrderWithOptions(listUserCertificateOrderReq, u.sdkRuntime)
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'cas.ListUserCertificateOrder': %w", err)
}
if listUserCertificateOrderResp.Body.CertificateOrderList != nil {
for _, certDetail := range listUserCertificateOrderResp.Body.CertificateOrderList {
if strings.EqualFold(certX509.SerialNumber.Text(16), *certDetail.SerialNo) {
getUserCertificateDetailReq := &cas20200407.GetUserCertificateDetailRequest{
CertId: certDetail.CertificateId,
}
getUserCertificateDetailResp, err := u.sdkClient.GetUserCertificateDetailWithOptions(getUserCertificateDetailReq, u.sdkRuntime)
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'cas.GetUserCertificateDetail': %w", err)
}
var isSameCert bool
if *getUserCertificateDetailResp.Body.Cert == certPem {
isSameCert = true
} else {
cert, err := x509.ParseCertificateFromPEM(*getUserCertificateDetailResp.Body.Cert)
if err != nil {
continue
}
isSameCert = x509.EqualCertificate(certX509, cert)
}
// 如果已存在相同证书,直接返回已有的证书信息
if isSameCert {
return &uploader.UploadResult{
CertId: fmt.Sprintf("%d", tea.Int64Value(certDetail.CertificateId)),
CertName: *certDetail.Name,
}, nil
}
}
}
}
if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) {
break
}
listUserCertificateOrderPage += 1
if listUserCertificateOrderPage > 99 { // 避免死循环
break
}
}
// 生成新证书名(需符合阿里云命名规则)
var certId, certName string
certName = fmt.Sprintf("certimate_%d", time.Now().UnixMilli())
// 上传新证书
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-uploadusercertificate
uploadUserCertificateReq := &cas20200407.UploadUserCertificateRequest{
Name: tea.String(certName),
Cert: tea.String(certPem),
Key: tea.String(privkeyPem),
}
uploadUserCertificateResp, err := u.sdkClient.UploadUserCertificateWithOptions(uploadUserCertificateReq, u.sdkRuntime)
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'cas.UploadUserCertificate': %w", err)
}
certId = fmt.Sprintf("%d", tea.Int64Value(uploadUserCertificateResp.Body.CertId))
return &uploader.UploadResult{
CertId: certId,
CertName: certName,
}, nil
}
func (u *AliyunCASUploader) createSdkClient() (*cas20200407.Client, error) {
region := u.config.Region
accessKeyId := u.config.AccessKeyId
accessKeySecret := u.config.AccessKeySecret
if region == "" {
region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州
}
aConfig := &openapi.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
}
var endpoint string
switch region {
case "cn-hangzhou":
endpoint = "cas.aliyuncs.com"
case "ap-southeast-1":
endpoint = "cas.ap-southeast-1.aliyuncs.com"
case "eu-central-1":
endpoint = "cas.eu-central-1.aliyuncs.com"
default:
endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region)
}
aConfig.Endpoint = tea.String(endpoint)
client, err := cas20200407.NewClient(aConfig)
if err != nil {
return nil, err
}
return client, nil
}

View File

@@ -92,7 +92,7 @@ func (u *HuaweiCloudELBUploader) Upload(ctx context.Context, certPem string, pri
listCertificatesMarker = listCertificatesResp.PageInfo.NextMarker
listCertificatesPage++
if listCertificatesPage >= 9 { // 避免无限获取
if listCertificatesPage >= 9 { // 避免死循环
break
}
}
@@ -131,7 +131,7 @@ func (u *HuaweiCloudELBUploader) createSdkClient() (*hcElb.ElbClient, error) {
accessKeyId := u.config.AccessKeyId
secretAccessKey := u.config.SecretAccessKey
if region == "" {
region = "cn-north-4" // ELB 服务默认区域:华北北京
region = "cn-north-4" // ELB 服务默认区域:华北北京
}
auth, err := basic.NewCredentialsBuilder().

View File

@@ -40,7 +40,7 @@ func NewHuaweiCloudSCMUploader(config *HuaweiCloudSCMUploaderConfig) (*HuaweiClo
func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
// 解析证书内容
newCert, err := x509.ParseCertificateFromPEM(certPem)
certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil {
return nil, err
}
@@ -85,7 +85,7 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
continue
}
isSameCert = x509.EqualCertificate(cert, newCert)
isSameCert = x509.EqualCertificate(certX509, cert)
}
// 如果已存在相同证书,直接返回已有的证书信息
@@ -104,7 +104,7 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
listCertificatesOffset += listCertificatesLimit
listCertificatesPage += 1
if listCertificatesPage > 99 { // 避免无限获取
if listCertificatesPage > 99 { // 避免死循环
break
}
}
@@ -139,7 +139,7 @@ func (u *HuaweiCloudSCMUploader) createSdkClient() (*hcScm.ScmClient, error) {
accessKeyId := u.config.AccessKeyId
secretAccessKey := u.config.SecretAccessKey
if region == "" {
region = "cn-north-4" // SCM 服务默认区域:华北北京
region = "cn-north-4" // SCM 服务默认区域:华北北京
}
auth, err := basic.NewCredentialsBuilder().