mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-10 22:49:51 +00:00
feat: add huaweicloud elb uploader
This commit is contained in:
parent
fc55e37454
commit
f168bd903d
160
internal/pkg/core/uploader/impl/huaweicloud_elb.go
Normal file
160
internal/pkg/core/uploader/impl/huaweicloud_elb.go
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
|
||||||
|
elb "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3"
|
||||||
|
elbModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/model"
|
||||||
|
elbRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/region"
|
||||||
|
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/utils/cast"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/utils/x509"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HuaweiCloudELBUploaderConfig struct {
|
||||||
|
Region string `json:"region"`
|
||||||
|
ProjectId string `json:"projectId"`
|
||||||
|
AccessKeyId string `json:"accessKeyId"`
|
||||||
|
SecretAccessKey string `json:"secretAccessKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HuaweiCloudELBUploader struct {
|
||||||
|
config *HuaweiCloudELBUploaderConfig
|
||||||
|
sdkClient *elb.ElbClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHuaweiCloudELBUploader(config *HuaweiCloudELBUploaderConfig) (*HuaweiCloudELBUploader, error) {
|
||||||
|
client, err := (&HuaweiCloudELBUploader{config: config}).createSdkClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HuaweiCloudELBUploader{
|
||||||
|
config: config,
|
||||||
|
sdkClient: client,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *HuaweiCloudELBUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
|
||||||
|
// 解析证书内容
|
||||||
|
newCert, err := x509.ParseCertificateFromPEM(certPem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历查询已有证书,避免重复上传
|
||||||
|
// REF: https://support.huaweicloud.com/api-elb/ListCertificates.html
|
||||||
|
listCertificatesPage := 1
|
||||||
|
listCertificatesLimit := int32(2000)
|
||||||
|
var listCertificatesMarker *string = nil
|
||||||
|
for {
|
||||||
|
listCertificatesReq := &elbModel.ListCertificatesRequest{
|
||||||
|
Limit: cast.Int32Ptr(listCertificatesLimit),
|
||||||
|
Marker: listCertificatesMarker,
|
||||||
|
Type: &[]string{"server"},
|
||||||
|
}
|
||||||
|
listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to execute sdk request 'elb.ListCertificates': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if listCertificatesResp.Certificates != nil {
|
||||||
|
for _, certDetail := range *listCertificatesResp.Certificates {
|
||||||
|
var isSameCert bool
|
||||||
|
if certDetail.Certificate == certPem {
|
||||||
|
isSameCert = true
|
||||||
|
} else {
|
||||||
|
cert, err := x509.ParseCertificateFromPEM(certDetail.Certificate)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
isSameCert = x509.EqualCertificate(cert, newCert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已存在相同证书,直接返回已有的证书信息
|
||||||
|
if isSameCert {
|
||||||
|
return &uploader.UploadResult{
|
||||||
|
CertId: certDetail.Id,
|
||||||
|
CertName: certDetail.Name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if listCertificatesResp.Certificates == nil || len(*listCertificatesResp.Certificates) < int(listCertificatesLimit) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
listCertificatesMarker = listCertificatesResp.PageInfo.NextMarker
|
||||||
|
listCertificatesPage++
|
||||||
|
if listCertificatesPage >= 9 { // 避免无限获取
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成证书名(需符合华为云命名规则)
|
||||||
|
var certId, certName string
|
||||||
|
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
|
||||||
|
|
||||||
|
// 创建新证书
|
||||||
|
// REF: https://support.huaweicloud.com/api-elb/CreateCertificate.html
|
||||||
|
createCertificateReq := &elbModel.CreateCertificateRequest{
|
||||||
|
Body: &elbModel.CreateCertificateRequestBody{
|
||||||
|
Certificate: &elbModel.CreateCertificateOption{
|
||||||
|
ProjectId: cast.StringPtr(u.config.ProjectId),
|
||||||
|
Name: cast.StringPtr(certName),
|
||||||
|
Certificate: cast.StringPtr(certPem),
|
||||||
|
PrivateKey: cast.StringPtr(privkeyPem),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
createCertificateResp, err := u.sdkClient.CreateCertificate(createCertificateReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to execute sdk request 'elb.CreateCertificate': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certId = createCertificateResp.Certificate.Id
|
||||||
|
certName = createCertificateResp.Certificate.Name
|
||||||
|
return &uploader.UploadResult{
|
||||||
|
CertId: certId,
|
||||||
|
CertName: certName,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *HuaweiCloudELBUploader) createSdkClient() (*elb.ElbClient, error) {
|
||||||
|
region := u.config.Region
|
||||||
|
accessKeyId := u.config.AccessKeyId
|
||||||
|
secretAccessKey := u.config.SecretAccessKey
|
||||||
|
if region == "" {
|
||||||
|
region = "cn-north-4" // ELB 服务默认区域:华北北京四
|
||||||
|
}
|
||||||
|
|
||||||
|
auth, err := basic.NewCredentialsBuilder().
|
||||||
|
WithAk(accessKeyId).
|
||||||
|
WithSk(secretAccessKey).
|
||||||
|
SafeBuild()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hcRegion, err := elbRegion.SafeValueOf(region)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hcClient, err := elb.ElbClientBuilder().
|
||||||
|
WithRegion(hcRegion).
|
||||||
|
WithCredential(auth).
|
||||||
|
SafeBuild()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := elb.NewElbClient(hcClient)
|
||||||
|
return client, nil
|
||||||
|
}
|
@ -22,19 +22,19 @@ type HuaweiCloudSCMUploaderConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HuaweiCloudSCMUploader struct {
|
type HuaweiCloudSCMUploader struct {
|
||||||
config *HuaweiCloudSCMUploaderConfig
|
config *HuaweiCloudSCMUploaderConfig
|
||||||
client *scm.ScmClient
|
sdkClient *scm.ScmClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHuaweiCloudSCMUploader(config *HuaweiCloudSCMUploaderConfig) (*HuaweiCloudSCMUploader, error) {
|
func NewHuaweiCloudSCMUploader(config *HuaweiCloudSCMUploaderConfig) (*HuaweiCloudSCMUploader, error) {
|
||||||
client, err := createClient(config.Region, config.AccessKeyId, config.SecretAccessKey)
|
client, err := (&HuaweiCloudSCMUploader{config: config}).createSdkClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create client: %w", err)
|
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HuaweiCloudSCMUploader{
|
return &HuaweiCloudSCMUploader{
|
||||||
config: config,
|
config: config,
|
||||||
client: client,
|
sdkClient: client,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
// 遍历查询已有证书,避免重复上传
|
// 遍历查询已有证书,避免重复上传
|
||||||
// REF: https://support.huaweicloud.com/api-ccm/ListCertificates.html
|
// REF: https://support.huaweicloud.com/api-ccm/ListCertificates.html
|
||||||
// REF: https://support.huaweicloud.com/api-ccm/ExportCertificate_0.html
|
// REF: https://support.huaweicloud.com/api-ccm/ExportCertificate_0.html
|
||||||
|
listCertificatesPage := 1
|
||||||
listCertificatesLimit := int32(50)
|
listCertificatesLimit := int32(50)
|
||||||
listCertificatesOffset := int32(0)
|
listCertificatesOffset := int32(0)
|
||||||
for {
|
for {
|
||||||
@ -57,9 +58,9 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
SortDir: cast.StringPtr("DESC"),
|
SortDir: cast.StringPtr("DESC"),
|
||||||
SortKey: cast.StringPtr("certExpiredTime"),
|
SortKey: cast.StringPtr("certExpiredTime"),
|
||||||
}
|
}
|
||||||
listCertificatesResp, err := u.client.ListCertificates(listCertificatesReq)
|
listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to execute request 'scm.ListCertificates': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'scm.ListCertificates': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if listCertificatesResp.Certificates != nil {
|
if listCertificatesResp.Certificates != nil {
|
||||||
@ -67,12 +68,12 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
exportCertificateReq := &scmModel.ExportCertificateRequest{
|
exportCertificateReq := &scmModel.ExportCertificateRequest{
|
||||||
CertificateId: certDetail.Id,
|
CertificateId: certDetail.Id,
|
||||||
}
|
}
|
||||||
exportCertificateResp, err := u.client.ExportCertificate(exportCertificateReq)
|
exportCertificateResp, err := u.sdkClient.ExportCertificate(exportCertificateReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if exportCertificateResp != nil && exportCertificateResp.HttpStatusCode == 404 {
|
if exportCertificateResp != nil && exportCertificateResp.HttpStatusCode == 404 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to execute request 'scm.ExportCertificate': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'scm.ExportCertificate': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isSameCert bool
|
var isSameCert bool
|
||||||
@ -102,7 +103,8 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
}
|
}
|
||||||
|
|
||||||
listCertificatesOffset += listCertificatesLimit
|
listCertificatesOffset += listCertificatesLimit
|
||||||
if listCertificatesOffset >= 999 { // 避免无限获取
|
listCertificatesPage += 1
|
||||||
|
if listCertificatesPage > 99 { // 避免无限获取
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,9 +122,9 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
PrivateKey: privkeyPem,
|
PrivateKey: privkeyPem,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
importCertificateResp, err := u.client.ImportCertificate(importCertificateReq)
|
importCertificateResp, err := u.sdkClient.ImportCertificate(importCertificateReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to execute request 'scm.ImportCertificate': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'scm.ImportCertificate': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
certId = *importCertificateResp.CertificateId
|
certId = *importCertificateResp.CertificateId
|
||||||
@ -132,7 +134,14 @@ func (u *HuaweiCloudSCMUploader) Upload(ctx context.Context, certPem string, pri
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *HuaweiCloudSCMUploader) createClient(region, accessKeyId, secretAccessKey string) (*scm.ScmClient, error) {
|
func (u *HuaweiCloudSCMUploader) createSdkClient() (*scm.ScmClient, error) {
|
||||||
|
region := u.config.Region
|
||||||
|
accessKeyId := u.config.AccessKeyId
|
||||||
|
secretAccessKey := u.config.SecretAccessKey
|
||||||
|
if region == "" {
|
||||||
|
region = "cn-north-4" // SCM 服务默认区域:华北北京四
|
||||||
|
}
|
||||||
|
|
||||||
auth, err := basic.NewCredentialsBuilder().
|
auth, err := basic.NewCredentialsBuilder().
|
||||||
WithAk(accessKeyId).
|
WithAk(accessKeyId).
|
||||||
WithSk(secretAccessKey).
|
WithSk(secretAccessKey).
|
||||||
@ -141,10 +150,6 @@ func (u *HuaweiCloudSCMUploader) createClient(region, accessKeyId, secretAccessK
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if region == "" {
|
|
||||||
region = "cn-north-4" // SCM 服务默认区域:华北北京四
|
|
||||||
}
|
|
||||||
|
|
||||||
hcRegion, err := scmRegion.SafeValueOf(region)
|
hcRegion, err := scmRegion.SafeValueOf(region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user