refactor

refactor
This commit is contained in:
Fu Diwei 2024-10-18 12:16:14 +08:00
parent 3c4b7d251a
commit 3093fc6b02
12 changed files with 272 additions and 269 deletions

View File

@ -1,12 +1,13 @@
package applicant
import (
"certimate/internal/domain"
"encoding/json"
"fmt"
"os"
"github.com/go-acme/lego/v4/providers/dns/route53"
"certimate/internal/domain"
)
type aws struct {

View File

@ -1,68 +0,0 @@
package deployer
import (
"context"
"encoding/json"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"certimate/internal/domain"
)
type aliyun struct {
client *oss.Client
option *DeployerOption
infos []string
}
func NewAliyun(option *DeployerOption) (Deployer, error) {
access := &domain.AliyunAccess{}
json.Unmarshal([]byte(option.Access), access)
a := &aliyun{
option: option,
infos: make([]string, 0),
}
client, err := a.createClient(access.AccessKeyId, access.AccessKeySecret)
if err != nil {
return nil, err
}
a.client = client
return a, nil
}
func (a *aliyun) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
}
func (a *aliyun) GetInfo() []string {
return a.infos
}
func (a *aliyun) Deploy(ctx context.Context) error {
err := a.client.PutBucketCnameWithCertificate(getDeployString(a.option.DeployConfig, "bucket"), oss.PutBucketCname{
Cname: getDeployString(a.option.DeployConfig, "domain"),
CertificateConfiguration: &oss.CertificateConfiguration{
Certificate: a.option.Certificate.Certificate,
PrivateKey: a.option.Certificate.PrivateKey,
Force: true,
},
})
if err != nil {
return fmt.Errorf("deploy aliyun oss error: %w", err)
}
return nil
}
func (a *aliyun) createClient(accessKeyId, accessKeySecret string) (*oss.Client, error) {
client, err := oss.New(
getDeployString(a.option.DeployConfig, "endpoint"),
accessKeyId,
accessKeySecret,
)
if err != nil {
return nil, fmt.Errorf("create aliyun client error: %w", err)
}
return client, nil
}

View File

