mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
feat(provider): new deployment provider: byteplus certcenter
This commit is contained in:
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
bytepluscdn "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn"
|
||||
bpcdn "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/certmgr"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
@@ -26,7 +26,7 @@ type CertmgrConfig struct {
|
||||
type Certmgr struct {
|
||||
config *CertmgrConfig
|
||||
logger *slog.Logger
|
||||
sdkClient *bytepluscdn.CDN
|
||||
sdkClient *bpcdn.CDN
|
||||
}
|
||||
|
||||
var _ certmgr.Provider = (*Certmgr)(nil)
|
||||
@@ -36,7 +36,7 @@ func NewCertmgr(config *CertmgrConfig) (*Certmgr, error) {
|
||||
return nil, fmt.Errorf("the configuration of the certmgr provider is nil")
|
||||
}
|
||||
|
||||
client := bytepluscdn.NewInstance()
|
||||
client := bpcdn.NewInstance()
|
||||
client.Client.SetAccessKey(config.AccessKey)
|
||||
client.Client.SetSecretKey(config.SecretKey)
|
||||
|
||||
@@ -73,10 +73,10 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*cert
|
||||
default:
|
||||
}
|
||||
|
||||
listCertInfoReq := &bytepluscdn.ListCertInfoRequest{
|
||||
PageNum: bytepluscdn.GetInt64Ptr(int64(listCertInfoPageNum)),
|
||||
PageSize: bytepluscdn.GetInt64Ptr(int64(listCertInfoPageSize)),
|
||||
Source: bytepluscdn.GetStrPtr("cert_center"),
|
||||
listCertInfoReq := &bpcdn.ListCertInfoRequest{
|
||||
PageNum: bpcdn.GetInt64Ptr(int64(listCertInfoPageNum)),
|
||||
PageSize: bpcdn.GetInt64Ptr(int64(listCertInfoPageSize)),
|
||||
Source: bpcdn.GetStrPtr("cert_center"),
|
||||
}
|
||||
listCertInfoResp, err := c.sdkClient.ListCertInfo(listCertInfoReq)
|
||||
c.logger.Debug("sdk request 'cdn.ListCertInfo'", slog.Any("request", listCertInfoReq), slog.Any("response", listCertInfoResp))
|
||||
@@ -117,11 +117,11 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*cert
|
||||
|
||||
// 上传新证书
|
||||
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-addcertificate
|
||||
addCertificateReq := &bytepluscdn.AddCertificateRequest{
|
||||
addCertificateReq := &bpcdn.AddCertificateRequest{
|
||||
Certificate: certPEM,
|
||||
PrivateKey: privkeyPEM,
|
||||
Source: bytepluscdn.GetStrPtr("cert_center"),
|
||||
Desc: bytepluscdn.GetStrPtr(certName),
|
||||
Source: bpcdn.GetStrPtr("cert_center"),
|
||||
Desc: bpcdn.GetStrPtr(certName),
|
||||
}
|
||||
addCertificateResp, err := c.sdkClient.AddCertificate(addCertificateReq)
|
||||
c.logger.Debug("sdk request 'cdn.AddCertificate'", slog.Any("request", addCertificateReq), slog.Any("response", addCertificateResp))
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package bytepluscertcenter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
bp "github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
bpsesion "github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/session"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/certmgr"
|
||||
bpcertificateservice "github.com/certimate-go/certimate/pkg/sdk3rd-trimmed/github.com/byteplus-sdk/byteplus-go-sdk-v2/service/certificateservice"
|
||||
)
|
||||
|
||||
type CertmgrConfig struct {
|
||||
// BytePlus AccessKey。
|
||||
AccessKey string `json:"accessKey"`
|
||||
// BytePlus SecretKey。
|
||||
SecretKey string `json:"secretKey"`
|
||||
// BytePlus 项目名称。
|
||||
ProjectName string `json:"projectName,omitempty"`
|
||||
// BytePlus 地域。
|
||||
Region string `json:"region"`
|
||||
}
|
||||
|
||||
type Certmgr struct {
|
||||
config *CertmgrConfig
|
||||
logger *slog.Logger
|
||||
sdkClient *bpcertificateservice.CERTIFICATESERVICE
|
||||
}
|
||||
|
||||
var _ certmgr.Provider = (*Certmgr)(nil)
|
||||
|
||||
func NewCertmgr(config *CertmgrConfig) (*Certmgr, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("the configuration of the certmgr provider is nil")
|
||||
}
|
||||
|
||||
client, err := createSDKClient(config.AccessKey, config.SecretKey, config.Region)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create client: %w", err)
|
||||
}
|
||||
|
||||
return &Certmgr{
|
||||
config: config,
|
||||
logger: slog.Default(),
|
||||
sdkClient: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Certmgr) SetLogger(logger *slog.Logger) {
|
||||
if logger == nil {
|
||||
c.logger = slog.New(slog.DiscardHandler)
|
||||
} else {
|
||||
c.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*certmgr.UploadResult, error) {
|
||||
// 上传证书
|
||||
// REF: https://docs.byteplus.com/en/docs/byteplus-certificate-center/reference-uploadcertificate
|
||||
uploadCertificateReq := &bpcertificateservice.UploadCertificateInput{
|
||||
ProjectName: lo.EmptyableToPtr(c.config.ProjectName),
|
||||
CertificateInfo: &bpcertificateservice.CertificateInfoForUploadCertificateInput{
|
||||
CertificateChain: bp.String(certPEM),
|
||||
PrivateKey: bp.String(privkeyPEM),
|
||||
},
|
||||
Repeatable: bp.Bool(false),
|
||||
}
|
||||
uploadCertificateResp, err := c.sdkClient.UploadCertificateWithContext(ctx, uploadCertificateReq)
|
||||
c.logger.Debug("sdk request 'certificateservice.UploadCertificate'", slog.Any("request", uploadCertificateReq), slog.Any("response", uploadCertificateResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'certificateservice.UploadCertificate': %w", err)
|
||||
}
|
||||
|
||||
var sslId string
|
||||
if uploadCertificateResp.InstanceId != nil && *uploadCertificateResp.InstanceId != "" {
|
||||
sslId = *uploadCertificateResp.InstanceId
|
||||
}
|
||||
if uploadCertificateResp.RepeatId != nil && *uploadCertificateResp.RepeatId != "" {
|
||||
sslId = *uploadCertificateResp.RepeatId
|
||||
}
|
||||
|
||||
if sslId == "" {
|
||||
return nil, fmt.Errorf("received empty certificate id, both `InstanceId` and `RepeatId` are empty")
|
||||
}
|
||||
|
||||
return &certmgr.UploadResult{
|
||||
CertId: sslId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, privkeyPEM string) (*certmgr.ReplaceResult, error) {
|
||||
return nil, certmgr.ErrUnsupported
|
||||
}
|
||||
|
||||
func createSDKClient(accessKey, secretKey, region string) (*bpcertificateservice.CERTIFICATESERVICE, error) {
|
||||
if region == "" {
|
||||
region = "ap-singapore-1" // 证书中心默认区域:新加坡
|
||||
}
|
||||
|
||||
config := bp.NewConfig().
|
||||
WithAkSk(accessKey, secretKey).
|
||||
WithRegion(region)
|
||||
|
||||
session, err := bpsesion.NewSession(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := bpcertificateservice.New(session, config)
|
||||
return client, nil
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package bytepluscertcenter_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/certmgr/internal/tester"
|
||||
impl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/byteplus-certcenter"
|
||||
)
|
||||
|
||||
var (
|
||||
fp = tester.Args("BYTEPLUSCERTCENTER_")
|
||||
fTestCertPath string
|
||||
fTestKeyPath string
|
||||
fAccessKey string
|
||||
fSecretKey string
|
||||
)
|
||||
|
||||
func init() {
|
||||
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
|
||||
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
|
||||
fp.DefineString(&fAccessKey, "ACCESSKEY")
|
||||
fp.DefineString(&fSecretKey, "SECRETKEY")
|
||||
}
|
||||
|
||||
/*
|
||||
Shell command to run this test:
|
||||
|
||||
go test -v ./byteplus_certcenter_test.go -args \
|
||||
--BYTEPLUSCERTCENTER_TESTCERTPATH="/path/to/your-test-cert.pem" \
|
||||
--BYTEPLUSCERTCENTER_TESTKEYPATH="/path/to/your-test-key.pem" \
|
||||
--BYTEPLUSCERTCENTER_ACCESSKEY="your-access-key" \
|
||||
--BYTEPLUSCERTCENTER_SECRETKEY="your-secret-key"
|
||||
*/
|
||||
func TestProvider(t *testing.T) {
|
||||
fp.Parse()
|
||||
|
||||
t.Run("Upload", func(t *testing.T) {
|
||||
provider, err := impl.NewCertmgr(&impl.CertmgrConfig{
|
||||
AccessKey: fAccessKey,
|
||||
SecretKey: fSecretKey,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("err: %+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
tester.TestUpload(t, provider, tester.TestUploadArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package bytepluscertcenter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/certmgr"
|
||||
certmgrimpl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/byteplus-certcenter"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
// BytePlus AccessKey。
|
||||
AccessKey string `json:"accessKey"`
|
||||
// BytePlus SecretKey。
|
||||
SecretKey string `json:"secretKey"`
|
||||
// BytePlus 项目名称。
|
||||
ProjectName string `json:"projectName,omitempty"`
|
||||
// BytePlus 地域。
|
||||
Region string `json:"region"`
|
||||
}
|
||||
|
||||
type Deployer struct {
|
||||
config *DeployerConfig
|
||||
logger *slog.Logger
|
||||
sdkCertmgr certmgr.Provider
|
||||
}
|
||||
|
||||
var _ deployer.Provider = (*Deployer)(nil)
|
||||
|
||||
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
|
||||
}
|
||||
|
||||
pcertmgr, err := certmgrimpl.NewCertmgr(&certmgrimpl.CertmgrConfig{
|
||||
AccessKey: config.AccessKey,
|
||||
SecretKey: config.SecretKey,
|
||||
ProjectName: config.ProjectName,
|
||||
Region: config.Region,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create certmgr: %w", err)
|
||||
}
|
||||
|
||||
return &Deployer{
|
||||
config: config,
|
||||
logger: slog.Default(),
|
||||
sdkCertmgr: pcertmgr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Deployer) SetLogger(logger *slog.Logger) {
|
||||
if logger == nil {
|
||||
d.logger = slog.New(slog.DiscardHandler)
|
||||
} else {
|
||||
d.logger = logger
|
||||
}
|
||||
|
||||
d.sdkCertmgr.SetLogger(logger)
|
||||
}
|
||||
|
||||
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*deployer.DeployResult, error) {
|
||||
// 上传证书
|
||||
upres, err := d.sdkCertmgr.Upload(ctx, certPEM, privkeyPEM)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
|
||||
} else {
|
||||
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
|
||||
}
|
||||
|
||||
return &deployer.DeployResult{}, nil
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package certificateservice
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/byteplusutil"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/response"
|
||||
)
|
||||
|
||||
const opUploadCertificate = "UploadCertificate"
|
||||
|
||||
func (c *CERTIFICATESERVICE) UploadCertificateRequest(input *UploadCertificateInput) (req *request.Request, output *UploadCertificateOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opUploadCertificate,
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &UploadCertificateInput{}
|
||||
}
|
||||
|
||||
output = &UploadCertificateOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
req.HTTPRequest.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *CERTIFICATESERVICE) UploadCertificateWithContext(ctx byteplus.Context, input *UploadCertificateInput, opts ...request.Option) (*UploadCertificateOutput, error) {
|
||||
req, out := c.UploadCertificateRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type UploadCertificateInput struct {
|
||||
_ struct{} `type:"structure" json:",omitempty"`
|
||||
|
||||
CertificateInfo *CertificateInfoForUploadCertificateInput `type:"structure" json:",omitempty"`
|
||||
|
||||
NoVerifyAndFixChain *bool `type:"boolean" json:",omitempty"`
|
||||
|
||||
ProjectName *string `type:"string" json:",omitempty"`
|
||||
|
||||
Repeatable *bool `type:"boolean" json:",omitempty"`
|
||||
|
||||
Tag *string `type:"string" json:",omitempty"`
|
||||
|
||||
Tags []*TagForUploadCertificateInput `type:"list" json:",omitempty"`
|
||||
}
|
||||
|
||||
func (s UploadCertificateInput) String() string {
|
||||
return byteplusutil.Prettify(s)
|
||||
}
|
||||
|
||||
func (s UploadCertificateInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
type UploadCertificateOutput struct {
|
||||
_ struct{} `type:"structure" json:",omitempty"`
|
||||
|
||||
Metadata *response.ResponseMetadata
|
||||
|
||||
InstanceId *string `type:"string" json:",omitempty"`
|
||||
|
||||
RepeatId *string `type:"string" json:",omitempty"`
|
||||
}
|
||||
|
||||
func (s UploadCertificateOutput) String() string {
|
||||
return byteplusutil.Prettify(s)
|
||||
}
|
||||
|
||||
func (s UploadCertificateOutput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
type CertificateInfoForUploadCertificateInput struct {
|
||||
_ struct{} `type:"structure" json:",omitempty"`
|
||||
|
||||
CertificateChain *string `type:"string" json:",omitempty"`
|
||||
|
||||
PrivateKey *string `type:"string" json:",omitempty"`
|
||||
}
|
||||
|
||||
func (s CertificateInfoForUploadCertificateInput) String() string {
|
||||
return byteplusutil.Prettify(s)
|
||||
}
|
||||
|
||||
func (s CertificateInfoForUploadCertificateInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
type TagForUploadCertificateInput struct {
|
||||
_ struct{} `type:"structure" json:",omitempty"`
|
||||
|
||||
Key *string `type:"string" json:",omitempty"`
|
||||
|
||||
Value *string `type:"string" json:",omitempty"`
|
||||
}
|
||||
|
||||
func (s TagForUploadCertificateInput) String() string {
|
||||
return byteplusutil.Prettify(s)
|
||||
}
|
||||
|
||||
func (s TagForUploadCertificateInput) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package certificateservice
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/byteplusquery"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/client"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/client/metadata"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/corehandlers"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/signer/byteplussign"
|
||||
)
|
||||
|
||||
type CERTIFICATESERVICE struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
const (
|
||||
ServiceName = "certificate_service"
|
||||
EndpointsID = ServiceName
|
||||
ServiceID = "certificate_service"
|
||||
)
|
||||
|
||||
func New(p client.ConfigProvider, cfgs ...*byteplus.Config) *CERTIFICATESERVICE {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
func newClient(cfg byteplus.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *CERTIFICATESERVICE {
|
||||
svc := &CERTIFICATESERVICE{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2021-06-01",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
svc.Handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
svc.Handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHandler)
|
||||
svc.Handlers.Sign.PushBackNamed(byteplussign.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(byteplusquery.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(byteplusquery.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(byteplusquery.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(byteplusquery.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *CERTIFICATESERVICE) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
Reference in New Issue
Block a user