refactor: clean code

main
Fu Diwei 2024-11-19 22:43:15 +08:00
parent a6c93ef9b8
commit 82807fcc1b
10 changed files with 127 additions and 111 deletions

View File

@ -29,7 +29,7 @@ func NewVolcengineCDNDeployer(option *DeployerOption) (Deployer, error) {
client := cdn.NewInstance() client := cdn.NewInstance()
client.Client.SetAccessKey(access.AccessKeyID) client.Client.SetAccessKey(access.AccessKeyID)
client.Client.SetSecretKey(access.SecretAccessKey) client.Client.SetSecretKey(access.SecretAccessKey)
uploader, err := volcenginecdn.New(&volcenginecdn.VolcengineCDNUploaderConfig{ uploader, err := volcenginecdn.New(&volcenginecdn.VolcEngineCDNUploaderConfig{
AccessKeyId: access.AccessKeyID, AccessKeyId: access.AccessKeyID,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
}) })

View File

@ -33,7 +33,7 @@ func NewVolcengineLiveDeployer(option *DeployerOption) (Deployer, error) {
AccessKeyID: access.AccessKeyID, AccessKeyID: access.AccessKeyID,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
}) })
uploader, err := volcenginelive.New(&volcenginelive.VolcengineLiveUploaderConfig{ uploader, err := volcenginelive.New(&volcenginelive.VolcEngineLiveUploaderConfig{
AccessKeyId: access.AccessKeyID, AccessKeyId: access.AccessKeyID,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
}) })

View File

@ -83,13 +83,13 @@ func (d *LocalDeployer) Deploy(ctx context.Context, certPem string, privkeyPem s
switch d.config.OutputFormat { switch d.config.OutputFormat {
case "", OUTPUT_FORMAT_PEM: case "", OUTPUT_FORMAT_PEM:
if err := fs.WriteFileString(d.config.OutputCertPath, certPem); err != nil { if err := fs.WriteFileString(d.config.OutputCertPath, certPem); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to save certificate file")
} }
d.logger.Appendt("certificate file saved") d.logger.Appendt("certificate file saved")
if err := fs.WriteFileString(d.config.OutputKeyPath, privkeyPem); err != nil { if err := fs.WriteFileString(d.config.OutputKeyPath, privkeyPem); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to save private key file")
} }
d.logger.Appendt("private key file saved") d.logger.Appendt("private key file saved")
@ -97,13 +97,13 @@ func (d *LocalDeployer) Deploy(ctx context.Context, certPem string, privkeyPem s
case OUTPUT_FORMAT_PFX: case OUTPUT_FORMAT_PFX:
pfxData, err := x509.TransformCertificateFromPEMToPFX(certPem, privkeyPem, d.config.PfxPassword) pfxData, err := x509.TransformCertificateFromPEMToPFX(certPem, privkeyPem, d.config.PfxPassword)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to transform certificate to PFX")
} }
d.logger.Appendt("certificate transformed to PFX") d.logger.Appendt("certificate transformed to PFX")
if err := fs.WriteFile(d.config.OutputCertPath, pfxData); err != nil { if err := fs.WriteFile(d.config.OutputCertPath, pfxData); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to save certificate file")
} }
d.logger.Appendt("certificate file saved") d.logger.Appendt("certificate file saved")
@ -111,13 +111,13 @@ func (d *LocalDeployer) Deploy(ctx context.Context, certPem string, privkeyPem s
case OUTPUT_FORMAT_JKS: case OUTPUT_FORMAT_JKS:
jksData, err := x509.TransformCertificateFromPEMToJKS(certPem, privkeyPem, d.config.JksAlias, d.config.JksKeypass, d.config.JksStorepass) jksData, err := x509.TransformCertificateFromPEMToJKS(certPem, privkeyPem, d.config.JksAlias, d.config.JksKeypass, d.config.JksStorepass)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to transform certificate to JKS")
} }
d.logger.Appendt("certificate transformed to JKS") d.logger.Appendt("certificate transformed to JKS")
if err := fs.WriteFile(d.config.OutputCertPath, jksData); err != nil { if err := fs.WriteFile(d.config.OutputCertPath, jksData); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to save certificate file")
} }
d.logger.Appendt("certificate file uploaded") d.logger.Appendt("certificate file uploaded")

View File

