mirror of https://github.com/usual2970/certimate
				
				
				
			
		
			
				
	
	
		
			203 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
| package deployer
 | |
| 
 | |
| import (
 | |
| 	"certimate/internal/applicant"
 | |
| 	"certimate/internal/domain"
 | |
| 	"certimate/internal/utils/rand"
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 
 | |
| 	cas20200407 "github.com/alibabacloud-go/cas-20200407/v2/client"
 | |
| 	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
 | |
| 	util "github.com/alibabacloud-go/tea-utils/v2/service"
 | |
| 	"github.com/alibabacloud-go/tea/tea"
 | |
| )
 | |
| 
 | |
| type aliyun struct {
 | |
| 	client *cas20200407.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) GetInfo() []string {
 | |
| 	return a.infos
 | |
| }
 | |
| 
 | |
| func (a *aliyun) Deploy(ctx context.Context) error {
 | |
| 
 | |
| 	// 查询有没有对应的资源
 | |
| 	resource, err := a.resource()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	a.infos = append(a.infos, toStr("查询对应的资源", resource))
 | |
| 
 | |
| 	// 查询有没有对应的联系人
 | |
| 	contacts, err := a.contacts()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	a.infos = append(a.infos, toStr("查询联系人", contacts))
 | |
| 
 | |
| 	// 上传证书
 | |
| 	certId, err := a.uploadCert(&a.option.Certificate)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	a.infos = append(a.infos, toStr("上传证书", certId))
 | |
| 
 | |
| 	// 部署证书
 | |
| 	jobId, err := a.deploy(resource, certId, contacts)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	a.infos = append(a.infos, toStr("创建部署证书任务", jobId))
 | |
| 
 | |
| 	// 等待部署成功
 | |
| 	err = a.updateDeployStatus(*jobId)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	// 部署成功后删除旧的证书
 | |
| 	a.deleteCert(resource)
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) updateDeployStatus(jobId int64) error {
 | |
| 	// 查询部署状态
 | |
| 	req := &cas20200407.UpdateDeploymentJobStatusRequest{
 | |
| 		JobId: tea.Int64(jobId),
 | |
| 	}
 | |
| 
 | |
| 	resp, err := a.client.UpdateDeploymentJobStatus(req)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	a.infos = append(a.infos, toStr("查询对应的资源", resp))
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) deleteCert(resource *cas20200407.ListCloudResourcesResponseBodyData) error {
 | |
| 	// 查询有没有对应的资源
 | |
| 	if resource.CertId == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	// 删除证书
 | |
| 	_, err := a.client.DeleteUserCertificate(&cas20200407.DeleteUserCertificateRequest{
 | |
| 		CertId: resource.CertId,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) contacts() ([]*cas20200407.ListContactResponseBodyContactList, error) {
 | |
| 	listContactRequest := &cas20200407.ListContactRequest{}
 | |
| 	runtime := &util.RuntimeOptions{}
 | |
| 
 | |
| 	resp, err := a.client.ListContactWithOptions(listContactRequest, runtime)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	if resp.Body.TotalCount == nil {
 | |
| 		return nil, errors.New("no contact found")
 | |
| 	}
 | |
| 
 | |
| 	return resp.Body.ContactList, nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) deploy(resource *cas20200407.ListCloudResourcesResponseBodyData, certId int64, contacts []*cas20200407.ListContactResponseBodyContactList) (*int64, error) {
 | |
| 	contactIds := make([]string, 0, len(contacts))
 | |
| 	for _, contact := range contacts {
 | |
| 		contactIds = append(contactIds, fmt.Sprintf("%d", *contact.ContactId))
 | |
| 	}
 | |
| 	// 部署证书
 | |
| 	createCloudResourceRequest := &cas20200407.CreateDeploymentJobRequest{
 | |
| 		CertIds:     tea.String(fmt.Sprintf("%d", certId)),
 | |
| 		Name:        tea.String(a.option.Domain + rand.RandStr(6)),
 | |
| 		JobType:     tea.String("user"),
 | |
| 		ResourceIds: tea.String(fmt.Sprintf("%d", *resource.Id)),
 | |
| 		ContactIds:  tea.String(strings.Join(contactIds, ",")),
 | |
| 	}
 | |
| 	runtime := &util.RuntimeOptions{}
 | |
| 
 | |
| 	resp, err := a.client.CreateDeploymentJobWithOptions(createCloudResourceRequest, runtime)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return resp.Body.JobId, nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) uploadCert(cert *applicant.Certificate) (int64, error) {
 | |
| 	uploadUserCertificateRequest := &cas20200407.UploadUserCertificateRequest{
 | |
| 		Cert: &cert.Certificate,
 | |
| 		Key:  &cert.PrivateKey,
 | |
| 		Name: tea.String(a.option.Domain + rand.RandStr(6)),
 | |
| 	}
 | |
| 	runtime := &util.RuntimeOptions{}
 | |
| 
 | |
| 	resp, err := a.client.UploadUserCertificateWithOptions(uploadUserCertificateRequest, runtime)
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 
 | |
| 	return *resp.Body.CertId, nil
 | |
| }
 | |
| 
 | |
| func (a *aliyun) createClient(accessKeyId, accessKeySecret string) (_result *cas20200407.Client, _err error) {
 | |
| 	config := &openapi.Config{
 | |
| 		AccessKeyId:     tea.String(accessKeyId),
 | |
| 		AccessKeySecret: tea.String(accessKeySecret),
 | |
| 	}
 | |
| 	config.Endpoint = tea.String("cas.aliyuncs.com")
 | |
| 	_result = &cas20200407.Client{}
 | |
| 	_result, _err = cas20200407.NewClient(config)
 | |
| 	return _result, _err
 | |
| }
 | |
| 
 | |
| func (a *aliyun) resource() (*cas20200407.ListCloudResourcesResponseBodyData, error) {
 | |
| 
 | |
| 	listCloudResourcesRequest := &cas20200407.ListCloudResourcesRequest{
 | |
| 		CloudProduct: tea.String(a.option.Product),
 | |
| 		Keyword:      tea.String(a.option.Domain),
 | |
| 	}
 | |
| 
 | |
| 	resp, err := a.client.ListCloudResources(listCloudResourcesRequest)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if *resp.Body.Total == 0 {
 | |
| 		return nil, errors.New("no resource found")
 | |
| 	}
 | |
| 
 | |
| 	return resp.Body.Data[0], nil
 | |
| }
 |