internal/kms/sm.go (72 lines of code) (raw):
package kms
import (
"context"
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
kmssdk "github.com/alibabacloud-go/kms-20160120/v3/client"
teautil "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/aliyun/alibabacloud-kms-agent/internal/model"
"math"
"time"
)
const (
StartUpCheckSecretName = "kms-agent-startup-check"
)
type SMInterface interface {
GetSecretValue(ctx context.Context, request *kmssdk.GetSecretValueRequest) (*kmssdk.GetSecretValueResponseBody, error)
SelfCheck() error
}
type secretManagerClient struct {
client *kmssdk.Client
}
func newSecretManagerClient(config *openapi.Config) (*secretManagerClient, error) {
kmsClient, err := kmssdk.NewClient(config)
if err != nil {
return nil, fmt.Errorf("failed to create sm client: %v", err)
}
return &secretManagerClient{client: kmsClient}, nil
}
func (smClient *secretManagerClient) GetSecretValue(ctx context.Context, request *kmssdk.GetSecretValueRequest) (*kmssdk.GetSecretValueResponseBody, error) {
runtime := &teautil.RuntimeOptions{}
runtime.Autoretry = tea.Bool(true)
runtime.MaxAttempts = tea.Int(3)
var ret = new(kmssdk.GetSecretValueResponse)
var err error
for i := 0; i < 3; i++ {
ret, err = smClient.client.GetSecretValueWithOptions(request, runtime)
if err != nil {
if sdkErr, ok := err.(*tea.SDKError); ok {
// throttling or unexpected errors
if *sdkErr.StatusCode == 429 || *sdkErr.StatusCode >= 500 {
time.Sleep(time.Duration(getWaitTimeExponential(i+1) * int64(time.Millisecond)))
continue
}
}
}
break
}
if err != nil {
if sdkErr, ok := err.(*tea.SDKError); ok {
return nil, &model.ErrorResponse{StatusCode: *sdkErr.StatusCode, ErrorMsg: fmt.Sprintf("failed to get secret [%s]: %v", *request.SecretName, sdkErr.Error())}
}
return nil, err
}
return ret.Body, nil
}
func (smClient *secretManagerClient) SelfCheck() error {
ctx := context.Background()
_, err := smClient.GetSecretValue(ctx, &kmssdk.GetSecretValueRequest{
SecretName: tea.String(StartUpCheckSecretName),
})
if err == nil {
return nil
}
if _, ok := err.(*model.ErrorResponse); ok {
return nil
}
return fmt.Errorf("secret manager client self check falied: %w", err)
}
func getWaitTimeExponential(retryCount int) int64 {
var initialDelay float64 = 200 //ms
return int64(math.Pow(2, float64(retryCount)) * initialDelay)
}