@ -91,7 +91,7 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
d.config.SshKeyPassphrase, d.config.SshKeyPassphrase,
) )
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to create ssh client")
} }
defer client.Close() defer client.Close()
@ -111,13 +111,13 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
switch d.config.OutputFormat { switch d.config.OutputFormat {
case "", OUTPUT_FORMAT_PEM: case "", OUTPUT_FORMAT_PEM:
if err := writeSftpFileString(client, d.config.OutputCertPath, certPem); err != nil { if err := writeSftpFileString(client, d.config.OutputCertPath, certPem); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to upload certificate file")
} }
d.logger.Appendt("certificate file uploaded") d.logger.Appendt("certificate file uploaded")
if err := writeSftpFileString(client, d.config.OutputKeyPath, privkeyPem); err != nil { if err := writeSftpFileString(client, d.config.OutputKeyPath, privkeyPem); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to upload private key file")
} }
d.logger.Appendt("private key file uploaded") d.logger.Appendt("private key file uploaded")
@ -125,13 +125,13 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
case OUTPUT_FORMAT_PFX: case OUTPUT_FORMAT_PFX:
pfxData, err := x509.TransformCertificateFromPEMToPFX(certPem, privkeyPem, d.config.PfxPassword) pfxData, err := x509.TransformCertificateFromPEMToPFX(certPem, privkeyPem, d.config.PfxPassword)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to transform certificate to PFX")
} }
d.logger.Appendt("certificate transformed to PFX") d.logger.Appendt("certificate transformed to PFX")
if err := writeSftpFile(client, d.config.OutputCertPath, pfxData); err != nil { if err := writeSftpFile(client, d.config.OutputCertPath, pfxData); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to upload certificate file")
} }
d.logger.Appendt("certificate file uploaded") d.logger.Appendt("certificate file uploaded")
@ -139,13 +139,13 @@ func (d *SshDeployer) Deploy(ctx context.Context, certPem string, privkeyPem str
case OUTPUT_FORMAT_JKS: case OUTPUT_FORMAT_JKS:
jksData, err := x509.TransformCertificateFromPEMToJKS(certPem, privkeyPem, d.config.JksAlias, d.config.JksKeypass, d.config.JksStorepass) jksData, err := x509.TransformCertificateFromPEMToJKS(certPem, privkeyPem, d.config.JksAlias, d.config.JksKeypass, d.config.JksStorepass)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to transform certificate to JKS")
} }
d.logger.Appendt("certificate transformed to JKS") d.logger.Appendt("certificate transformed to JKS")
if err := writeSftpFile(client, d.config.OutputCertPath, jksData); err != nil { if err := writeSftpFile(client, d.config.OutputCertPath, jksData); err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to upload certificate file")
} }
d.logger.Appendt("certificate file uploaded") d.logger.Appendt("certificate file uploaded")
@ -205,7 +205,7 @@ func createSshClient(host string, port int32, username string, password string,
func execSshCommand(sshCli *ssh.Client, command string) (string, string, error) { func execSshCommand(sshCli *ssh.Client, command string) (string, string, error) {
session, err := sshCli.NewSession() session, err := sshCli.NewSession()
if err != nil { if err != nil {
return "", "", xerrors.Wrap(err, "failed to create ssh session") return "", "", err
} }
defer session.Close() defer session.Close()
@ -215,7 +215,7 @@ func execSshCommand(sshCli *ssh.Client, command string) (string, string, error)
session.Stderr = &stderrBuf session.Stderr = &stderrBuf
err = session.Run(command) err = session.Run(command)
if err != nil { if err != nil {
return "", "", xerrors.Wrap(err, "failed to execute ssh command") return "", "", err
} }
return stdoutBuf.String(), stderrBuf.String(), nil return stdoutBuf.String(), stderrBuf.String(), nil

View File

@ -58,7 +58,7 @@ type webhookData struct {
func (d *WebhookDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *WebhookDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
certX509, err := x509.ParseCertificateFromPEM(certPem) certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil { if err != nil {
return nil, err return nil, xerrors.Wrap(err, "failed to parse x509")
} }
data := &webhookData{ data := &webhookData{

View File

@ -144,11 +144,6 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl
region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州 region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州
} }
aConfig := &aliyunOpen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
}
var endpoint string var endpoint string
switch region { switch region {
case "cn-hangzhou": case "cn-hangzhou":
@ -156,9 +151,14 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl
default: default:
endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region)
} }
aConfig.Endpoint = tea.String(endpoint)
client, err := aliyunCas.NewClient(aConfig) config := &aliyunOpen.Config{
Endpoint: tea.String(endpoint),
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
}
client, err := aliyunCas.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -121,11 +121,6 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Cl
region = "cn-hangzhou" // SLB 服务默认区域:华东一杭州 region = "cn-hangzhou" // SLB 服务默认区域:华东一杭州
} }
aConfig := &aliyunOpen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
}
var endpoint string var endpoint string
switch region { switch region {
case case
@ -137,9 +132,14 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Cl
default: default:
endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region)
} }
aConfig.Endpoint = tea.String(endpoint)
client, err := aliyunSlb.NewClient(aConfig) config := &aliyunOpen.Config{
Endpoint: tea.String(endpoint),
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
}
client, err := aliyunSlb.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,6 +2,7 @@ package bytepluscdn
import ( import (
"context" "context"
"crypto/sha1"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors" "errors"
@ -9,9 +10,11 @@ import (
"strings" "strings"
"time" "time"
"github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn" bpCdn "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
"github.com/usual2970/certimate/internal/pkg/utils/cast"
"github.com/usual2970/certimate/internal/pkg/utils/x509" "github.com/usual2970/certimate/internal/pkg/utils/x509"
) )
@ -22,7 +25,7 @@ type ByteplusCDNUploaderConfig struct {
type ByteplusCDNUploader struct { type ByteplusCDNUploader struct {
config *ByteplusCDNUploaderConfig config *ByteplusCDNUploaderConfig
sdkClient *cdn.CDN sdkClient *bpCdn.CDN
} }
var _ uploader.Uploader = (*ByteplusCDNUploader)(nil) var _ uploader.Uploader = (*ByteplusCDNUploader)(nil)
@ -32,14 +35,13 @@ func New(config *ByteplusCDNUploaderConfig) (*ByteplusCDNUploader, error) {
return nil, errors.New("config is nil") return nil, errors.New("config is nil")
} }
instance := cdn.NewInstance() client := bpCdn.NewInstance()
client := instance.Client client.Client.SetAccessKey(config.AccessKey)
client.SetAccessKey(config.AccessKey) client.Client.SetSecretKey(config.SecretKey)
client.SetSecretKey(config.SecretKey)
return &ByteplusCDNUploader{ return &ByteplusCDNUploader{
config: config, config: config,
sdkClient: instance, sdkClient: client,
}, nil }, nil
} }
@ -49,17 +51,17 @@ func (u *ByteplusCDNUploader) Upload(ctx context.Context, certPem string, privke
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 查询证书列表,避免重复上传 // 查询证书列表,避免重复上传
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-listcertinfo // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-listcertinfo
pageNum := int64(1) listCertInfoPageNum := int64(1)
pageSize := int64(100) listCertInfoPageSize := int64(100)
certSource := "cert_center" listCertInfoTotal := 0
listCertInfoReq := &cdn.ListCertInfoRequest{ listCertInfoReq := &bpCdn.ListCertInfoRequest{
PageNum: &pageNum, PageNum: cast.Int64Ptr(listCertInfoPageNum),
PageSize: &pageSize, PageSize: cast.Int64Ptr(listCertInfoPageSize),
Source: &certSource, Source: cast.StringPtr("cert_center"),
} }
searchTotal := 0
for { for {
listCertInfoResp, err := u.sdkClient.ListCertInfo(listCertInfoReq) listCertInfoResp, err := u.sdkClient.ListCertInfo(listCertInfoReq)
if err != nil { if err != nil {
@ -68,8 +70,10 @@ func (u *ByteplusCDNUploader) Upload(ctx context.Context, certPem string, privke
if listCertInfoResp.Result.CertInfo != nil { if listCertInfoResp.Result.CertInfo != nil {
for _, certDetail := range listCertInfoResp.Result.CertInfo { for _, certDetail := range listCertInfoResp.Result.CertInfo {
hash := sha256.Sum256(certX509.Raw) fingerprintSha1 := sha1.Sum(certX509.Raw)
isSameCert := strings.EqualFold(hex.EncodeToString(hash[:]), certDetail.CertFingerprint.Sha256) fingerprintSha256 := sha256.Sum256(certX509.Raw)
isSameCert := strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), certDetail.CertFingerprint.Sha1) &&
strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), certDetail.CertFingerprint.Sha256)
// 如果已存在相同证书,直接返回已有的证书信息 // 如果已存在相同证书,直接返回已有的证书信息
if isSameCert { if isSameCert {
return &uploader.UploadResult{ return &uploader.UploadResult{
@ -80,23 +84,26 @@ func (u *ByteplusCDNUploader) Upload(ctx context.Context, certPem string, privke
} }
} }
searchTotal += len(listCertInfoResp.Result.CertInfo) listCertInfoLen := len(listCertInfoResp.Result.CertInfo)
if int(listCertInfoResp.Result.Total) > searchTotal { if listCertInfoLen < int(listCertInfoPageSize) || int(listCertInfoResp.Result.Total) <= listCertInfoTotal+listCertInfoLen {
pageNum++
} else {
break break
} else {
listCertInfoPageNum++
listCertInfoTotal += listCertInfoLen
} }
} }
// 生成新证书名(需符合 BytePlus 命名规则)
var certId, certName string var certId, certName string
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli()) certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
// 上传新证书 // 上传新证书
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-addcertificate // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-addcertificate
addCertificateReq := &cdn.AddCertificateRequest{ addCertificateReq := &bpCdn.AddCertificateRequest{
Certificate: certPem, Certificate: certPem,
PrivateKey: privkeyPem, PrivateKey: privkeyPem,
Source: &certSource, Source: cast.StringPtr("cert_center"),
Desc: &certName, Desc: cast.StringPtr(certName),
} }
addCertificateResp, err := u.sdkClient.AddCertificate(addCertificateReq) addCertificateResp, err := u.sdkClient.AddCertificate(addCertificateReq)
if err != nil { if err != nil {

View File

@ -2,6 +2,7 @@ package volcenginecdn
import ( import (
"context" "context"
"crypto/sha1"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors" "errors"
@ -10,56 +11,57 @@ import (
"time" "time"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veCdn "github.com/volcengine/volc-sdk-golang/service/cdn"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
"github.com/usual2970/certimate/internal/pkg/utils/cast"
"github.com/usual2970/certimate/internal/pkg/utils/x509" "github.com/usual2970/certimate/internal/pkg/utils/x509"
"github.com/volcengine/volc-sdk-golang/service/cdn"
) )
type VolcengineCDNUploaderConfig struct { type VolcEngineCDNUploaderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
} }
type VolcengineCDNUploader struct { type VolcEngineCDNUploader struct {
config *VolcengineCDNUploaderConfig config *VolcEngineCDNUploaderConfig
sdkClient *cdn.CDN sdkClient *veCdn.CDN
} }
var _ uploader.Uploader = (*VolcengineCDNUploader)(nil) var _ uploader.Uploader = (*VolcEngineCDNUploader)(nil)
func New(config *VolcengineCDNUploaderConfig) (*VolcengineCDNUploader, error) { func New(config *VolcEngineCDNUploaderConfig) (*VolcEngineCDNUploader, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") return nil, errors.New("config is nil")
} }
instance := cdn.NewInstance() client := veCdn.NewInstance()
client := instance.Client client.Client.SetAccessKey(config.AccessKeyId)
client.SetAccessKey(config.AccessKeyId) client.Client.SetSecretKey(config.AccessKeySecret)
client.SetSecretKey(config.AccessKeySecret)
return &VolcengineCDNUploader{ return &VolcEngineCDNUploader{
config: config, config: config,
sdkClient: instance, sdkClient: client,
}, nil }, nil
} }
func (u *VolcengineCDNUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) { func (u *VolcEngineCDNUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
// 解析证书内容 // 解析证书内容
certX509, err := x509.ParseCertificateFromPEM(certPem) certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 查询证书列表,避免重复上传 // 查询证书列表,避免重复上传
// REF: https://www.volcengine.com/docs/6454/125709 // REF: https://www.volcengine.com/docs/6454/125709
pageNum := int64(1) listCertInfoPageNum := int64(1)
pageSize := int64(100) listCertInfoPageSize := int64(100)
certSource := "volc_cert_center" listCertInfoTotal := 0
listCertInfoReq := &cdn.ListCertInfoRequest{ listCertInfoReq := &veCdn.ListCertInfoRequest{
PageNum: &pageNum, PageNum: cast.Int64Ptr(listCertInfoPageNum),
PageSize: &pageSize, PageSize: cast.Int64Ptr(listCertInfoPageSize),
Source: certSource, Source: "volc_cert_center",
} }
searchTotal := 0
for { for {
listCertInfoResp, err := u.sdkClient.ListCertInfo(listCertInfoReq) listCertInfoResp, err := u.sdkClient.ListCertInfo(listCertInfoReq)
if err != nil { if err != nil {
@ -68,8 +70,10 @@ func (u *VolcengineCDNUploader) Upload(ctx context.Context, certPem string, priv
if listCertInfoResp.Result.CertInfo != nil { if listCertInfoResp.Result.CertInfo != nil {
for _, certDetail := range listCertInfoResp.Result.CertInfo { for _, certDetail := range listCertInfoResp.Result.CertInfo {
hash := sha256.Sum256(certX509.Raw) fingerprintSha1 := sha1.Sum(certX509.Raw)
isSameCert := strings.EqualFold(hex.EncodeToString(hash[:]), certDetail.CertFingerprint.Sha256) fingerprintSha256 := sha256.Sum256(certX509.Raw)
isSameCert := strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), certDetail.CertFingerprint.Sha1) &&
strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), certDetail.CertFingerprint.Sha256)
// 如果已存在相同证书,直接返回已有的证书信息 // 如果已存在相同证书,直接返回已有的证书信息
if isSameCert { if isSameCert {
return &uploader.UploadResult{ return &uploader.UploadResult{
@ -80,24 +84,26 @@ func (u *VolcengineCDNUploader) Upload(ctx context.Context, certPem string, priv
} }
} }
searchTotal += len(listCertInfoResp.Result.CertInfo) listCertInfoLen := len(listCertInfoResp.Result.CertInfo)
if int(listCertInfoResp.Result.Total) > searchTotal { if listCertInfoLen < int(listCertInfoPageSize) || int(listCertInfoResp.Result.Total) <= listCertInfoTotal+listCertInfoLen {
pageNum++
} else {
break break
} else {
listCertInfoPageNum++
listCertInfoTotal += listCertInfoLen
} }
} }
// 生成新证书名(需符合火山引擎命名规则) // 生成新证书名(需符合火山引擎命名规则)
var certId, certName string var certId, certName string
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli()) certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
// 上传新证书 // 上传新证书
// REF: https://www.volcengine.com/docs/6454/1245763 // REF: https://www.volcengine.com/docs/6454/1245763
addCertificateReq := &cdn.AddCertificateRequest{ addCertificateReq := &veCdn.AddCertificateRequest{
Certificate: certPem, Certificate: certPem,
PrivateKey: privkeyPem, PrivateKey: privkeyPem,
Source: &certSource, Source: cast.StringPtr("volc_cert_center"),
Desc: &certName, Desc: cast.StringPtr(certName),
} }
addCertificateResp, err := u.sdkClient.AddCertificate(addCertificateReq) addCertificateResp, err := u.sdkClient.AddCertificate(addCertificateReq)
if err != nil { if err != nil {

View File

@ -8,77 +8,79 @@ import (
"time" "time"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veLive "github.com/volcengine/volc-sdk-golang/service/live/v20230101"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
"github.com/usual2970/certimate/internal/pkg/utils/cast" "github.com/usual2970/certimate/internal/pkg/utils/cast"
"github.com/usual2970/certimate/internal/pkg/utils/x509" "github.com/usual2970/certimate/internal/pkg/utils/x509"
live "github.com/volcengine/volc-sdk-golang/service/live/v20230101"
) )
type VolcengineLiveUploaderConfig struct { type VolcEngineLiveUploaderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
} }
type VolcengineLiveUploader struct { type VolcEngineLiveUploader struct {
config *VolcengineLiveUploaderConfig config *VolcEngineLiveUploaderConfig
sdkClient *live.Live sdkClient *veLive.Live
} }
var _ uploader.Uploader = (*VolcengineLiveUploader)(nil) var _ uploader.Uploader = (*VolcEngineLiveUploader)(nil)
func New(config *VolcengineLiveUploaderConfig) (*VolcengineLiveUploader, error) { func New(config *VolcEngineLiveUploaderConfig) (*VolcEngineLiveUploader, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") return nil, errors.New("config is nil")
} }
client := live.NewInstance() client := veLive.NewInstance()
client.SetAccessKey(config.AccessKeyId) client.SetAccessKey(config.AccessKeyId)
client.SetSecretKey(config.AccessKeySecret) client.SetSecretKey(config.AccessKeySecret)
return &VolcengineLiveUploader{ return &VolcEngineLiveUploader{
config: config, config: config,
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (u *VolcengineLiveUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) { func (u *VolcEngineLiveUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
// 解析证书内容 // 解析证书内容
certX509, err := x509.ParseCertificateFromPEM(certPem) certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 查询证书列表,避免重复上传 // 查询证书列表,避免重复上传
// REF: https://www.volcengine.com/docs/6469/1186278#%E6%9F%A5%E8%AF%A2%E8%AF%81%E4%B9%A6%E5%88%97%E8%A1%A8 // REF: https://www.volcengine.com/docs/6469/1186278#%E6%9F%A5%E8%AF%A2%E8%AF%81%E4%B9%A6%E5%88%97%E8%A1%A8
listCertReq := &live.ListCertV2Body{} listCertReq := &veLive.ListCertV2Body{}
listCertResp, err := u.sdkClient.ListCertV2(ctx, listCertReq) listCertResp, err := u.sdkClient.ListCertV2(ctx, listCertReq)
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'live.ListCertV2'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'live.ListCertV2'")
} }
if listCertResp.Result.CertList != nil { if listCertResp.Result.CertList != nil {
for _, certDetail := range listCertResp.Result.CertList { for _, certDetail := range listCertResp.Result.CertList {
describeCertDetailSecretReq := &live.DescribeCertDetailSecretV2Body{
ChainID: cast.StringPtr(certDetail.ChainID),
}
// 查询证书详细信息 // 查询证书详细信息
// REF: https://www.volcengine.com/docs/6469/1186278#%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E8%AF%A6%E6%83%85 // REF: https://www.volcengine.com/docs/6469/1186278#%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E8%AF%A6%E6%83%85
describeCertDetailSecretResp, detailErr := u.sdkClient.DescribeCertDetailSecretV2(ctx, describeCertDetailSecretReq) describeCertDetailSecretReq := &veLive.DescribeCertDetailSecretV2Body{
if detailErr != nil { ChainID: cast.StringPtr(certDetail.ChainID),
}
describeCertDetailSecretResp, err := u.sdkClient.DescribeCertDetailSecretV2(ctx, describeCertDetailSecretReq)
if err != nil {
continue continue
} }
var isSameCert bool var isSameCert bool
certificate := strings.Join(describeCertDetailSecretResp.Result.SSL.Chain, "\n\n") certificate := strings.Join(describeCertDetailSecretResp.Result.SSL.Chain, "\n\n")
if certificate == certPem { if certificate == certPem {
isSameCert = true isSameCert = true
} else { } else {
cert, err := x509.ParseCertificateFromPEM(certificate) oldCertX509, err := x509.ParseCertificateFromPEM(certificate)
if err != nil { if err != nil {
continue continue
} }
isSameCert = x509.EqualCertificate(cert, certX509) isSameCert = x509.EqualCertificate(certX509, oldCertX509)
} }
// 如果已存在相同证书,直接返回已有的证书信息 // 如果已存在相同证书,直接返回已有的证书信息
if isSameCert { if isSameCert {
return &uploader.UploadResult{ return &uploader.UploadResult{
@ -92,13 +94,14 @@ func (u *VolcengineLiveUploader) Upload(ctx context.Context, certPem string, pri
// 生成新证书名(需符合火山引擎命名规则) // 生成新证书名(需符合火山引擎命名规则)
var certId, certName string var certId, certName string
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli()) certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
// 上传新证书 // 上传新证书
// REF: https://www.volcengine.com/docs/6469/1186278#%E6%B7%BB%E5%8A%A0%E8%AF%81%E4%B9%A6 // REF: https://www.volcengine.com/docs/6469/1186278#%E6%B7%BB%E5%8A%A0%E8%AF%81%E4%B9%A6
createCertReq := &live.CreateCertBody{ createCertReq := &veLive.CreateCertBody{
CertName: &certName, CertName: &certName,
UseWay: "https", UseWay: "https",
ProjectName: cast.StringPtr("default"), ProjectName: cast.StringPtr("default"),
Rsa: live.CreateCertBodyRsa{ Rsa: veLive.CreateCertBodyRsa{
Prikey: privkeyPem, Prikey: privkeyPem,
Pubkey: certPem, Pubkey: certPem,
}, },