@ -14,63 +14,65 @@ import (
"certimate/internal/utils/rand"
)
type AliyunCdn struct {
type AliyunCDNDeployer struct {
client *cdn20180510.Client
option *DeployerOption
infos []string
}
func NewAliyunCdn(option *DeployerOption) (*AliyunCdn, error) {
func NewAliyunCdnDeployer(option *DeployerOption) (*AliyunCDNDeployer, error) {
access := &domain.AliyunAccess{}
json.Unmarshal([]byte(option.Access), access)
a := &AliyunCdn{
d := &AliyunCDNDeployer{
option: option,
}
client, err := a.createClient(access.AccessKeyId, access.AccessKeySecret)
client, err := d.createClient(access.AccessKeyId, access.AccessKeySecret)
if err != nil {
return nil, err
}
return &AliyunCdn{
return &AliyunCDNDeployer{
client: client,
option: option,
infos: make([]string, 0),
}, nil
}
func (a *AliyunCdn) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
func (d *AliyunCDNDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (a *AliyunCdn) GetInfo() []string {
return a.infos
func (d *AliyunCDNDeployer) GetInfo() []string {
return d.infos
}
func (a *AliyunCdn) Deploy(ctx context.Context) error {
certName := fmt.Sprintf("%s-%s-%s", a.option.Domain, a.option.DomainId, rand.RandStr(6))
func (deployer *AliyunCDNDeployer) Deploy(ctx context.Context) error {
certName := fmt.Sprintf("%s-%s-%s", deployer.option.Domain, deployer.option.DomainId, rand.RandStr(6))
setCdnDomainSSLCertificateRequest := &cdn20180510.SetCdnDomainSSLCertificateRequest{
DomainName: tea.String(getDeployString(a.option.DeployConfig, "domain")),
DomainName: tea.String(getDeployString(deployer.option.DeployConfig, "domain")),
CertName: tea.String(certName),
CertType: tea.String("upload"),
SSLProtocol: tea.String("on"),
SSLPub: tea.String(a.option.Certificate.Certificate),
SSLPri: tea.String(a.option.Certificate.PrivateKey),
SSLPub: tea.String(deployer.option.Certificate.Certificate),
SSLPri: tea.String(deployer.option.Certificate.PrivateKey),
CertRegion: tea.String("cn-hangzhou"),
}
runtime := &util.RuntimeOptions{}
resp, err := a.client.SetCdnDomainSSLCertificateWithOptions(setCdnDomainSSLCertificateRequest, runtime)
resp, err := deployer.client.SetCdnDomainSSLCertificateWithOptions(setCdnDomainSSLCertificateRequest, runtime)
if err != nil {
return err
}
a.infos = append(a.infos, toStr("cdn设置证书", resp))
deployer.infos = append(deployer.infos, toStr("cdn设置证书", resp))
return nil
}
func (a *AliyunCdn) createClient(accessKeyId, accessKeySecret string) (_result *cdn20180510.Client, _err error) {
func (d *AliyunCDNDeployer) createClient(accessKeyId, accessKeySecret string) (_result *cdn20180510.Client, _err error) {
config := &openapi.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),

View File

@ -19,63 +19,65 @@ import (
"certimate/internal/utils/rand"
)
type AliyunEsa struct {
type AliyunESADeployer struct {
client *dcdn20180115.Client
option *DeployerOption
infos []string
}
func NewAliyunEsa(option *DeployerOption) (*AliyunEsa, error) {
func NewAliyunEsaDeployer(option *DeployerOption) (*AliyunESADeployer, error) {
access := &domain.AliyunAccess{}
json.Unmarshal([]byte(option.Access), access)
a := &AliyunEsa{
d := &AliyunESADeployer{
option: option,
}
client, err := a.createClient(access.AccessKeyId, access.AccessKeySecret)
client, err := d.createClient(access.AccessKeyId, access.AccessKeySecret)
if err != nil {
return nil, err
}
return &AliyunEsa{
return &AliyunESADeployer{
client: client,
option: option,
infos: make([]string, 0),
}, nil
}
func (a *AliyunEsa) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
func (d *AliyunESADeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (a *AliyunEsa) GetInfo() []string {
return a.infos
func (d *AliyunESADeployer) GetInfo() []string {
return d.infos
}
func (a *AliyunEsa) Deploy(ctx context.Context) error {
certName := fmt.Sprintf("%s-%s-%s", a.option.Domain, a.option.DomainId, rand.RandStr(6))
func (d *AliyunESADeployer) Deploy(ctx context.Context) error {
certName := fmt.Sprintf("%s-%s-%s", d.option.Domain, d.option.DomainId, rand.RandStr(6))
setDcdnDomainSSLCertificateRequest := &dcdn20180115.SetDcdnDomainSSLCertificateRequest{
DomainName: tea.String(getDeployString(a.option.DeployConfig, "domain")),
DomainName: tea.String(getDeployString(d.option.DeployConfig, "domain")),
CertName: tea.String(certName),
CertType: tea.String("upload"),
SSLProtocol: tea.String("on"),
SSLPub: tea.String(a.option.Certificate.Certificate),
SSLPri: tea.String(a.option.Certificate.PrivateKey),
SSLPub: tea.String(d.option.Certificate.Certificate),
SSLPri: tea.String(d.option.Certificate.PrivateKey),
CertRegion: tea.String("cn-hangzhou"),
}
runtime := &util.RuntimeOptions{}
resp, err := a.client.SetDcdnDomainSSLCertificateWithOptions(setDcdnDomainSSLCertificateRequest, runtime)
resp, err := d.client.SetDcdnDomainSSLCertificateWithOptions(setDcdnDomainSSLCertificateRequest, runtime)
if err != nil {
return err
}
a.infos = append(a.infos, toStr("dcdn设置证书", resp))
d.infos = append(d.infos, toStr("dcdn设置证书", resp))
return nil
}
func (a *AliyunEsa) createClient(accessKeyId, accessKeySecret string) (_result *dcdn20180115.Client, _err error) {
func (d *AliyunESADeployer) createClient(accessKeyId, accessKeySecret string) (_result *dcdn20180115.Client, _err error) {
config := &openapi.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),

View File

@ -0,0 +1,70 @@
package deployer
import (
"context"
"encoding/json"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"certimate/internal/domain"
)
type AliyunOSSDeployer struct {
client *oss.Client
option *DeployerOption
infos []string
}
func NewAliyunOssDeployer(option *DeployerOption) (Deployer, error) {
access := &domain.AliyunAccess{}
json.Unmarshal([]byte(option.Access), access)
d := &AliyunOSSDeployer{
option: option,
infos: make([]string, 0),
}
client, err := d.createClient(access.AccessKeyId, access.AccessKeySecret)
if err != nil {
return nil, err
}
d.client = client
return d, nil
}
func (d *AliyunOSSDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (d *AliyunOSSDeployer) GetInfo() []string {
return d.infos
}
func (d *AliyunOSSDeployer) Deploy(ctx context.Context) error {
err := d.client.PutBucketCnameWithCertificate(getDeployString(d.option.DeployConfig, "bucket"), oss.PutBucketCname{
Cname: getDeployString(d.option.DeployConfig, "domain"),
CertificateConfiguration: &oss.CertificateConfiguration{
Certificate: d.option.Certificate.Certificate,
PrivateKey: d.option.Certificate.PrivateKey,
Force: true,
},
})
if err != nil {
return fmt.Errorf("deploy aliyun oss error: %w", err)
}
return nil
}
func (d *AliyunOSSDeployer) createClient(accessKeyId, accessKeySecret string) (*oss.Client, error) {
client, err := oss.New(
getDeployString(d.option.DeployConfig, "endpoint"),
accessKeyId,
accessKeySecret,
)
if err != nil {
return nil, fmt.Errorf("create aliyun client error: %w", err)
}
return client, nil
}

View File

@ -15,14 +15,14 @@ import (
)
const (
targetAliyunOss = "aliyun-oss"
targetAliyunCdn = "aliyun-cdn"
targetAliyunEsa = "aliyun-dcdn"
targetSSH = "ssh"
targetWebhook = "webhook"
targetTencentCdn = "tencent-cdn"
targetAliyunOSS = "aliyun-oss"
targetAliyunCDN = "aliyun-cdn"
targetAliyunESA = "aliyun-dcdn"
targetTencentCDN = "tencent-cdn"
targetQiniuCdn = "qiniu-cdn"
targetLocal = "local"
targetSSH = "ssh"
targetWebhook = "webhook"
)
type DeployerOption struct {
@ -60,7 +60,6 @@ func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error
}
for _, deployConfig := range deployConfigs {
deployer, err := getWithDeployConfig(record, cert, deployConfig)
if err != nil {
return nil, err
@ -96,23 +95,22 @@ func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, dep
}
switch deployConfig.Type {
case targetAliyunOss:
return NewAliyun(option)
case targetAliyunCdn:
return NewAliyunCdn(option)
case targetAliyunEsa:
return NewAliyunEsa(option)
case targetSSH:
return NewSSH(option)
case targetWebhook:
return NewWebhook(option)
case targetTencentCdn:
return NewTencentCdn(option)
case targetAliyunOSS:
return NewAliyunOssDeployer(option)
case targetAliyunCDN:
return NewAliyunCdnDeployer(option)
case targetAliyunESA:
return NewAliyunEsaDeployer(option)
case targetTencentCDN:
return NewTencentCDNDeployer(option)
case targetQiniuCdn:
return NewQiNiu(option)
return NewQiniuCDNDeployer(option)
case targetLocal:
return NewLocal(option), nil
return NewLocalDeployer(option)
case targetSSH:
return NewSSHDeployer(option)
case targetWebhook:
return NewWebhookDeployer(option)
}
return nil, errors.New("not implemented")
}

View File

@ -10,35 +10,35 @@ import (
"runtime"
)
type localAccess struct{}
type LocalAccess struct{}
type local struct {
type LocalDeployer struct {
option *DeployerOption
infos []string
}
func NewLocal(option *DeployerOption) *local {
return &local{
func NewLocalDeployer(option *DeployerOption) (Deployer, error) {
return &LocalDeployer{
option: option,
infos: make([]string, 0),
}
}, nil
}
func (l *local) GetID() string {
return fmt.Sprintf("%s-%s", l.option.AceessRecord.GetString("name"), l.option.AceessRecord.Id)
func (d *LocalDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (l *local) GetInfo() []string {
func (d *LocalDeployer) GetInfo() []string {
return []string{}
}
func (l *local) Deploy(ctx context.Context) error {
access := &localAccess{}
if err := json.Unmarshal([]byte(l.option.Access), access); err != nil {
func (d *LocalDeployer) Deploy(ctx context.Context) error {
access := &LocalAccess{}
if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
return err
}
preCommand := getDeployString(l.option.DeployConfig, "preCommand")
preCommand := getDeployString(d.option.DeployConfig, "preCommand")
if preCommand != "" {
if err := execCmd(preCommand); err != nil {
@ -46,18 +46,18 @@ func (l *local) Deploy(ctx context.Context) error {
}
}
// 复制文件
if err := copyFile(l.option.Certificate.Certificate, getDeployString(l.option.DeployConfig, "certPath")); err != nil {
// 复制证书文件
if err := copyFile(getDeployString(d.option.DeployConfig, "certPath"), d.option.Certificate.Certificate); err != nil {
return fmt.Errorf("复制证书失败: %w", err)
}
if err := copyFile(l.option.Certificate.PrivateKey, getDeployString(l.option.DeployConfig, "keyPath")); err != nil {
// 复制私钥文件
if err := copyFile(getDeployString(d.option.DeployConfig, "keyPath"), d.option.Certificate.PrivateKey); err != nil {
return fmt.Errorf("复制私钥失败: %w", err)
}
// 执行命令
if err := execCmd(getDeployString(l.option.DeployConfig, "command")); err != nil {
if err := execCmd(getDeployString(d.option.DeployConfig, "command")); err != nil {
return fmt.Errorf("执行命令失败: %w", err)
}
@ -85,7 +85,7 @@ func execCmd(command string) error {
return nil
}
func copyFile(content string, path string) error {
func copyFile(path string, content string) error {
dir := filepath.Dir(path)
// 如果目录不存在,创建目录

View File

@ -16,17 +16,17 @@ import (
const qiniuGateway = "http://api.qiniu.com"
type qiuniu struct {
type QiniuCDNDeployer struct {
option *DeployerOption
info []string
credentials *auth.Credentials
}
func NewQiNiu(option *DeployerOption) (*qiuniu, error) {
func NewQiniuCDNDeployer(option *DeployerOption) (*QiniuCDNDeployer, error) {
access := &domain.QiniuAccess{}
json.Unmarshal([]byte(option.Access), access)
return &qiuniu{
return &QiniuCDNDeployer{
option: option,
info: make([]string, 0),
@ -34,41 +34,39 @@ func NewQiNiu(option *DeployerOption) (*qiuniu, error) {
}, nil
}
func (a *qiuniu) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
func (d *QiniuCDNDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (q *qiuniu) GetInfo() []string {
return q.info
func (d *QiniuCDNDeployer) GetInfo() []string {
return d.info
}
func (q *qiuniu) Deploy(ctx context.Context) error {
func (d *QiniuCDNDeployer) Deploy(ctx context.Context) error {
// 上传证书
certId, err := q.uploadCert()
certId, err := d.uploadCert()
if err != nil {
return fmt.Errorf("uploadCert failed: %w", err)
}
// 获取域名信息
domainInfo, err := q.getDomainInfo()
domainInfo, err := d.getDomainInfo()
if err != nil {
return fmt.Errorf("getDomainInfo failed: %w", err)
}
// 判断域名是否启用 https
if domainInfo.Https != nil && domainInfo.Https.CertID != "" {
// 启用了 https
// 修改域名证书
err = q.modifyDomainCert(certId)
err = d.modifyDomainCert(certId)
if err != nil {
return fmt.Errorf("modifyDomainCert failed: %w", err)
}
} else {
// 没启用 https
// 启用 https
err = q.enableHttps(certId)
err = d.enableHttps(certId)
if err != nil {
return fmt.Errorf("enableHttps failed: %w", err)
}
@ -77,10 +75,10 @@ func (q *qiuniu) Deploy(ctx context.Context) error {
return nil
}
func (q *qiuniu) enableHttps(certId string) error {
path := fmt.Sprintf("/domain/%s/sslize", getDeployString(q.option.DeployConfig, "domain"))
func (d *QiniuCDNDeployer) enableHttps(certId string) error {
path := fmt.Sprintf("/domain/%s/sslize", getDeployString(d.option.DeployConfig, "domain"))
body := &modifyDomainCertReq{
body := &qiniuModifyDomainCertReq{
CertID: certId,
ForceHttps: true,
Http2Enable: true,
@ -91,7 +89,7 @@ func (q *qiuniu) enableHttps(certId string) error {
return fmt.Errorf("enable https failed: %w", err)
}
_, err = q.req(qiniuGateway+path, http.MethodPut, bytes.NewReader(bodyBytes))
_, err = d.req(qiniuGateway+path, http.MethodPut, bytes.NewReader(bodyBytes))
if err != nil {
return fmt.Errorf("enable https failed: %w", err)
}
@ -99,19 +97,19 @@ func (q *qiuniu) enableHttps(certId string) error {
return nil
}
type domainInfo struct {
Https *modifyDomainCertReq `json:"https"`
type qiniuDomainInfo struct {
Https *qiniuModifyDomainCertReq `json:"https"`
}
func (q *qiuniu) getDomainInfo() (*domainInfo, error) {
path := fmt.Sprintf("/domain/%s", getDeployString(q.option.DeployConfig, "domain"))
func (d *QiniuCDNDeployer) getDomainInfo() (*qiniuDomainInfo, error) {
path := fmt.Sprintf("/domain/%s", getDeployString(d.option.DeployConfig, "domain"))
res, err := q.req(qiniuGateway+path, http.MethodGet, nil)
res, err := d.req(qiniuGateway+path, http.MethodGet, nil)
if err != nil {
return nil, fmt.Errorf("req failed: %w", err)
}
resp := &domainInfo{}
resp := &qiniuDomainInfo{}
err = json.Unmarshal(res, resp)
if err != nil {
return nil, fmt.Errorf("json.Unmarshal failed: %w", err)
@ -120,25 +118,25 @@ func (q *qiuniu) getDomainInfo() (*domainInfo, error) {
return resp, nil
}
type uploadCertReq struct {
type qiniuUploadCertReq struct {
Name string `json:"name"`
CommonName string `json:"common_name"`
Pri string `json:"pri"`
Ca string `json:"ca"`
}
type uploadCertResp struct {
type qiniuUploadCertResp struct {
CertID string `json:"certID"`
}
func (q *qiuniu) uploadCert() (string, error) {
func (d *QiniuCDNDeployer) uploadCert() (string, error) {
path := "/sslcert"
body := &uploadCertReq{
Name: getDeployString(q.option.DeployConfig, "domain"),
CommonName: getDeployString(q.option.DeployConfig, "domain"),
Pri: q.option.Certificate.PrivateKey,
Ca: q.option.Certificate.Certificate,
body := &qiniuUploadCertReq{
Name: getDeployString(d.option.DeployConfig, "domain"),
CommonName: getDeployString(d.option.DeployConfig, "domain"),
Pri: d.option.Certificate.PrivateKey,
Ca: d.option.Certificate.Certificate,
}
bodyBytes, err := json.Marshal(body)
@ -146,11 +144,11 @@ func (q *qiuniu) uploadCert() (string, error) {
return "", fmt.Errorf("json.Marshal failed: %w", err)
}
res, err := q.req(qiniuGateway+path, http.MethodPost, bytes.NewReader(bodyBytes))
res, err := d.req(qiniuGateway+path, http.MethodPost, bytes.NewReader(bodyBytes))
if err != nil {
return "", fmt.Errorf("req failed: %w", err)
}
resp := &uploadCertResp{}
resp := &qiniuUploadCertResp{}
err = json.Unmarshal(res, resp)
if err != nil {
return "", fmt.Errorf("json.Unmarshal failed: %w", err)
@ -159,16 +157,16 @@ func (q *qiuniu) uploadCert() (string, error) {
return resp.CertID, nil
}
type modifyDomainCertReq struct {
type qiniuModifyDomainCertReq struct {
CertID string `json:"certId"`
ForceHttps bool `json:"forceHttps"`
Http2Enable bool `json:"http2Enable"`
}
func (q *qiuniu) modifyDomainCert(certId string) error {
path := fmt.Sprintf("/domain/%s/httpsconf", getDeployString(q.option.DeployConfig, "domain"))
func (d *QiniuCDNDeployer) modifyDomainCert(certId string) error {
path := fmt.Sprintf("/domain/%s/httpsconf", getDeployString(d.option.DeployConfig, "domain"))
body := &modifyDomainCertReq{
body := &qiniuModifyDomainCertReq{
CertID: certId,
ForceHttps: true,
Http2Enable: true,
@ -179,7 +177,7 @@ func (q *qiuniu) modifyDomainCert(certId string) error {
return fmt.Errorf("json.Marshal failed: %w", err)
}
_, err = q.req(qiniuGateway+path, http.MethodPut, bytes.NewReader(bodyBytes))
_, err = d.req(qiniuGateway+path, http.MethodPut, bytes.NewReader(bodyBytes))
if err != nil {
return fmt.Errorf("req failed: %w", err)
}
@ -187,12 +185,12 @@ func (q *qiuniu) modifyDomainCert(certId string) error {
return nil
}
func (q *qiuniu) req(url, method string, body io.Reader) ([]byte, error) {
func (d *QiniuCDNDeployer) req(url, method string, body io.Reader) ([]byte, error) {
req := xhttp.BuildReq(url, method, body, map[string]string{
"Content-Type": "application/json",
})
if err := q.credentials.AddToken(auth.TokenQBox, req); err != nil {
if err := d.credentials.AddToken(auth.TokenQBox, req); err != nil {
return nil, fmt.Errorf("credentials.AddToken failed: %w", err)
}

View File

@ -36,7 +36,7 @@ func Test_qiuniu_uploadCert(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
q, _ := NewQiNiu(tt.fields.option)
q, _ := NewQiniuCDNDeployer(tt.fields.option)
got, err := q.uploadCert()
if (err != nil) != tt.wantErr {
t.Errorf("qiuniu.uploadCert() error = %v, wantErr %v", err, tt.wantErr)
@ -78,7 +78,7 @@ func Test_qiuniu_modifyDomainCert(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
q, _ := NewQiNiu(tt.fields.option)
q, _ := NewQiniuCDNDeployer(tt.fields.option)
if err := q.modifyDomainCert(tt.args.certId); (err != nil) != tt.wantErr {
t.Errorf("qiuniu.modifyDomainCert() error = %v, wantErr %v", err, tt.wantErr)
}

View File

@ -12,12 +12,7 @@ import (
sshPkg "golang.org/x/crypto/ssh"
)
type ssh struct {
option *DeployerOption
infos []string
}
type sshAccess struct {
type SSHAccess struct {
Host string `json:"host"`
Port string `json:"port"`
Username string `json:"username"`
@ -26,71 +21,76 @@ type sshAccess struct {
KeyPassphrase string `json:"keyPassphrase"`
}
func NewSSH(option *DeployerOption) (Deployer, error) {
return &ssh{
type SSHDeployer struct {
option *DeployerOption
infos []string
}
func NewSSHDeployer(option *DeployerOption) (Deployer, error) {
return &SSHDeployer{
option: option,
infos: make([]string, 0),
}, nil
}
func (a *ssh) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
func (d *SSHDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (s *ssh) GetInfo() []string {
return s.infos
func (d *SSHDeployer) GetInfo() []string {
return d.infos
}
func (s *ssh) Deploy(ctx context.Context) error {
access := &sshAccess{}
if err := json.Unmarshal([]byte(s.option.Access), access); err != nil {
func (d *SSHDeployer) Deploy(ctx context.Context) error {
access := &SSHAccess{}
if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
return err
}
// 连接
client, err := s.getClient(access)
client, err := d.createClient(access)
if err != nil {
return err
}
defer client.Close()
s.infos = append(s.infos, toStr("ssh连接成功", nil))
d.infos = append(d.infos, toStr("ssh连接成功", nil))
// 执行前置命令
preCommand := getDeployString(s.option.DeployConfig, "preCommand")
preCommand := getDeployString(d.option.DeployConfig, "preCommand")
if preCommand != "" {
stdout, stderr, err := s.sshExecCommand(client, preCommand)
stdout, stderr, err := d.sshExecCommand(client, preCommand)
if err != nil {
return fmt.Errorf("failed to run pre-command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
}
}
// 上传证书
if err := s.upload(client, s.option.Certificate.Certificate, getDeployString(s.option.DeployConfig, "certPath")); err != nil {
if err := d.upload(client, d.option.Certificate.Certificate, getDeployString(d.option.DeployConfig, "certPath")); err != nil {
return fmt.Errorf("failed to upload certificate: %w", err)
}
s.infos = append(s.infos, toStr("ssh上传证书成功", nil))
d.infos = append(d.infos, toStr("ssh上传证书成功", nil))
// 上传私钥
if err := s.upload(client, s.option.Certificate.PrivateKey, getDeployString(s.option.DeployConfig, "keyPath")); err != nil {
if err := d.upload(client, d.option.Certificate.PrivateKey, getDeployString(d.option.DeployConfig, "keyPath")); err != nil {
return fmt.Errorf("failed to upload private key: %w", err)
}
s.infos = append(s.infos, toStr("ssh上传私钥成功", nil))
d.infos = append(d.infos, toStr("ssh上传私钥成功", nil))
// 执行命令
stdout, stderr, err := s.sshExecCommand(client, getDeployString(s.option.DeployConfig, "command"))
stdout, stderr, err := d.sshExecCommand(client, getDeployString(d.option.DeployConfig, "command"))
if err != nil {
return fmt.Errorf("failed to run command: %w, stdout: %s, stderr: %s", err, stdout, stderr)
}
s.infos = append(s.infos, toStr("ssh执行命令成功", stdout))
d.infos = append(d.infos, toStr("ssh执行命令成功", stdout))
return nil
}
func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (string, string, error) {
func (d *SSHDeployer) sshExecCommand(client *sshPkg.Client, command string) (string, string, error) {
session, err := client.NewSession()
if err != nil {
return "", "", fmt.Errorf("failed to create ssh session: %w", err)
@ -105,7 +105,7 @@ func (s *ssh) sshExecCommand(client *sshPkg.Client, command string) (string, str
return stdoutBuf.String(), stderrBuf.String(), err
}
func (s *ssh) upload(client *sshPkg.Client, content, path string) error {
func (d *SSHDeployer) upload(client *sshPkg.Client, content, path string) error {
sftpCli, err := sftp.NewClient(client)
if err != nil {
return fmt.Errorf("failed to create sftp client: %w", err)
@ -130,7 +130,7 @@ func (s *ssh) upload(client *sshPkg.Client, content, path string) error {
return nil
}
func (s *ssh) getClient(access *sshAccess) (*sshPkg.Client, error) {
func (d *SSHDeployer) createClient(access *SSHAccess) (*sshPkg.Client, error) {
var authMethod sshPkg.AuthMethod
if access.Key != "" {

View File

@ -16,13 +16,13 @@ import (
"certimate/internal/utils/rand"
)
type tencentCdn struct {
type TencentCDNDeployer struct {
option *DeployerOption
credential *common.Credential
infos []string
}
func NewTencentCdn(option *DeployerOption) (Deployer, error) {
func NewTencentCDNDeployer(option *DeployerOption) (Deployer, error) {
access := &domain.TencentAccess{}
if err := json.Unmarshal([]byte(option.Access), access); err != nil {
return nil, fmt.Errorf("failed to unmarshal tencent access: %w", err)
@ -33,47 +33,47 @@ func NewTencentCdn(option *DeployerOption) (Deployer, error) {
access.SecretKey,
)
return &tencentCdn{
return &TencentCDNDeployer{
option: option,
credential: credential,
infos: make([]string, 0),
}, nil
}
func (a *tencentCdn) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
func (d *TencentCDNDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (t *tencentCdn) GetInfo() []string {
return t.infos
func (d *TencentCDNDeployer) GetInfo() []string {
return d.infos
}
func (t *tencentCdn) Deploy(ctx context.Context) error {
func (d *TencentCDNDeployer) Deploy(ctx context.Context) error {
// 上传证书
certId, err := t.uploadCert()
certId, err := d.uploadCert()
if err != nil {
return fmt.Errorf("failed to upload certificate: %w", err)
}
t.infos = append(t.infos, toStr("上传证书", certId))
d.infos = append(d.infos, toStr("上传证书", certId))
if err := t.deploy(certId); err != nil {
if err := d.deploy(certId); err != nil {
return fmt.Errorf("failed to deploy: %w", err)
}
return nil
}
func (t *tencentCdn) uploadCert() (string, error) {
func (d *TencentCDNDeployer) uploadCert() (string, error) {
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = "ssl.tencentcloudapi.com"
client, _ := ssl.NewClient(t.credential, "", cpf)
client, _ := ssl.NewClient(d.credential, "", cpf)
request := ssl.NewUploadCertificateRequest()
request.CertificatePublicKey = common.StringPtr(t.option.Certificate.Certificate)
request.CertificatePrivateKey = common.StringPtr(t.option.Certificate.PrivateKey)
request.Alias = common.StringPtr(t.option.Domain + "_" + rand.RandStr(6))
request.CertificatePublicKey = common.StringPtr(d.option.Certificate.Certificate)
request.CertificatePrivateKey = common.StringPtr(d.option.Certificate.PrivateKey)
request.Alias = common.StringPtr(d.option.Domain + "_" + rand.RandStr(6))
request.Repeatable = common.BoolPtr(false)
response, err := client.UploadCertificate(request)
@ -84,11 +84,11 @@ func (t *tencentCdn) uploadCert() (string, error) {
return *response.Response.CertificateId, nil
}
func (t *tencentCdn) deploy(certId string) error {
func (d *TencentCDNDeployer) deploy(certId string) error {
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = "ssl.tencentcloudapi.com"
// 实例化要请求产品的client对象,clientProfile是可选的
client, _ := ssl.NewClient(t.credential, "", cpf)
client, _ := ssl.NewClient(d.credential, "", cpf)
// 实例化一个请求对象,每个接口都会对应一个request对象
request := ssl.NewDeployCertificateInstanceRequest()
@ -98,9 +98,9 @@ func (t *tencentCdn) deploy(certId string) error {
request.Status = common.Int64Ptr(1)
// 如果是泛域名就从cdn列表下获取SSL证书中的可用域名
domain := getDeployString(t.option.DeployConfig, "domain")
domain := getDeployString(d.option.DeployConfig, "domain")
if strings.Contains(domain, "*") {
list, errGetList := t.getDomainList()
list, errGetList := d.getDomainList()
if errGetList != nil {
return fmt.Errorf("failed to get certificate domain list: %w", errGetList)
}
@ -117,18 +117,18 @@ func (t *tencentCdn) deploy(certId string) error {
if err != nil {
return fmt.Errorf("failed to deploy certificate: %w", err)
}
t.infos = append(t.infos, toStr("部署证书", resp.Response))
d.infos = append(d.infos, toStr("部署证书", resp.Response))
return nil
}
func (t *tencentCdn) getDomainList() ([]string, error) {
func (d *TencentCDNDeployer) getDomainList() ([]string, error) {
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = "cdn.tencentcloudapi.com"
client, _ := cdn.NewClient(t.credential, "", cpf)
client, _ := cdn.NewClient(d.credential, "", cpf)
request := cdn.NewDescribeCertDomainsRequest()
cert := base64.StdEncoding.EncodeToString([]byte(t.option.Certificate.Certificate))
cert := base64.StdEncoding.EncodeToString([]byte(d.option.Certificate.Certificate))
request.Cert = &cert
response, err := client.DescribeCertDomains(request)

View File

@ -10,48 +10,48 @@ import (
xhttp "certimate/internal/utils/http"
)
type webhookAccess struct {
type WebhookAccess struct {
Url string `json:"url"`
}
type hookData struct {
type WebhookDeployer struct {
option *DeployerOption
infos []string
}
func NewWebhookDeployer(option *DeployerOption) (Deployer, error) {
return &WebhookDeployer{
option: option,
infos: make([]string, 0),
}, nil
}
func (d *WebhookDeployer) GetID() string {
return fmt.Sprintf("%s-%s", d.option.AceessRecord.GetString("name"), d.option.AceessRecord.Id)
}
func (d *WebhookDeployer) GetInfo() []string {
return d.infos
}
type webhookData struct {
Domain string `json:"domain"`
Certificate string `json:"certificate"`
PrivateKey string `json:"privateKey"`
Variables map[string]string `json:"variables"`
}
type webhook struct {
option *DeployerOption
infos []string
}
func NewWebhook(option *DeployerOption) (Deployer, error) {
return &webhook{
option: option,
infos: make([]string, 0),
}, nil
}
func (a *webhook) GetID() string {
return fmt.Sprintf("%s-%s", a.option.AceessRecord.GetString("name"), a.option.AceessRecord.Id)
}
func (w *webhook) GetInfo() []string {
return w.infos
}
func (w *webhook) Deploy(ctx context.Context) error {
access := &webhookAccess{}
if err := json.Unmarshal([]byte(w.option.Access), access); err != nil {
func (d *WebhookDeployer) Deploy(ctx context.Context) error {
access := &WebhookAccess{}
if err := json.Unmarshal([]byte(d.option.Access), access); err != nil {
return fmt.Errorf("failed to parse hook access config: %w", err)
}
data := &hookData{
Domain: w.option.Domain,
Certificate: w.option.Certificate.Certificate,
PrivateKey: w.option.Certificate.PrivateKey,
Variables: getDeployVariables(w.option.DeployConfig),
data := &webhookData{
Domain: d.option.Domain,
Certificate: d.option.Certificate.Certificate,
PrivateKey: d.option.Certificate.PrivateKey,
Variables: getDeployVariables(d.option.DeployConfig),
}
body, _ := json.Marshal(data)
@ -63,7 +63,7 @@ func (w *webhook) Deploy(ctx context.Context) error {
return fmt.Errorf("failed to send hook request: %w", err)
}
w.infos = append(w.infos, toStr("webhook response", string(resp)))
d.infos = append(d.infos, toStr("webhook response", string(resp)))
return nil
}