Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions pkg/core/certifier/challengers/dns01/aws-lightsail/internal/lego.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import (
"strconv"
"time"

aws "github.com/aws/aws-sdk-go-v2/aws"
awscfg "github.com/aws/aws-sdk-go-v2/config"
awscred "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/lightsail"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/lightsail/types"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/platform/env"

awslightsailsdk "github.com/certimate-go/certimate/pkg/sdk3rd/aws/lightsail"
)

const (
Expand All @@ -25,8 +24,6 @@ const (
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
)

const maxRetries = 5

var _ challenge.ProviderTimeout = (*DNSProvider)(nil)

type Config struct {
Expand All @@ -49,7 +46,7 @@ func NewDefaultConfig() *Config {
// 这里有意不使用 lego 提供的 lightsail 实现,
// 因为它只支持单个域,无法签发多域名证书。
type DNSProvider struct {
client *lightsail.Client
client *awslightsailsdk.Client
config *Config
}

Expand All @@ -65,18 +62,17 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, fmt.Errorf("lightsail: the configuration of the DNS provider is nil")
}

ctx := context.Background()
cfg, err := awscfg.LoadDefaultConfig(ctx,
awscfg.WithCredentialsProvider(awscred.NewStaticCredentialsProvider(config.AccessKeyID, config.SecretAccessKey, config.SessionToken)),
awscfg.WithRegion(config.Region),
client, err := awslightsailsdk.NewClient(
awslightsailsdk.WithAkSk(config.AccessKeyID, config.SecretAccessKey),
awslightsailsdk.WithRegion(config.Region),
)
if err != nil {
return nil, err
}

return &DNSProvider{
config: config,
client: lightsail.NewFromConfig(cfg),
client: client,
}, nil
}

Expand All @@ -88,7 +84,8 @@ func (d *DNSProvider) Present(ctx context.Context, domain, _, keyAuth string) er
return fmt.Errorf("lightsail: could not find zone for domain %q: %w", domain, err)
}

if _, err := d.client.CreateDomainEntry(ctx, &lightsail.CreateDomainEntryInput{
// REF: https://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_CreateDomainEntry.html
if _, err := d.client.CreateDomainEntryWithContext(ctx, &awslightsailsdk.CreateDomainEntryRequest{
DomainName: aws.String(dns01.UnFqdn(authZone)),
DomainEntry: &types.DomainEntry{
Type: aws.String("TXT"),
Expand All @@ -110,7 +107,8 @@ func (d *DNSProvider) CleanUp(ctx context.Context, domain, _, keyAuth string) er
return fmt.Errorf("lightsail: could not find zone for domain %q: %w", domain, err)
}

if _, err := d.client.DeleteDomainEntry(ctx, &lightsail.DeleteDomainEntryInput{
// REF: https://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_DeleteDomainEntry.html
if _, err := d.client.DeleteDomainEntryWithContext(ctx, &awslightsailsdk.DeleteDomainEntryRequest{
DomainName: aws.String(dns01.UnFqdn(authZone)),
DomainEntry: &types.DomainEntry{
Type: aws.String("TXT"),
Expand Down
43 changes: 22 additions & 21 deletions pkg/core/certmgr/providers/aws-acm/aws_acm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
"strings"

aws "github.com/aws/aws-sdk-go-v2/aws"
awscfg "github.com/aws/aws-sdk-go-v2/config"
awscred "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/acm"
"github.com/aws/aws-sdk-go-v2/service/acm/types"
"github.com/aws/smithy-go"

"github.com/certimate-go/certimate/pkg/core"
awsacmsdk "github.com/certimate-go/certimate/pkg/sdk3rd/aws/acm"
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
)

Expand All @@ -35,7 +34,7 @@ type CertmgrConfig struct {
type Certmgr struct {
config *CertmgrConfig
logger *slog.Logger
sdkClient *acm.Client
sdkClient *awsacmsdk.Client
}

var _ Provider = (*Certmgr)(nil)
Expand Down Expand Up @@ -89,34 +88,37 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*Uplo
default:
}

listCertificatesReq := &acm.ListCertificatesInput{
listCertificatesReq := &awsacmsdk.ListCertificatesRequest{
NextToken: listCertificatesNextToken,
MaxItems: aws.Int32(1000),
SortBy: types.SortByCreatedAt,
SortOrder: types.SortOrderDescending,
}
listCertificatesResp, err := c.sdkClient.ListCertificates(ctx, listCertificatesReq)
listCertificatesResp, err := c.sdkClient.ListCertificatesWithContext(ctx, listCertificatesReq)
c.logger.Debug("sdk request 'acm.ListCertificates'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'acm.ListCertificates': %w", err)
}

for _, certItem := range listCertificatesResp.CertificateSummaryList {
// 对比证书备用名称
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certItem.SubjectAlternativeNameSummaries, ",")) {
// 对比证书通用名称
// 注意,虽然文档中描述为包含了备用名称字段,但实际值不完整,因此不能用于判断证书是否相同
if certItem.DomainName == nil || !strings.EqualFold(certX509.Subject.CommonName, *certItem.DomainName) {
continue
}

// 对比证书有效期
if certItem.NotBefore == nil || !certX509.NotBefore.Equal(*certItem.NotBefore) {
if certItem.NotBefore == nil || certX509.NotBefore.Unix() != certItem.NotBefore.Unix() {
continue
} else if certItem.NotAfter == nil || !certX509.NotAfter.Equal(*certItem.NotAfter) {
} else if certItem.NotAfter == nil || certX509.NotAfter.Unix() != certItem.NotAfter.Unix() {
continue
}

// 对比证书内容
getCertificateReq := &acm.GetCertificateInput{
getCertificateReq := &awsacmsdk.GetCertificateRequest{
CertificateArn: certItem.CertificateArn,
}
getCertificateResp, err := c.sdkClient.GetCertificate(ctx, getCertificateReq)
getCertificateResp, err := c.sdkClient.GetCertificateWithContext(ctx, getCertificateReq)
if err != nil {
var sdkErr smithy.APIError
if errors.As(err, &sdkErr) {
Expand Down Expand Up @@ -151,12 +153,12 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*Uplo

// 导入证书
// REF: https://docs.aws.amazon.com/acm/latest/APIReference/API_ImportCertificate.html
importCertificateReq := &acm.ImportCertificateInput{
importCertificateReq := &awsacmsdk.ImportCertificateRequest{
Certificate: ([]byte)(serverCertPEM),
CertificateChain: ([]byte)(issuerCertPEM),
PrivateKey: ([]byte)(privkeyPEM),
}
importCertificateResp, err := c.sdkClient.ImportCertificate(ctx, importCertificateReq)
importCertificateResp, err := c.sdkClient.ImportCertificateWithContext(ctx, importCertificateReq)
c.logger.Debug("sdk request 'acm.ImportCertificate'", slog.Any("request", importCertificateReq), slog.Any("response", importCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'acm.ImportCertificate': %w", err)
Expand All @@ -179,13 +181,13 @@ func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, pri

// 导入证书
// REF: https://docs.aws.amazon.com/acm/latest/APIReference/API_ImportCertificate.html
importCertificateReq := &acm.ImportCertificateInput{
importCertificateReq := &awsacmsdk.ImportCertificateRequest{
CertificateArn: aws.String(certIdOrName),
Certificate: ([]byte)(serverCertPEM),
CertificateChain: ([]byte)(issuerCertPEM),
PrivateKey: ([]byte)(privkeyPEM),
}
importCertificateResp, err := c.sdkClient.ImportCertificate(ctx, importCertificateReq)
importCertificateResp, err := c.sdkClient.ImportCertificateWithContext(ctx, importCertificateReq)
c.logger.Debug("sdk request 'acm.ImportCertificate'", slog.Any("request", importCertificateReq), slog.Any("response", importCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'acm.ImportCertificate': %w", err)
Expand All @@ -194,15 +196,14 @@ func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, pri
return &ReplaceResult{}, nil
}

func createSDKClient(accessKeyId, secretAccessKey, region string) (*acm.Client, error) {
cfg, err := awscfg.LoadDefaultConfig(context.Background(),
awscfg.WithCredentialsProvider(awscred.NewStaticCredentialsProvider(accessKeyId, secretAccessKey, "")),
awscfg.WithRegion(region),
func createSDKClient(accessKeyId, secretAccessKey, region string) (*awsacmsdk.Client, error) {
client, err := awsacmsdk.NewClient(
awsacmsdk.WithAkSk(accessKeyId, secretAccessKey),
awsacmsdk.WithRegion(region),
)
if err != nil {
return nil, err
}

client := acm.NewFromConfig(cfg)
return client, nil
}
26 changes: 12 additions & 14 deletions pkg/core/certmgr/providers/aws-iam/aws_iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import (
"time"

aws "github.com/aws/aws-sdk-go-v2/aws"
awscfg "github.com/aws/aws-sdk-go-v2/config"
awscred "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/smithy-go"
"github.com/samber/lo"

"github.com/certimate-go/certimate/pkg/core"
awsiamsdk "github.com/certimate-go/certimate/pkg/sdk3rd/aws/iam"
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
)

Expand All @@ -40,7 +39,7 @@ type CertmgrConfig struct {
type Certmgr struct {
config *CertmgrConfig
logger *slog.Logger
sdkClient *iam.Client
sdkClient *awsiamsdk.Client
}

var _ Provider = (*Certmgr)(nil)
Expand Down Expand Up @@ -99,7 +98,7 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*Uplo
Marker: listServerCertificatesMarker,
MaxItems: aws.Int32(1000),
}
listServerCertificatesResp, err := c.sdkClient.ListServerCertificates(ctx, listServerCertificatesReq)
listServerCertificatesResp, err := c.sdkClient.ListServerCertificatesWithContext(ctx, listServerCertificatesReq)
c.logger.Debug("sdk request 'iam.ListServerCertificates'", slog.Any("request", listServerCertificatesReq), slog.Any("response", listServerCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'iam.ListServerCertificates': %w", err)
Expand All @@ -112,15 +111,15 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*Uplo
}

// 对比证书有效期
if certItem.Expiration == nil || !certX509.NotAfter.Equal(*certItem.Expiration) {
if certItem.Expiration == nil || certX509.NotAfter.Unix() != certItem.Expiration.Unix() {
continue
}

// 对比证书内容
getServerCertificateReq := &iam.GetServerCertificateInput{
getServerCertificateReq := &awsiamsdk.GetServerCertificateRequest{
ServerCertificateName: certItem.ServerCertificateName,
}
getServerCertificateResp, err := c.sdkClient.GetServerCertificate(ctx, getServerCertificateReq)
getServerCertificateResp, err := c.sdkClient.GetServerCertificateWithContext(ctx, getServerCertificateReq)
if err != nil {
var sdkErr smithy.APIError
if errors.As(err, &sdkErr) {
Expand Down Expand Up @@ -160,14 +159,14 @@ func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*Uplo

// 导入证书
// REF: https://docs.aws.amazon.com/IAM/latest/APIReference/API_UploadServerCertificate.html
uploadServerCertificateReq := &iam.UploadServerCertificateInput{
uploadServerCertificateReq := &awsiamsdk.UploadServerCertificateRequest{
ServerCertificateName: aws.String(certName),
Path: aws.String(cmp.Or(c.config.CertificatePath, "/")),
CertificateBody: aws.String(serverCertPEM),
CertificateChain: aws.String(issuerCertPEM),
PrivateKey: aws.String(privkeyPEM),
}
uploadServerCertificateResp, err := c.sdkClient.UploadServerCertificate(ctx, uploadServerCertificateReq)
uploadServerCertificateResp, err := c.sdkClient.UploadServerCertificateWithContext(ctx, uploadServerCertificateReq)
c.logger.Debug("sdk request 'iam.UploadServerCertificate'", slog.Any("request", uploadServerCertificateReq), slog.Any("response", uploadServerCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'iam.UploadServerCertificate': %w", err)
Expand All @@ -187,15 +186,14 @@ func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, pri
return nil, core.ErrUnsupported
}

func createSDKClient(accessKeyId, secretAccessKey, region string) (*iam.Client, error) {
cfg, err := awscfg.LoadDefaultConfig(context.Background(),
awscfg.WithCredentialsProvider(awscred.NewStaticCredentialsProvider(accessKeyId, secretAccessKey, "")),
awscfg.WithRegion(region),
func createSDKClient(accessKeyId, secretAccessKey, region string) (*awsiamsdk.Client, error) {
client, err := awsiamsdk.NewClient(
awsiamsdk.WithAkSk(accessKeyId, secretAccessKey),
awsiamsdk.WithRegion(region),
)
if err != nil {
return nil, err
}

client := iam.NewFromConfig(cfg)
return client, nil
}
31 changes: 14 additions & 17 deletions pkg/core/deployer/providers/aws-alb/aws_alb.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ import (
"log/slog"

aws "github.com/aws/aws-sdk-go-v2/aws"
awscfg "github.com/aws/aws-sdk-go-v2/config"
awscred "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"

"github.com/certimate-go/certimate/pkg/core"
cmgrimplacm "github.com/certimate-go/certimate/pkg/core/certmgr/providers/aws-acm"
cmgrimpliam "github.com/certimate-go/certimate/pkg/core/certmgr/providers/aws-iam"
awselbsdk "github.com/certimate-go/certimate/pkg/sdk3rd/aws/elasticloadbalancingv2"
)

type (
Expand Down Expand Up @@ -42,7 +40,7 @@ type DeployerConfig struct {
type Deployer struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *elasticloadbalancingv2.Client
sdkClient *awselbsdk.Client
sdkCertmgr core.Certmgr
}

Expand Down Expand Up @@ -121,10 +119,10 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep

// 查询负载均衡器
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_DescribeLoadBalancers.html
describeLoadBalancersReq := &elasticloadbalancingv2.DescribeLoadBalancersInput{
describeLoadBalancersReq := &awselbsdk.DescribeLoadBalancersRequest{
LoadBalancerArns: []string{d.config.LoadbalancerArn},
}
describeLoadBalancersResp, err := d.sdkClient.DescribeLoadBalancers(ctx, describeLoadBalancersReq)
describeLoadBalancersResp, err := d.sdkClient.DescribeLoadBalancersWithContext(ctx, describeLoadBalancersReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.DescribeLoadBalancers'", slog.Any("request", describeLoadBalancersReq), slog.Any("response", describeLoadBalancersResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.DescribeLoadBalancers': %w", err)
Expand All @@ -134,11 +132,11 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep

// 查询侦听器
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_DescribeListeners.html
describeListenersReq := &elasticloadbalancingv2.DescribeListenersInput{
describeListenersReq := &awselbsdk.DescribeListenersRequest{
LoadBalancerArn: aws.String(d.config.LoadbalancerArn),
ListenerArns: []string{d.config.ListenerArn},
}
describeListenersResp, err := d.sdkClient.DescribeListeners(ctx, describeListenersReq)
describeListenersResp, err := d.sdkClient.DescribeListenersWithContext(ctx, describeListenersReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.DescribeListeners': %w", err)
Expand Down Expand Up @@ -183,15 +181,15 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerArn string, cloudCertArn string) error {
// 更新 HTTPS 侦听器
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_ModifyListener.html
modifyListenerReq := &elasticloadbalancingv2.ModifyListenerInput{
modifyListenerReq := &awselbsdk.ModifyListenerRequest{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
modifyListenerResp, err := d.sdkClient.ModifyListener(ctx, modifyListenerReq)
modifyListenerResp, err := d.sdkClient.ModifyListenerWithContext(ctx, modifyListenerReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.ModifyListener'", slog.Any("request", modifyListenerReq), slog.Any("response", modifyListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.ModifyListener': %w", err)
Expand All @@ -203,15 +201,15 @@ func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudLi
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerArn string, cloudCertArn string) error {
// 将证书添加到证书列表
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_AddListenerCertificates.html
addListenerCertificatesReq := &elasticloadbalancingv2.AddListenerCertificatesInput{
addListenerCertificatesReq := &awselbsdk.AddListenerCertificatesRequest{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(ctx, addListenerCertificatesReq)
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificatesWithContext(ctx, addListenerCertificatesReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.AddListenerCertificates'", slog.Any("request", addListenerCertificatesReq), slog.Any("response", addListenerCertificatesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.AddListenerCertificates': %w", err)
Expand All @@ -220,15 +218,14 @@ func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListen
return nil
}

func createSDKClient(accessKeyId, secretAccessKey, region string) (*elasticloadbalancingv2.Client, error) {
cfg, err := awscfg.LoadDefaultConfig(context.Background(),
awscfg.WithCredentialsProvider(awscred.NewStaticCredentialsProvider(accessKeyId, secretAccessKey, "")),
awscfg.WithRegion(region),
func createSDKClient(accessKeyId, secretAccessKey, region string) (*awselbsdk.Client, error) {
client, err := awselbsdk.NewClient(
awselbsdk.WithAkSk(accessKeyId, secretAccessKey),
awselbsdk.WithRegion(region),
)
if err != nil {
return nil, err
}

client := elasticloadbalancingv2.NewFromConfig(cfg)
return client, nil
}
Loading