refactor: extend qiniu sdk

This commit is contained in:
Fu Diwei
2024-10-31 11:37:03 +08:00
parent ce55365292
commit 3c3d4e9109
5 changed files with 338 additions and 251 deletions

View File

@@ -0,0 +1,69 @@
package uploader
import (
"context"
"fmt"
"time"
xerrors "github.com/pkg/errors"
"github.com/qiniu/go-sdk/v7/auth"
"github.com/usual2970/certimate/internal/pkg/utils/x509"
qiniuEx "github.com/usual2970/certimate/internal/pkg/vendors/qiniu-sdk"
)
type QiniuSSLCertUploaderConfig struct {
AccessKey string `json:"accessKey"`
SecretKey string `json:"secretKey"`
}
type QiniuSSLCertUploader struct {
config *QiniuSSLCertUploaderConfig
sdkClient *qiniuEx.Client
}
func NewQiniuSSLCertUploader(config *QiniuSSLCertUploaderConfig) (Uploader, error) {
client, err := (&QiniuSSLCertUploader{}).createSdkClient(
config.AccessKey,
config.SecretKey,
)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &QiniuSSLCertUploader{
config: config,
sdkClient: client,
}, nil
}
func (u *QiniuSSLCertUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *UploadResult, err error) {
// 解析证书内容
certX509, err := x509.ParseCertificateFromPEM(certPem)
if err != nil {
return nil, err
}
// 生成新证书名(需符合七牛云命名规则)
var certId, certName string
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
// 上传新证书
// REF: https://developer.qiniu.com/fusion/8593/interface-related-certificate
uploadSslCertResp, err := u.sdkClient.UploadSslCert(certName, certX509.Subject.CommonName, privkeyPem, certPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.UploadSslCert'")
}
certId = uploadSslCertResp.CertID
return &UploadResult{
CertId: certId,
CertName: certName,
}, nil
}
func (u *QiniuSSLCertUploader) createSdkClient(accessKey, secretKey string) (*qiniuEx.Client, error) {
credential := auth.New(accessKey, secretKey)
client := qiniuEx.NewClient(credential)
return client, nil
}

160
internal/pkg/vendors/qiniu-sdk/client.go vendored Normal file
View File

@@ -0,0 +1,160 @@
package qiniusdk
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/qiniu/go-sdk/v7/auth"
xhttp "github.com/usual2970/certimate/internal/utils/http"
)
const qiniuHost = "http://api.qiniu.com"
type Client struct {
mac *auth.Credentials
}
func NewClient(mac *auth.Credentials) *Client {
if mac == nil {
mac = auth.Default()
}
return &Client{mac: mac}
}
func (c *Client) GetDomainInfo(domain string) (*GetDomainInfoResponse, error) {
respBytes, err := c.sendReq(http.MethodGet, fmt.Sprintf("domain/%s", domain), nil)
if err != nil {
return nil, err
}
resp := &GetDomainInfoResponse{}
err = json.Unmarshal(respBytes, resp)
if err != nil {
return nil, err
}
if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 {
return nil, fmt.Errorf("code: %d, error: %s", *resp.Code, *resp.Error)
}
return resp, nil
}
func (c *Client) ModifyDomainHttpsConf(domain, certId string, forceHttps, http2Enable bool) (*ModifyDomainHttpsConfResponse, error) {
req := &ModifyDomainHttpsConfRequest{
DomainInfoHttpsData: DomainInfoHttpsData{
CertID: certId,
ForceHttps: forceHttps,
Http2Enable: http2Enable,
},
}
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
respBytes, err := c.sendReq(http.MethodPut, fmt.Sprintf("domain/%s/httpsconf", domain), bytes.NewReader(reqBytes))
if err != nil {
return nil, err
}
resp := &ModifyDomainHttpsConfResponse{}
err = json.Unmarshal(respBytes, resp)
if err != nil {
return nil, err
}
if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 {
return nil, fmt.Errorf("code: %d, error: %s", *resp.Code, *resp.Error)
}
return resp, nil
}
func (c *Client) EnableDomainHttps(domain, certId string, forceHttps, http2Enable bool) (*EnableDomainHttpsResponse, error) {
req := &EnableDomainHttpsRequest{
DomainInfoHttpsData: DomainInfoHttpsData{
CertID: certId,
ForceHttps: forceHttps,
Http2Enable: http2Enable,
},
}
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
respBytes, err := c.sendReq(http.MethodPut, fmt.Sprintf("domain/%s/sslize", domain), bytes.NewReader(reqBytes))
if err != nil {
return nil, err
}
resp := &EnableDomainHttpsResponse{}
err = json.Unmarshal(respBytes, resp)
if err != nil {
return nil, err
}
if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 {
return nil, fmt.Errorf("code: %d, error: %s", *resp.Code, *resp.Error)
}
return resp, nil
}
func (c *Client) UploadSslCert(name, commonName, pri, ca string) (*UploadSslCertResponse, error) {
req := &UploadSslCertRequest{
Name: name,
CommonName: commonName,
Pri: pri,
Ca: ca,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
respBytes, err := c.sendReq(http.MethodPost, "sslcert", bytes.NewReader(reqBytes))
if err != nil {
return nil, err
}
resp := &UploadSslCertResponse{}
err = json.Unmarshal(respBytes, resp)
if err != nil {
return nil, err
}
if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 {
return nil, fmt.Errorf("code: %d, error: %s", *resp.Code, *resp.Error)
}
return resp, nil
}
func (c *Client) sendReq(method string, path string, body io.Reader) ([]byte, error) {
req := xhttp.BuildReq(fmt.Sprintf("%s/%s", qiniuHost, path), method, body, map[string]string{
"Content-Type": "application/json",
})
if err := c.mac.AddToken(auth.TokenQBox, req); err != nil {
return nil, err
}
respBody, err := xhttp.ToRequest(req)
if err != nil {
return nil, err
}
defer respBody.Close()
res, err := io.ReadAll(respBody)
if err != nil {
return nil, err
}
return res, nil
}

View File

@@ -0,0 +1,53 @@
package qiniusdk
type UploadSslCertRequest struct {
Name string `json:"name"`
CommonName string `json:"common_name"`
Pri string `json:"pri"`
Ca string `json:"ca"`
}
type UploadSslCertResponse struct {
Code *int `json:"code,omitempty"`
Error *string `json:"error,omitempty"`
CertID string `json:"certID"`
}
type DomainInfoHttpsData struct {
CertID string `json:"certId"`
ForceHttps bool `json:"forceHttps"`
Http2Enable bool `json:"http2Enable"`
}
type GetDomainInfoResponse struct {
Code *int `json:"code,omitempty"`
Error *string `json:"error,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
CName string `json:"cname"`
Https *DomainInfoHttpsData `json:"https"`
PareDomain string `json:"pareDomain"`
OperationType string `json:"operationType"`
OperatingState string `json:"operatingState"`
OperatingStateDesc string `json:"operatingStateDesc"`
CreateAt string `json:"createAt"`
ModifyAt string `json:"modifyAt"`
}
type ModifyDomainHttpsConfRequest struct {
DomainInfoHttpsData
}
type ModifyDomainHttpsConfResponse struct {
Code *int `json:"code,omitempty"`
Error *string `json:"error,omitempty"`
}
type EnableDomainHttpsRequest struct {
DomainInfoHttpsData
}
type EnableDomainHttpsResponse struct {
Code *int `json:"code,omitempty"`
Error *string `json:"error,omitempty"`
}