mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-01 15:39:35 +08:00
refactor: use xwait utils instead of time.Sleep
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type delayNodeExecutor struct {
|
||||
@@ -16,7 +18,7 @@ func (ne *delayNodeExecutor) Execute(execCtx *NodeExecutionContext) (*NodeExecut
|
||||
nodeCfg := execCtx.Node.Data.Config.AsDelay()
|
||||
ne.logger.Info(fmt.Sprintf("delay for %d second(s) before continuing ...", nodeCfg.Wait))
|
||||
|
||||
time.Sleep(time.Duration(nodeCfg.Wait) * time.Second)
|
||||
xwait.DelayWithContext(execCtx.ctx, time.Duration(nodeCfg.Wait)*time.Second)
|
||||
|
||||
return execRes, nil
|
||||
}
|
||||
|
||||
@@ -127,7 +127,24 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*cert
|
||||
}
|
||||
|
||||
func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, privkeyPEM string) (*certmgr.OperateResult, error) {
|
||||
return nil, certmgr.ErrUnsupported
|
||||
certId := certIdOrName
|
||||
certName := fmt.Sprintf("certimate_%d", time.Now().UnixMilli())
|
||||
|
||||
// 修改证书
|
||||
// REF: https://www.wangsu.com/document/api-doc/25568?productCode=certificatemanagement
|
||||
updateCertificateReq := &wangsusdk.UpdateCertificateRequest{
|
||||
Name: lo.ToPtr(certName),
|
||||
Certificate: lo.ToPtr(certPEM),
|
||||
PrivateKey: lo.ToPtr(privkeyPEM),
|
||||
Comment: lo.ToPtr("upload from certimate"),
|
||||
}
|
||||
updateCertificateResp, err := c.sdkClient.UpdateCertificate(certId, updateCertificateReq)
|
||||
c.logger.Debug("sdk request 'certificatemanagement.UpdateCertificate'", slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanagement.UpdateCertificate': %w", err)
|
||||
}
|
||||
|
||||
return &certmgr.OperateResult{}, nil
|
||||
}
|
||||
|
||||
func createSDKClient(accessKeyId, accessKeySecret string) (*wangsusdk.Client, error) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
onepanelsdk "github.com/certimate-go/certimate/pkg/sdk3rd/1panel"
|
||||
onepanelsdk2 "github.com/certimate-go/certimate/pkg/sdk3rd/1panel/v2"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -163,7 +164,7 @@ func (d *Deployer) deployToWebsite(ctx context.Context, certPEM, privkeyPEM stri
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if i < len(websiteIds)-1 {
|
||||
time.Sleep(time.Second * 5)
|
||||
xwait.DelayWithContext(ctx, time.Second*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/aliyun-cas"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/providers/aliyun-cas-deploy/internal"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -129,33 +130,29 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.CreateDeploymentJob': %w", err)
|
||||
}
|
||||
|
||||
// 循环获取部署任务详情,等待任务状态变更
|
||||
// 获取部署任务详情,等待任务状态变更
|
||||
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-describedeploymentjob
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeDeploymentJobReq := &alicas.DescribeDeploymentJobRequest{
|
||||
JobId: createDeploymentJobResp.Body.JobId,
|
||||
}
|
||||
describeDeploymentJobResp, err := d.sdkClient.DescribeDeploymentJobWithContext(ctx, describeDeploymentJobReq, &dara.RuntimeOptions{})
|
||||
d.logger.Debug("sdk request 'cas.DescribeDeploymentJob'", slog.Any("request", describeDeploymentJobReq), slog.Any("response", describeDeploymentJobResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.DescribeDeploymentJob': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'cas.DescribeDeploymentJob': %w", err)
|
||||
}
|
||||
|
||||
status := tea.StringValue(describeDeploymentJobResp.Body.Status)
|
||||
if status == "" || status == "editing" {
|
||||
return nil, errors.New("unexpected aliyun deployment job status")
|
||||
} else if status == "success" || status == "error" {
|
||||
break
|
||||
switch tea.StringValue(describeDeploymentJobResp.Body.Status) {
|
||||
case "success", "error":
|
||||
return true, nil
|
||||
case "", "editing":
|
||||
return false, fmt.Errorf("unexpected aliyun deployment job status")
|
||||
}
|
||||
|
||||
d.logger.Info("waiting for aliyun deployment job completion ...")
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &deployer.DeployResult{}, nil
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
btsdk "github.com/certimate-go/certimate/pkg/sdk3rd/btpanel"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -108,7 +109,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if i < len(d.config.SiteNames)-1 {
|
||||
time.Sleep(time.Second * 5)
|
||||
xwait.DelayWithContext(ctx, time.Second*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
btsdk "github.com/certimate-go/certimate/pkg/sdk3rd/btpanelgo"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -85,7 +86,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if i < len(d.config.SiteNames)-1 {
|
||||
time.Sleep(time.Second * 5)
|
||||
xwait.DelayWithContext(ctx, time.Second*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
btwafsdk "github.com/certimate-go/certimate/pkg/sdk3rd/btwaf"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -77,7 +78,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if i < len(d.config.SiteNames)-1 {
|
||||
time.Sleep(time.Second * 5)
|
||||
xwait.DelayWithContext(ctx, time.Second*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
npmsdk "github.com/certimate-go/certimate/pkg/sdk3rd/nginxproxymanager"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -201,7 +202,7 @@ func (d *Deployer) deployToHost(ctx context.Context, certPEM, privkeyPEM string)
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if i < len(hostIds)-1 {
|
||||
time.Sleep(time.Second * 5)
|
||||
xwait.DelayWithContext(ctx, time.Second*5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ func (d *Deployer) deployToCertificate(ctx context.Context, certPEM, privkeyPEM
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置站点 SSL 证书
|
||||
// 更新 SSL 证书
|
||||
certUpdateReq := &ratpanelsdk.CertUpdateRequest{
|
||||
CertId: d.config.CertificateId,
|
||||
Type: "upload",
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/tencentcloud-ssl"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/providers/tencentcloud-clb/internal"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -217,32 +218,28 @@ func (d *Deployer) deployToRuleDomain(ctx context.Context, cloudCertId string) e
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.ModifyDomainAttributes': %w", err)
|
||||
}
|
||||
|
||||
// 循环查询异步任务状态,等待任务状态变更
|
||||
// 查询异步任务状态,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/product/214/30683
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeTaskStatusReq := tcclb.NewDescribeTaskStatusRequest()
|
||||
describeTaskStatusReq.TaskId = modifyDomainAttributesResp.Response.RequestId
|
||||
describeTaskStatusResp, err := d.sdkClient.DescribeTaskStatus(describeTaskStatusReq)
|
||||
d.logger.Debug("sdk request 'clb.DescribeTaskStatus'", slog.Any("request", describeTaskStatusReq), slog.Any("response", describeTaskStatusResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
}
|
||||
|
||||
status := lo.FromPtr(describeTaskStatusResp.Response.Status)
|
||||
if status == 1 {
|
||||
return errors.New("unexpected tencentcloud task status")
|
||||
} else if status == 0 {
|
||||
break
|
||||
switch lo.FromPtr(describeTaskStatusResp.Response.Status) {
|
||||
case 0:
|
||||
return true, nil
|
||||
case 1:
|
||||
return false, fmt.Errorf("unexpected tencentcloud task status")
|
||||
}
|
||||
|
||||
d.logger.Info("waiting for tencentcloud task completion ...")
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -280,32 +277,28 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudLoadbalan
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.ModifyListener': %w", err)
|
||||
}
|
||||
|
||||
// 循环查询异步任务状态,等待任务状态变更
|
||||
// 查询异步任务状态,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/product/214/30683
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeTaskStatusReq := tcclb.NewDescribeTaskStatusRequest()
|
||||
describeTaskStatusReq.TaskId = modifyListenerResp.Response.RequestId
|
||||
describeTaskStatusResp, err := d.sdkClient.DescribeTaskStatus(describeTaskStatusReq)
|
||||
d.logger.Debug("sdk request 'clb.DescribeTaskStatus'", slog.Any("request", describeTaskStatusReq), slog.Any("response", describeTaskStatusResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
}
|
||||
|
||||
status := lo.FromPtr(describeTaskStatusResp.Response.Status)
|
||||
if status == 1 {
|
||||
return errors.New("unexpected tencentcloud task status")
|
||||
} else if status == 0 {
|
||||
break
|
||||
switch lo.FromPtr(describeTaskStatusResp.Response.Status) {
|
||||
case 0:
|
||||
return true, nil
|
||||
case 1:
|
||||
return false, fmt.Errorf("unexpected tencentcloud task status")
|
||||
}
|
||||
|
||||
d.logger.Info("waiting for tencentcloud task completion ...")
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/tencentcloud-ssl"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/providers/tencentcloud-cos/internal"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -115,26 +116,20 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
||||
}
|
||||
|
||||
// 循环获取部署任务详情,等待任务状态变更
|
||||
// 获取部署任务详情,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/api/400/91658
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||
describeHostDeployRecordDetailResp, err := d.sdkClient.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||
}
|
||||
|
||||
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||
return nil, errors.New("unexpected tencentcloud deployment job status")
|
||||
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
|
||||
@@ -144,14 +139,16 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
return nil, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
}
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
d.logger.Info(fmt.Sprintf("waiting for tencentcloud deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &deployer.DeployResult{}, nil
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/tencentcloud-ssl"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/providers/tencentcloud-ssl-deploy/internal"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -110,27 +111,21 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
return nil, errors.New("failed to create deploy record")
|
||||
}
|
||||
|
||||
// 循环获取部署任务详情,等待任务状态变更
|
||||
// 获取部署任务详情,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/api/400/91658
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||
describeHostDeployRecordDetailReq.Limit = common.Uint64Ptr(200)
|
||||
describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||
}
|
||||
|
||||
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||
return nil, errors.New("unexpected tencentcloud deployment job status")
|
||||
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
|
||||
@@ -140,14 +135,16 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
return nil, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
}
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
d.logger.Info(fmt.Sprintf("waiting for tencentcloud deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &deployer.DeployResult{}, nil
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/tencentcloud-ssl"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/providers/tencentcloud-ssl-update/internal"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -115,13 +116,7 @@ func (d *Deployer) executeUpdateCertificateInstance(ctx context.Context, certPEM
|
||||
// 一键更新新旧证书资源
|
||||
// REF: https://cloud.tencent.com/document/product/400/91649
|
||||
var deployRecordId string
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
updateCertificateInstanceReq := tcssl.NewUpdateCertificateInstanceRequest()
|
||||
updateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificateId)
|
||||
updateCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
|
||||
@@ -130,40 +125,36 @@ func (d *Deployer) executeUpdateCertificateInstance(ctx context.Context, certPEM
|
||||
updateCertificateInstanceResp, err := d.sdkClient.UpdateCertificateInstance(updateCertificateInstanceReq)
|
||||
d.logger.Debug("sdk request 'ssl.UpdateCertificateInstance'", slog.Any("request", updateCertificateInstanceReq), slog.Any("response", updateCertificateInstanceResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'ssl.UpdateCertificateInstance': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.UpdateCertificateInstance': %w", err)
|
||||
}
|
||||
|
||||
if updateCertificateInstanceResp.Response.DeployStatus == nil || updateCertificateInstanceResp.Response.DeployRecordId == nil {
|
||||
return errors.New("unexpected deployment job status")
|
||||
return false, fmt.Errorf("unexpected deployment job status")
|
||||
} else if *updateCertificateInstanceResp.Response.DeployRecordId > 0 {
|
||||
deployRecordId = fmt.Sprintf("%d", *updateCertificateInstanceResp.Response.DeployRecordId)
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 循环查询证书云资源更新记录详情,等待任务状态变更
|
||||
// 查询证书云资源更新记录详情,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/api/400/91652
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeHostUpdateRecordDetailReq := tcssl.NewDescribeHostUpdateRecordDetailRequest()
|
||||
describeHostUpdateRecordDetailReq.DeployRecordId = common.StringPtr(deployRecordId)
|
||||
describeHostUpdateRecordDetailReq.Limit = common.StringPtr("200")
|
||||
describeHostUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUpdateRecordDetail(describeHostUpdateRecordDetailReq)
|
||||
d.logger.Debug("sdk request 'ssl.DescribeHostUpdateRecordDetail'", slog.Any("request", describeHostUpdateRecordDetailReq), slog.Any("response", describeHostUpdateRecordDetailResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUpdateRecordDetail': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUpdateRecordDetail': %w", err)
|
||||
}
|
||||
|
||||
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
|
||||
if describeHostUpdateRecordDetailResp.Response.TotalCount == nil {
|
||||
return errors.New("unexpected tencentcloud deployment job status")
|
||||
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
pendingCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.RunningTotalCount)
|
||||
@@ -173,14 +164,16 @@ func (d *Deployer) executeUpdateCertificateInstance(ctx context.Context, certPEM
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
return fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
}
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
d.logger.Info(fmt.Sprintf("waiting for tencentcloud deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -190,13 +183,7 @@ func (d *Deployer) executeUploadUpdateCertificateInstance(ctx context.Context, c
|
||||
// 更新证书内容并更新关联的云资源
|
||||
// REF: https://cloud.tencent.com/document/product/400/119791
|
||||
var deployRecordId int64
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
uploadUpdateCertificateInstanceReq := tcssl.NewUploadUpdateCertificateInstanceRequest()
|
||||
uploadUpdateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificateId)
|
||||
uploadUpdateCertificateInstanceReq.CertificatePublicKey = common.StringPtr(certPEM)
|
||||
@@ -206,40 +193,36 @@ func (d *Deployer) executeUploadUpdateCertificateInstance(ctx context.Context, c
|
||||
uploadUpdateCertificateInstanceResp, err := d.sdkClient.UploadUpdateCertificateInstance(uploadUpdateCertificateInstanceReq)
|
||||
d.logger.Debug("sdk request 'ssl.UploadUpdateCertificateInstance'", slog.Any("request", uploadUpdateCertificateInstanceReq), slog.Any("response", uploadUpdateCertificateInstanceResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'ssl.UploadUpdateCertificateInstance': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.UploadUpdateCertificateInstance': %w", err)
|
||||
}
|
||||
|
||||
if uploadUpdateCertificateInstanceResp.Response.DeployStatus == nil {
|
||||
return errors.New("unexpected deployment job status")
|
||||
return false, fmt.Errorf("unexpected deployment job status")
|
||||
} else if *uploadUpdateCertificateInstanceResp.Response.DeployStatus == 1 {
|
||||
deployRecordId = int64(*uploadUpdateCertificateInstanceResp.Response.DeployRecordId)
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 循环查询证书云资源更新记录详情,等待任务状态变更
|
||||
// 查询证书云资源更新记录详情,等待任务状态变更
|
||||
// REF: https://cloud.tencent.com/document/product/400/120056
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
describeHostUploadUpdateRecordDetailReq := tcssl.NewDescribeHostUploadUpdateRecordDetailRequest()
|
||||
describeHostUploadUpdateRecordDetailReq.DeployRecordId = common.Int64Ptr(deployRecordId)
|
||||
describeHostUploadUpdateRecordDetailReq.Limit = common.Int64Ptr(200)
|
||||
describeHostUploadUpdateRecordDetailResp, err := d.sdkClient.DescribeHostUploadUpdateRecordDetail(describeHostUploadUpdateRecordDetailReq)
|
||||
d.logger.Debug("sdk request 'ssl.DescribeHostUploadUpdateRecordDetail'", slog.Any("request", describeHostUploadUpdateRecordDetailReq), slog.Any("response", describeHostUploadUpdateRecordDetailResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUploadUpdateRecordDetail': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostUploadUpdateRecordDetail': %w", err)
|
||||
}
|
||||
|
||||
var runningCount, succeededCount, failedCount, totalCount int64
|
||||
if describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail == nil {
|
||||
return errors.New("unexpected tencentcloud deployment job status")
|
||||
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
for _, record := range describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail {
|
||||
runningCount += lo.FromPtr(record.RunningTotalCount)
|
||||
@@ -250,14 +233,16 @@ func (d *Deployer) executeUploadUpdateCertificateInstance(ctx context.Context, c
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
return fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
|
||||
}
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
d.logger.Info(fmt.Sprintf("waiting for tencentcloud deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer"
|
||||
wangsucdn "github.com/certimate-go/certimate/pkg/sdk3rd/wangsu/cdnpro"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
xwait "github.com/certimate-go/certimate/pkg/utils/wait"
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
@@ -174,6 +175,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
|
||||
// 创建部署任务
|
||||
// REF: https://www.wangsu.com/document/api-doc/27034
|
||||
var wangsuTaskId string
|
||||
createDeploymentTaskReq := &wangsucdn.CreateDeploymentTaskRequest{
|
||||
Name: lo.ToPtr(fmt.Sprintf("certimate_%d", time.Now().UnixMilli())),
|
||||
Target: lo.ToPtr(d.config.Environment),
|
||||
@@ -192,36 +194,32 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
d.logger.Debug("sdk request 'cdnpro.CreateCertificate'", slog.Any("request", createDeploymentTaskReq), slog.Any("response", createDeploymentTaskResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdnpro.CreateDeploymentTask': %w", err)
|
||||
}
|
||||
|
||||
// 循环获取部署任务详细信息,等待任务状态变更
|
||||
// REF: https://www.wangsu.com/document/api-doc/27038
|
||||
var wangsuTaskId string
|
||||
wangsuTaskMatches := regexp.MustCompile(`/deploymentTasks/([a-zA-Z0-9-]+)`).FindStringSubmatch(createDeploymentTaskResp.DeploymentTaskLocation)
|
||||
if len(wangsuTaskMatches) > 1 {
|
||||
wangsuTaskId = wangsuTaskMatches[1]
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
} else {
|
||||
wangsuTaskMatches := regexp.MustCompile(`/deploymentTasks/([a-zA-Z0-9-]+)`).FindStringSubmatch(createDeploymentTaskResp.DeploymentTaskLocation)
|
||||
if len(wangsuTaskMatches) > 1 {
|
||||
wangsuTaskId = wangsuTaskMatches[1]
|
||||
}
|
||||
}
|
||||
|
||||
// 获取部署任务详细信息,等待任务状态变更
|
||||
// REF: https://www.wangsu.com/document/api-doc/27038
|
||||
if _, err := xwait.UntilWithContext(ctx, func(_ context.Context, _ int) (bool, error) {
|
||||
getDeploymentTaskDetailResp, err := d.sdkClient.GetDeploymentTaskDetail(wangsuTaskId)
|
||||
d.logger.Info("sdk request 'cdnpro.GetDeploymentTaskDetail'", slog.Any("taskId", wangsuTaskId), slog.Any("response", getDeploymentTaskDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdnpro.GetDeploymentTaskDetail': %w", err)
|
||||
return false, fmt.Errorf("failed to execute sdk request 'cdnpro.GetDeploymentTaskDetail': %w", err)
|
||||
}
|
||||
|
||||
if getDeploymentTaskDetailResp.Status == "failed" {
|
||||
return nil, errors.New("unexpected wangsu deployment task status")
|
||||
return false, fmt.Errorf("unexpected wangsu deployment task status")
|
||||
} else if getDeploymentTaskDetailResp.Status == "succeeded" || getDeploymentTaskDetailResp.FinishTime != "" {
|
||||
break
|
||||
return true, nil
|
||||
}
|
||||
|
||||
d.logger.Info(fmt.Sprintf("waiting for wangsu deployment task completion (current status: %s) ...", getDeploymentTaskDetailResp.Status))
|
||||
time.Sleep(time.Second * 5)
|
||||
return false, nil
|
||||
}, time.Second*5); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &deployer.DeployResult{}, nil
|
||||
|
||||
@@ -5,9 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/certmgr"
|
||||
mcertmgr "github.com/certimate-go/certimate/pkg/core/certmgr/providers/wangsu-certificate"
|
||||
@@ -78,18 +75,12 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep
|
||||
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
|
||||
}
|
||||
} else {
|
||||
// 修改证书
|
||||
// REF: https://www.wangsu.com/document/api-doc/25568?productCode=certificatemanagement
|
||||
updateCertificateReq := &wangsusdk.UpdateCertificateRequest{
|
||||
Name: lo.ToPtr(fmt.Sprintf("certimate_%d", time.Now().UnixMilli())),
|
||||
Certificate: lo.ToPtr(certPEM),
|
||||
PrivateKey: lo.ToPtr(privkeyPEM),
|
||||
Comment: lo.ToPtr("upload from certimate"),
|
||||
}
|
||||
updateCertificateResp, err := d.sdkClient.UpdateCertificate(d.config.CertificateId, updateCertificateReq)
|
||||
d.logger.Debug("sdk request 'certificatemanagement.UpdateCertificate'", slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp))
|
||||
// 替换证书
|
||||
opres, err := d.sdkCertmgr.Replace(ctx, d.config.CertificateId, certPEM, privkeyPEM)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanagement.CreateCertificate': %w", err)
|
||||
return nil, fmt.Errorf("failed to replace certificate file: %w", err)
|
||||
} else {
|
||||
d.logger.Info("ssl certificate replaced", slog.Any("result", opres))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 等待一段时间。
|
||||
//
|
||||
// 入参:
|
||||
// - wait: 等待时间。
|
||||
//
|
||||
// 出参:
|
||||
// - err: 错误。
|
||||
func Delay(wait time.Duration) error {
|
||||
return DelayWithContext(context.Background(), wait)
|
||||
}
|
||||
|
||||
// 等待一段时间,或上下文被取消。
|
||||
//
|
||||
// 入参:
|
||||
// - ctx: 上下文。
|
||||
// - wait: 等待时间。
|
||||
//
|
||||
// 出参:
|
||||
// - err: 错误。
|
||||
func DelayWithContext(ctx context.Context, wait time.Duration) error {
|
||||
ticker := time.NewTimer(wait)
|
||||
defer ticker.Stop()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 等待直到条件满足。
|
||||
//
|
||||
// 入参:
|
||||
// - condition: 条件函数,接收尝试次数作为参数,返回是否满足条件和错误。
|
||||
// - interval: 执行条件函数的间隔时间。
|
||||
//
|
||||
// 出参:
|
||||
// - ret: 是否满足条件。
|
||||
// - err: 错误。
|
||||
func Until(condition func(index int) (bool, error), interval time.Duration) (bool, error) {
|
||||
conditionWithContext := func(_ context.Context, index int) (bool, error) {
|
||||
return condition(index)
|
||||
}
|
||||
return UntilWithContext(context.Background(), conditionWithContext, interval)
|
||||
}
|
||||
|
||||
// 等待直到条件满足,或上下文被取消。
|
||||
//
|
||||
// 入参:
|
||||
// - ctx: 上下文。
|
||||
// - condition: 条件函数,接收上下文和尝试次数作为参数,返回是否满足条件和错误。
|
||||
// - interval: 执行条件函数的间隔时间。
|
||||
//
|
||||
// 出参:
|
||||
// - ret: 是否满足条件。
|
||||
// - err: 错误。
|
||||
func UntilWithContext(ctx context.Context, condition func(ctx context.Context, index int) (bool, error), interval time.Duration) (bool, error) {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
attempt := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false, ctx.Err()
|
||||
|
||||
case <-ticker.C:
|
||||
attempt++
|
||||
ret, err := condition(ctx, attempt)
|
||||
if ret || err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 等待直到条件满足或超时。
|
||||
//
|
||||
// 入参:
|
||||
// - condition: 条件函数,接收尝试次数作为参数,返回是否满足条件和错误。
|
||||
// - timeout: 超时时间。
|
||||
// - interval: 执行条件函数的间隔时间。
|
||||
//
|
||||
// 出参:
|
||||
// - ret: 是否满足条件。
|
||||
// - err: 错误。
|
||||
func UntilTimeout(condition func(index int) (bool, error), timeout time.Duration, interval time.Duration) (bool, error) {
|
||||
conditionWithContext := func(_ context.Context, index int) (bool, error) {
|
||||
return condition(index)
|
||||
}
|
||||
return UntilTimeoutWithContext(context.Background(), conditionWithContext, timeout, interval)
|
||||
}
|
||||
|
||||
// 等待直到条件满足或超时,或上下文被取消。
|
||||
//
|
||||
// 入参:
|
||||
// - ctx: 上下文。
|
||||
// - condition: 条件函数,接收上下文和尝试次数作为参数,返回是否满足条件和错误。
|
||||
// - timeout: 超时时间。
|
||||
// - interval: 执行条件函数的间隔时间。
|
||||
//
|
||||
// 出参:
|
||||
// - ret: 是否满足条件。
|
||||
// - err: 错误。
|
||||
func UntilTimeoutWithContext(ctx context.Context, condition func(ctx context.Context, index int) (bool, error), timeout time.Duration, interval time.Duration) (bool, error) {
|
||||
ctxWithTimeout, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
attempt := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctxWithTimeout.Done():
|
||||
return false, ctx.Err()
|
||||
|
||||
case <-ticker.C:
|
||||
attempt++
|
||||
ret, err := condition(ctxWithTimeout, attempt)
|
||||
if ret || err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user