refactor: clean code

This commit is contained in:
Fu Diwei
2026-07-01 16:40:42 +08:00
committed by RHQYZ
parent 0521934210
commit d543a6de90
32 changed files with 862 additions and 662 deletions
@@ -234,7 +234,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string,
d.logger.Info("no alb listeners to deploy")
} else {
var errs []error
d.logger.Info("found https/quic listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found alb listeners to deploy", slog.Any("listenerIds", listenerIds))
for _, listenerId := range listenerIds {
select {
@@ -271,186 +271,197 @@ func (d *Deployer) deployToListener(ctx context.Context, cloudCertId string, clo
func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string, cloudCertSANs []string) error {
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
return d.updateListenerDefaultCertificate(ctx, cloudListenerId, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateListenerSniCertificate(ctx, cloudListenerId, cloudCertId, cloudCertSANs)
}
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
if err := d.waitForListenerReady(ctx, cloudListenerId); err != nil {
return err
}
// 修改监听的属性
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-updatelistenerattribute
updateListenerAttributeReq := &alialb.UpdateListenerAttributeRequest{
ListenerId: tea.String(cloudListenerId),
Certificates: []*alialb.UpdateListenerAttributeRequestCertificates{{
CertificateId: tea.String(cloudCertId),
}},
}
updateListenerAttributeResp, err := d.sdkClients.ALB.UpdateListenerAttributeWithContext(ctx, updateListenerAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerAttributeResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.UpdateListenerAttribute': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerId string, cloudCertId string, cloudCertSANs []string) error {
// 查询监听证书列表
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
listenerExtCertificates := make([]alialb.ListListenerCertificatesResponseBodyCertificates, 0)
listListenerCertificatesToken := (*string)(nil)
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
listListenerCertificatesReq := &alialb.ListListenerCertificatesRequest{
NextToken: listListenerCertificatesToken,
MaxResults: tea.Int32(100),
ListenerId: tea.String(cloudListenerId),
CertificateType: tea.String("Server"),
}
listListenerCertificatesResp, err := d.sdkClients.ALB.ListListenerCertificatesWithContext(ctx, listListenerCertificatesReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.ListListenerCertificates'", slog.Any("request", listListenerCertificatesReq), slog.Any("response", listListenerCertificatesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ListListenerCertificates': %w", err)
}
if listListenerCertificatesResp.Body == nil {
break
}
for _, certItem := range listListenerCertificatesResp.Body.Certificates {
if tea.BoolValue(certItem.IsDefault) {
continue
}
if !strings.EqualFold(tea.StringValue(certItem.CertificateType), "Server") {
continue
}
if !strings.EqualFold(tea.StringValue(certItem.Status), "Associated") {
continue
}
listenerExtCertificates = append(listenerExtCertificates, *certItem)
}
if len(listListenerCertificatesResp.Body.Certificates) == 0 || listListenerCertificatesResp.Body.NextToken == nil {
break
}
listListenerCertificatesToken = listListenerCertificatesResp.Body.NextToken
}
// 查询监听证书,并找出需要解除关联的证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getcertificatedetail
certificateIsAlreadyAssociated := false
certificateIdsToDissociate := make([]string, 0)
if len(listenerExtCertificates) > 0 {
d.logger.Info("found alb listener certificates in used", slog.Any("certificates", listenerExtCertificates))
var errs []error
for _, listenerCertificate := range listenerExtCertificates {
certIdWithRegion := tea.StringValue(listenerCertificate.CertificateId)
if certIdWithRegion == cloudCertId {
certificateIsAlreadyAssociated = true
break
}
certIdBare := strings.SplitN(certIdWithRegion, "-", 2)[0]
certIdBareAsInt64, err := strconv.ParseInt(certIdBare, 10, 64)
if err != nil {
errs = append(errs, err)
continue
}
getCertificateDetailReq := &alicas.GetCertificateDetailRequest{
CertificateId: tea.Int64(certIdBareAsInt64),
}
getCertificateDetailResp, err := d.sdkClients.CAS.GetCertificateDetailWithContext(ctx, getCertificateDetailReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'cas.GetCertificateDetail'", slog.Any("request", getCertificateDetailReq), slog.Any("response", getCertificateDetailResp))
if err != nil {
if sdkErr, ok := err.(*tea.SDKError); ok {
if sdkErrCode := tea.StringValue(sdkErr.Code); strings.HasPrefix(sdkErrCode, "NotFound") {
continue
}
}
errs = append(errs, fmt.Errorf("failed to execute sdk request 'cas.GetCertificateDetail': %w", err))
continue
} else {
// 注意,虽然文档中存在 SubjectAlternativeNames 字段,但实际返回的数据结构中不包含
certSANMatched := lo.ElementsMatch(strings.Split(tea.StringValue(getCertificateDetailResp.Body.Domain), ","), cloudCertSANs)
if certSANMatched && lo.Contains(cloudCertSANs, d.config.Domain) { // 同域名证书需要删除
certificateIdsToDissociate = append(certificateIdsToDissociate, certIdWithRegion)
continue
}
certNotAfter := time.Unix(tea.Int64Value(getCertificateDetailResp.Body.NotAfter)/1000, 0)
if !certNotAfter.IsZero() && certNotAfter.Before(time.Now()) { // 过期证书需要删除。TODO: remove on v0.5
certificateIdsToDissociate = append(certificateIdsToDissociate, certIdWithRegion)
continue
}
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
// 关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-associateadditionalcertificateswithlistener
if certificateIsAlreadyAssociated {
d.logger.Info("no need to add alb listener sni certificate")
return nil
} else {
if err := d.waitForListenerReady(ctx, cloudListenerId); err != nil {
return err
}
// 修改监听的属性
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-updatelistenerattribute
updateListenerAttributeReq := &alialb.UpdateListenerAttributeRequest{
associateAdditionalCertificatesFromListenerReq := &alialb.AssociateAdditionalCertificatesWithListenerRequest{
ListenerId: tea.String(cloudListenerId),
Certificates: []*alialb.UpdateListenerAttributeRequestCertificates{{
CertificateId: tea.String(cloudCertId),
}},
Certificates: []*alialb.AssociateAdditionalCertificatesWithListenerRequestCertificates{
{
CertificateId: tea.String(cloudCertId),
},
},
}
updateListenerAttributeResp, err := d.sdkClients.ALB.UpdateListenerAttributeWithContext(ctx, updateListenerAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerAttributeResp))
associateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.AssociateAdditionalCertificatesWithListenerWithContext(ctx, associateAdditionalCertificatesFromListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesFromListenerReq), slog.Any("response", associateAdditionalCertificatesFromListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.UpdateListenerAttribute': %w", err)
return fmt.Errorf("failed to execute sdk request 'alb.AssociateAdditionalCertificatesWithListener': %w", err)
}
} else {
// 指定 SNI,需部署到扩展域名
}
// 查询监听证书列表
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
listenerExtCertificates := make([]alialb.ListListenerCertificatesResponseBodyCertificates, 0)
listListenerCertificatesToken := (*string)(nil)
for {
// 解除关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-dissociateadditionalcertificatesfromlistener
if len(certificateIdsToDissociate) > 0 {
d.logger.Info("found alb listener certificates to dissociate", slog.Any("certificateIds", certificateIdsToDissociate))
const MAX_CERT_PER_REQUEST = 10
certIdChunks := lo.Chunk(certificateIdsToDissociate, MAX_CERT_PER_REQUEST)
for _, certIds := range certIdChunks {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
listListenerCertificatesReq := &alialb.ListListenerCertificatesRequest{
NextToken: listListenerCertificatesToken,
MaxResults: tea.Int32(100),
ListenerId: tea.String(cloudListenerId),
CertificateType: tea.String("Server"),
}
listListenerCertificatesResp, err := d.sdkClients.ALB.ListListenerCertificatesWithContext(ctx, listListenerCertificatesReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.ListListenerCertificates'", slog.Any("request", listListenerCertificatesReq), slog.Any("response", listListenerCertificatesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ListListenerCertificates': %w", err)
}
if listListenerCertificatesResp.Body == nil {
break
}
for _, certItem := range listListenerCertificatesResp.Body.Certificates {
if tea.BoolValue(certItem.IsDefault) {
continue
if err := d.waitForListenerReady(ctx, cloudListenerId); err != nil {
return err
}
if !strings.EqualFold(tea.StringValue(certItem.CertificateType), "Server") {
continue
}
if !strings.EqualFold(tea.StringValue(certItem.Status), "Associated") {
continue
}
listenerExtCertificates = append(listenerExtCertificates, *certItem)
}
if len(listListenerCertificatesResp.Body.Certificates) == 0 || listListenerCertificatesResp.Body.NextToken == nil {
break
}
listListenerCertificatesToken = listListenerCertificatesResp.Body.NextToken
}
// 查询监听证书,并找出需要解除关联的证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getcertificatedetail
certificateIsAlreadyAssociated := false
certificateIdsToDissociate := make([]string, 0)
if len(listenerExtCertificates) > 0 {
d.logger.Info("found listener certificates in used", slog.Any("certificates", listenerExtCertificates))
var errs []error
for _, listenerCertificate := range listenerExtCertificates {
certIdWithRegion := tea.StringValue(listenerCertificate.CertificateId)
if certIdWithRegion == cloudCertId {
certificateIsAlreadyAssociated = true
break
}
certIdBare := strings.SplitN(certIdWithRegion, "-", 2)[0]
certIdBareAsInt64, err := strconv.ParseInt(certIdBare, 10, 64)
if err != nil {
errs = append(errs, err)
continue
}
getCertificateDetailReq := &alicas.GetCertificateDetailRequest{
CertificateId: tea.Int64(certIdBareAsInt64),
}
getCertificateDetailResp, err := d.sdkClients.CAS.GetCertificateDetailWithContext(ctx, getCertificateDetailReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'cas.GetCertificateDetail'", slog.Any("request", getCertificateDetailReq), slog.Any("response", getCertificateDetailResp))
if err != nil {
if sdkErr, ok := err.(*tea.SDKError); ok {
if sdkErrCode := tea.StringValue(sdkErr.Code); strings.HasPrefix(sdkErrCode, "NotFound") {
continue
dissociateAdditionalCertificatesFromListenerReq := &alialb.DissociateAdditionalCertificatesFromListenerRequest{
ListenerId: tea.String(cloudListenerId),
Certificates: lo.Map(certIds, func(certId string, _ int) *alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates {
return &alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates{
CertificateId: tea.String(certId),
}
}
errs = append(errs, fmt.Errorf("failed to execute sdk request 'cas.GetCertificateDetail': %w", err))
continue
} else {
// 注意,虽然文档中存在 SubjectAlternativeNames 字段,但实际返回的数据结构中不包含
certSANMatched := lo.ElementsMatch(strings.Split(tea.StringValue(getCertificateDetailResp.Body.Domain), ","), cloudCertSANs)
if certSANMatched && lo.Contains(cloudCertSANs, d.config.Domain) { // 同域名证书需要删除
certificateIdsToDissociate = append(certificateIdsToDissociate, certIdWithRegion)
continue
}
certNotAfter := time.Unix(tea.Int64Value(getCertificateDetailResp.Body.NotAfter)/1000, 0)
if !certNotAfter.IsZero() && certNotAfter.Before(time.Now()) { // 过期证书需要删除
certificateIdsToDissociate = append(certificateIdsToDissociate, certIdWithRegion)
continue
}
}),
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
// 关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-associateadditionalcertificateswithlistener
if !certificateIsAlreadyAssociated {
if err := d.waitForListenerReady(ctx, cloudListenerId); err != nil {
return err
}
associateAdditionalCertificatesFromListenerReq := &alialb.AssociateAdditionalCertificatesWithListenerRequest{
ListenerId: tea.String(cloudListenerId),
Certificates: []*alialb.AssociateAdditionalCertificatesWithListenerRequestCertificates{
{
CertificateId: tea.String(cloudCertId),
},
},
}
associateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.AssociateAdditionalCertificatesWithListenerWithContext(ctx, associateAdditionalCertificatesFromListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesFromListenerReq), slog.Any("response", associateAdditionalCertificatesFromListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.AssociateAdditionalCertificatesWithListener': %w", err)
}
}
// 解除关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-dissociateadditionalcertificatesfromlistener
if !certificateIsAlreadyAssociated && len(certificateIdsToDissociate) > 0 {
d.logger.Info("found listener certificates to dissociate", slog.Any("certificateIds", certificateIdsToDissociate))
const MAX_CERT_PER_REQUEST = 10
certIdChunks := lo.Chunk(certificateIdsToDissociate, MAX_CERT_PER_REQUEST)
for _, certIds := range certIdChunks {
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := d.waitForListenerReady(ctx, cloudListenerId); err != nil {
return err
}
dissociateAdditionalCertificatesFromListenerReq := &alialb.DissociateAdditionalCertificatesFromListenerRequest{
ListenerId: tea.String(cloudListenerId),
Certificates: lo.Map(certIds, func(certId string, _ int) *alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates {
return &alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates{
CertificateId: tea.String(certId),
}
}),
}
dissociateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.DissociateAdditionalCertificatesFromListenerWithContext(ctx, dissociateAdditionalCertificatesFromListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.DissociateAdditionalCertificatesFromListener'", slog.Any("request", dissociateAdditionalCertificatesFromListenerReq), slog.Any("response", dissociateAdditionalCertificatesFromListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.DissociateAdditionalCertificatesFromListener': %w", err)
}
dissociateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.DissociateAdditionalCertificatesFromListenerWithContext(ctx, dissociateAdditionalCertificatesFromListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'alb.DissociateAdditionalCertificatesFromListener'", slog.Any("request", dissociateAdditionalCertificatesFromListenerReq), slog.Any("response", dissociateAdditionalCertificatesFromListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.DissociateAdditionalCertificatesFromListener': %w", err)
}
}
}
@@ -476,7 +487,7 @@ func (d *Deployer) waitForListenerReady(ctx context.Context, cloudListenerId str
return true, nil
}
d.logger.Info("waiting for aliyun alb listener's status to not be 'Configuring' ...")
d.logger.Info("waiting for alb listener's status to not be 'Configuring' ...")
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -149,10 +149,10 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
case "success", "error":
return true, nil
case "", "editing":
return false, fmt.Errorf("unexpected aliyun deployment job status")
return false, fmt.Errorf("unexpected deployment job status")
}
d.logger.Info("waiting for aliyun deployment job completion ...")
d.logger.Info("waiting for deployment job completion ...")
return false, nil
}, 10*time.Second); err != nil {
return nil, err
@@ -178,7 +178,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerPorts) == 0 {
d.logger.Info("no clb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerPorts", listenerPorts))
d.logger.Info("found clb listeners to deploy", slog.Any("listenerPorts", listenerPorts))
var errs []error
for _, listenerPort := range listenerPorts {
@@ -231,62 +231,79 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudLoadbalan
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 修改监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
setLoadBalancerHTTPSListenerAttributeReq := &alislb.SetLoadBalancerHTTPSListenerAttributeRequest{
RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort),
ServerCertificateId: tea.String(cloudCertId),
}
setLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.SetLoadBalancerHTTPSListenerAttributeWithContext(ctx, setLoadBalancerHTTPSListenerAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute'", slog.Any("request", setLoadBalancerHTTPSListenerAttributeReq), slog.Any("response", setLoadBalancerHTTPSListenerAttributeResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute': %w", err)
if tea.StringValue(describeLoadBalancerHTTPSListenerAttributeResp.Body.ServerCertificateId) == cloudCertId {
d.logger.Info("no need to update clb listener default certificate")
return nil
}
return d.updateListenerDefaultCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateListenerSniCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
}
}
// 查询扩展域名
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions
describeDomainExtensionsReq := &alislb.DescribeDomainExtensionsRequest{
RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort),
}
describeDomainExtensionsResp, err := d.sdkClient.DescribeDomainExtensionsWithContext(ctx, describeDomainExtensionsReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.DescribeDomainExtensions'", slog.Any("request", describeDomainExtensionsReq), slog.Any("response", describeDomainExtensionsResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'slb.DescribeDomainExtensions': %w", err)
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error {
// 修改监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
setLoadBalancerHTTPSListenerAttributeReq := &alislb.SetLoadBalancerHTTPSListenerAttributeRequest{
RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort),
ServerCertificateId: tea.String(cloudCertId),
}
setLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.SetLoadBalancerHTTPSListenerAttributeWithContext(ctx, setLoadBalancerHTTPSListenerAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute'", slog.Any("request", setLoadBalancerHTTPSListenerAttributeReq), slog.Any("response", setLoadBalancerHTTPSListenerAttributeResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute': %w", err)
}
// 遍历修改扩展域名证书
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setdomainextensionattribute
if describeDomainExtensionsResp.Body.DomainExtensions != nil && describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension != nil {
var errs []error
return nil
}
for _, domainExtension := range describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension {
if *domainExtension.Domain != d.config.Domain {
continue
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error {
// 查询扩展域名
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions
describeDomainExtensionsReq := &alislb.DescribeDomainExtensionsRequest{
RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort),
}
describeDomainExtensionsResp, err := d.sdkClient.DescribeDomainExtensionsWithContext(ctx, describeDomainExtensionsReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.DescribeDomainExtensions'", slog.Any("request", describeDomainExtensionsReq), slog.Any("response", describeDomainExtensionsResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'slb.DescribeDomainExtensions': %w", err)
}
setDomainExtensionAttributeReq := &alislb.SetDomainExtensionAttributeRequest{
RegionId: tea.String(d.config.Region),
DomainExtensionId: tea.String(*domainExtension.DomainExtensionId),
ServerCertificateId: tea.String(cloudCertId),
}
setDomainExtensionAttributeResp, err := d.sdkClient.SetDomainExtensionAttributeWithContext(ctx, setDomainExtensionAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.SetDomainExtensionAttribute'", slog.Any("request", setDomainExtensionAttributeReq), slog.Any("response", setDomainExtensionAttributeResp))
if err != nil {
errs = append(errs, fmt.Errorf("failed to execute sdk request 'slb.SetDomainExtensionAttribute': %w", err))
continue
}
// 遍历修改扩展域名证书
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setdomainextensionattribute
if describeDomainExtensionsResp.Body.DomainExtensions != nil && describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension != nil {
var errs []error
for _, domainExtension := range describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension {
if tea.StringValue(domainExtension.Domain) != d.config.Domain {
continue
}
if len(errs) > 0 {
return errors.Join(errs...)
if tea.StringValue(domainExtension.ServerCertificateId) == cloudCertId {
d.logger.Info("no need to add clb listener sni certificate")
continue
}
setDomainExtensionAttributeReq := &alislb.SetDomainExtensionAttributeRequest{
RegionId: tea.String(d.config.Region),
DomainExtensionId: domainExtension.DomainExtensionId,
ServerCertificateId: tea.String(cloudCertId),
}
setDomainExtensionAttributeResp, err := d.sdkClient.SetDomainExtensionAttributeWithContext(ctx, setDomainExtensionAttributeReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'slb.SetDomainExtensionAttribute'", slog.Any("request", setDomainExtensionAttributeReq), slog.Any("response", setDomainExtensionAttributeResp))
if err != nil {
errs = append(errs, fmt.Errorf("failed to execute sdk request 'slb.SetDomainExtensionAttribute': %w", err))
continue
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
@@ -168,7 +168,7 @@ func (d *Deployer) deployToAccelerator(ctx context.Context, cloudCertId string)
d.logger.Info("no ga listeners to deploy")
} else {
var errs []error
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found ga listeners to deploy", slog.Any("listenerIds", listenerIds))
for _, listenerId := range listenerIds {
select {
@@ -250,64 +250,74 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudAccelerat
d.logger.Info("no need to update ga listener default certificate")
return nil
}
// 修改监听的属性
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-updatelistener
updateListenerReq := &aliga.UpdateListenerRequest{
RegionId: tea.String("cn-hangzhou"),
ListenerId: tea.String(cloudListenerId),
Certificates: []*aliga.UpdateListenerRequestCertificates{{
Id: tea.String(cloudCertId),
}},
}
updateListenerResp, err := d.sdkClient.UpdateListenerWithContext(ctx, updateListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.UpdateListener': %w", err)
}
return d.updateListenerDefaultCertificate(ctx, cloudListenerId, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
if lo.SomeBy(listenerAdditionalCertificates, func(item *aliga.ListListenerCertificatesResponseBodyCertificates) bool {
return tea.StringValue(item.CertificateId) == cloudCertId
}) {
d.logger.Info("no need to update ga listener additional certificate")
d.logger.Info("no need to add ga listener sni certificate")
return nil
}
if lo.SomeBy(listenerAdditionalCertificates, func(item *aliga.ListListenerCertificatesResponseBodyCertificates) bool {
added := lo.SomeBy(listenerAdditionalCertificates, func(item *aliga.ListListenerCertificatesResponseBodyCertificates) bool {
return tea.StringValue(item.Domain) == d.config.Domain
}) {
// 为监听替换扩展证书
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-updateadditionalcertificatewithlistener
updateAdditionalCertificateWithListenerReq := &aliga.UpdateAdditionalCertificateWithListenerRequest{
RegionId: tea.String("cn-hangzhou"),
AcceleratorId: tea.String(cloudAcceleratorId),
ListenerId: tea.String(cloudListenerId),
CertificateId: tea.String(cloudCertId),
Domain: tea.String(d.config.Domain),
}
updateAdditionalCertificateWithListenerResp, err := d.sdkClient.UpdateAdditionalCertificateWithListenerWithContext(ctx, updateAdditionalCertificateWithListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.UpdateAdditionalCertificateWithListener'", slog.Any("request", updateAdditionalCertificateWithListenerReq), slog.Any("response", updateAdditionalCertificateWithListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.UpdateAdditionalCertificateWithListener': %w", err)
}
} else {
// 为监听绑定扩展证书
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-associateadditionalcertificateswithlistener
associateAdditionalCertificatesWithListenerReq := &aliga.AssociateAdditionalCertificatesWithListenerRequest{
RegionId: tea.String("cn-hangzhou"),
AcceleratorId: tea.String(cloudAcceleratorId),
ListenerId: tea.String(cloudListenerId),
Certificates: []*aliga.AssociateAdditionalCertificatesWithListenerRequestCertificates{{
Id: tea.String(cloudCertId),
Domain: tea.String(d.config.Domain),
}},
}
associateAdditionalCertificatesWithListenerResp, err := d.sdkClient.AssociateAdditionalCertificatesWithListenerWithContext(ctx, associateAdditionalCertificatesWithListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesWithListenerReq), slog.Any("response", associateAdditionalCertificatesWithListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.AssociateAdditionalCertificatesWithListener': %w", err)
}
})
return d.updateListenerSniCertificate(ctx, cloudAcceleratorId, cloudListenerId, cloudCertId, added)
}
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 修改监听的属性
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-updatelistener
updateListenerReq := &aliga.UpdateListenerRequest{
RegionId: tea.String("cn-hangzhou"),
ListenerId: tea.String(cloudListenerId),
Certificates: []*aliga.UpdateListenerRequestCertificates{{
Id: tea.String(cloudCertId),
}},
}
updateListenerResp, err := d.sdkClient.UpdateListenerWithContext(ctx, updateListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.UpdateListener': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudAcceleratorId string, cloudListenerId string, cloudCertId string, added bool) error {
if added {
// 为监听替换扩展证书
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-updateadditionalcertificatewithlistener
updateAdditionalCertificateWithListenerReq := &aliga.UpdateAdditionalCertificateWithListenerRequest{
RegionId: tea.String("cn-hangzhou"),
AcceleratorId: tea.String(cloudAcceleratorId),
ListenerId: tea.String(cloudListenerId),
CertificateId: tea.String(cloudCertId),
Domain: tea.String(d.config.Domain),
}
updateAdditionalCertificateWithListenerResp, err := d.sdkClient.UpdateAdditionalCertificateWithListenerWithContext(ctx, updateAdditionalCertificateWithListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.UpdateAdditionalCertificateWithListener'", slog.Any("request", updateAdditionalCertificateWithListenerReq), slog.Any("response", updateAdditionalCertificateWithListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.UpdateAdditionalCertificateWithListener': %w", err)
}
} else {
// 为监听绑定扩展证书
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-associateadditionalcertificateswithlistener
associateAdditionalCertificatesWithListenerReq := &aliga.AssociateAdditionalCertificatesWithListenerRequest{
RegionId: tea.String("cn-hangzhou"),
AcceleratorId: tea.String(cloudAcceleratorId),
ListenerId: tea.String(cloudListenerId),
Certificates: []*aliga.AssociateAdditionalCertificatesWithListenerRequestCertificates{{
Id: tea.String(cloudCertId),
Domain: tea.String(d.config.Domain),
}},
}
associateAdditionalCertificatesWithListenerResp, err := d.sdkClient.AssociateAdditionalCertificatesWithListenerWithContext(ctx, associateAdditionalCertificatesWithListenerReq, &dara.RuntimeOptions{})
d.logger.Debug("sdk request 'ga.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesWithListenerReq), slog.Any("response", associateAdditionalCertificatesWithListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga.AssociateAdditionalCertificatesWithListener': %w", err)
}
}
@@ -177,7 +177,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no nlb listeners to deploy")
} else {
d.logger.Info("found tcpssl listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found nlb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
+61 -33
View File
@@ -146,52 +146,80 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
return nil, fmt.Errorf("could not find alb listener '%s'", d.config.ListenerArn)
}
listenerInfo := describeListenersResp.Listeners[0]
if len(listenerInfo.Certificates) > 0 {
d.logger.Info("found alb listener certificates in used", slog.Any("certificates", listenerInfo.Certificates))
}
if d.config.IsDefault {
if describeListenersResp.Listeners[0].Certificates != nil {
for _, cert := range describeListenersResp.Listeners[0].Certificates {
if aws.ToString(cert.CertificateArn) == upres.ExtendedData["Arn"].(string) {
d.logger.Info("no need to update alb listener default certificate")
return &DeployResult{}, nil
}
certArn := upres.ExtendedData["Arn"].(string)
for _, certItem := range listenerInfo.Certificates {
if aws.ToString(certItem.CertificateArn) == certArn && aws.ToBool(certItem.IsDefault) {
d.logger.Info("no need to update alb listener default certificate")
return &DeployResult{}, nil
}
}
// 更新 HTTPS 侦听器
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_ModifyListener.html
modifyListenerReq := &elasticloadbalancingv2.ModifyListenerInput{
ListenerArn: aws.String(d.config.ListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(upres.ExtendedData["Arn"].(string)),
},
},
}
modifyListenerResp, err := d.sdkClient.ModifyListener(ctx, modifyListenerReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.ModifyListener'", slog.Any("request", modifyListenerReq), slog.Any("response", modifyListenerResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.ModifyListener': %w", err)
if err := d.updateListenerDefaultCertificate(ctx, *listenerInfo.ListenerArn, certArn); err != nil {
return nil, err
}
} else {
// 将证书添加到证书列表
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_AddListenerCertificates.html
addListenerCertificatesReq := &elasticloadbalancingv2.AddListenerCertificatesInput{
ListenerArn: aws.String(d.config.ListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(upres.ExtendedData["Arn"].(string)),
},
},
certArn := upres.ExtendedData["Arn"].(string)
for _, certItem := range listenerInfo.Certificates {
if aws.ToString(certItem.CertificateArn) == certArn && !aws.ToBool(certItem.IsDefault) {
d.logger.Info("no need to add alb listener sni certificate")
return &DeployResult{}, nil
}
}
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(ctx, addListenerCertificatesReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.AddListenerCertificates'", slog.Any("request", addListenerCertificatesReq), slog.Any("response", addListenerCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.AddListenerCertificates': %w", err)
if err := d.updateListenerSniCertificate(ctx, *listenerInfo.ListenerArn, certArn); err != nil {
return nil, err
}
}
return &DeployResult{}, nil
}
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{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
modifyListenerResp, err := d.sdkClient.ModifyListener(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)
}
return nil
}
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{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(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)
}
return nil
}
func createSDKClient(accessKeyId, secretAccessKey, region string) (*elasticloadbalancingv2.Client, error) {
cfg, err := awscfg.LoadDefaultConfig(context.Background())
if err != nil {
+61 -33
View File
@@ -146,52 +146,80 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
return nil, fmt.Errorf("could not find nlb listener '%s'", d.config.ListenerArn)
}
listenerInfo := describeListenersResp.Listeners[0]
if len(listenerInfo.Certificates) > 0 {
d.logger.Info("found nlb listener certificates in used", slog.Any("certificates", listenerInfo.Certificates))
}
if d.config.IsDefault {
if describeListenersResp.Listeners[0].Certificates != nil {
for _, cert := range describeListenersResp.Listeners[0].Certificates {
if aws.ToString(cert.CertificateArn) == upres.ExtendedData["Arn"].(string) {
d.logger.Info("no need to update nlb listener default certificate")
return &DeployResult{}, nil
}
certArn := upres.ExtendedData["Arn"].(string)
for _, certItem := range listenerInfo.Certificates {
if aws.ToString(certItem.CertificateArn) == certArn && aws.ToBool(certItem.IsDefault) {
d.logger.Info("no need to update nlb listener default certificate")
return &DeployResult{}, nil
}
}
// 更新 HTTPS 侦听器
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_ModifyListener.html
modifyListenerReq := &elasticloadbalancingv2.ModifyListenerInput{
ListenerArn: aws.String(d.config.ListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(upres.ExtendedData["Arn"].(string)),
},
},
}
modifyListenerResp, err := d.sdkClient.ModifyListener(ctx, modifyListenerReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.ModifyListener'", slog.Any("request", modifyListenerReq), slog.Any("response", modifyListenerResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.ModifyListener': %w", err)
if err := d.updateListenerDefaultCertificate(ctx, *listenerInfo.ListenerArn, certArn); err != nil {
return nil, err
}
} else {
// 将证书添加到证书列表
// REF: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_AddListenerCertificates.html
addListenerCertificatesReq := &elasticloadbalancingv2.AddListenerCertificatesInput{
ListenerArn: aws.String(d.config.ListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(upres.ExtendedData["Arn"].(string)),
},
},
certArn := upres.ExtendedData["Arn"].(string)
for _, certItem := range listenerInfo.Certificates {
if aws.ToString(certItem.CertificateArn) == certArn && !aws.ToBool(certItem.IsDefault) {
d.logger.Info("no need to add nlb listener sni certificate")
return &DeployResult{}, nil
}
}
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(ctx, addListenerCertificatesReq)
d.logger.Debug("sdk request 'elasticloadbalancingv2.AddListenerCertificates'", slog.Any("request", addListenerCertificatesReq), slog.Any("response", addListenerCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'elasticloadbalancingv2.AddListenerCertificates': %w", err)
if err := d.updateListenerSniCertificate(ctx, *listenerInfo.ListenerArn, certArn); err != nil {
return nil, err
}
}
return &DeployResult{}, nil
}
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{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
modifyListenerResp, err := d.sdkClient.ModifyListener(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)
}
return nil
}
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{
ListenerArn: aws.String(cloudListenerArn),
Certificates: []types.Certificate{
{
CertificateArn: aws.String(cloudCertArn),
},
},
}
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(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)
}
return nil
}
func createSDKClient(accessKeyId, secretAccessKey, region string) (*elasticloadbalancingv2.Client, error) {
cfg, err := awscfg.LoadDefaultConfig(context.Background())
if err != nil {
@@ -151,9 +151,9 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
// 遍历更新监听证书
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
d.logger.Info("no appblb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
d.logger.Info("found appblb listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
@@ -216,7 +216,7 @@ func (d *Deployer) deployToListener(ctx context.Context, cloudCertId string) err
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
d.logger.Info("found appblb listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
@@ -262,54 +262,67 @@ func (d *Deployer) updateHttpsListenerCertificate(ctx context.Context, cloudLoad
if err != nil {
return fmt.Errorf("failed to execute sdk request 'appblb.DescribeAppHTTPSListeners': %w", err)
} else if len(describeAppHTTPSListenersResp.ListenerList) == 0 {
return fmt.Errorf("could not find listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
return fmt.Errorf("could not find appblb listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
}
listenerInfo := describeAppHTTPSListenersResp.ListenerList[0]
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#updateapphttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: uint16(cloudHttpsListenerPort),
Scheduler: describeAppHTTPSListenersResp.ListenerList[0].Scheduler,
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'appblb.UpdateAppHTTPSListener': %w", err)
if lo.SomeBy(listenerInfo.CertIds, func(item string) bool { return item == cloudCertId }) {
d.logger.Info("no need to update appblb listener default certificate")
return nil
}
return d.updateHttpsListenerDefaultCertificate(ctx, cloudLoadbalancerId, &listenerInfo, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateHttpsListenerSniCertificate(ctx, cloudLoadbalancerId, &listenerInfo, cloudCertId)
}
}
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: uint16(cloudHttpsListenerPort),
Scheduler: describeAppHTTPSListenersResp.ListenerList[0].Scheduler,
CertIds: describeAppHTTPSListenersResp.ListenerList[0].CertIds,
AdditionalCertDomains: lo.Map(describeAppHTTPSListenersResp.ListenerList[0].AdditionalCertDomains, func(domain bceappblb.AdditionalCertDomainsModel, _ int) bceappblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceappblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: cloudCertId,
}
}
func (d *Deployer) updateHttpsListenerDefaultCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerInfo *bceappblb.AppHTTPSListenerModel, cloudCertId string) error {
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#updateapphttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: cloudHttpsListenerInfo.ListenerPort,
Scheduler: cloudHttpsListenerInfo.Scheduler,
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'appblb.UpdateAppHTTPSListener': %w", err)
}
return nil
}
func (d *Deployer) updateHttpsListenerSniCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerInfo *bceappblb.AppHTTPSListenerModel, cloudCertId string) error {
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: cloudHttpsListenerInfo.ListenerPort,
Scheduler: cloudHttpsListenerInfo.Scheduler,
CertIds: cloudHttpsListenerInfo.CertIds,
AdditionalCertDomains: lo.Map(cloudHttpsListenerInfo.AdditionalCertDomains, func(domain bceappblb.AdditionalCertDomainsModel, _ int) bceappblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceappblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
CertId: cloudCertId,
}
}),
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'appblb.UpdateAppHTTPSListener': %w", err)
}
}
return bceappblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
}
}),
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'appblb.UpdateAppHTTPSListener': %w", err)
}
return nil
@@ -153,7 +153,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
d.logger.Info("found blb listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
@@ -216,7 +216,7 @@ func (d *Deployer) deployToListener(ctx context.Context, cloudCertId string) err
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
d.logger.Info("found blb listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
@@ -262,52 +262,65 @@ func (d *Deployer) updateHttpsListenerCertificate(ctx context.Context, cloudLoad
if err != nil {
return fmt.Errorf("failed to execute sdk request 'blb.DescribeHTTPSListeners': %w", err)
} else if len(describeHTTPSListenersResp.ListenerList) == 0 {
return fmt.Errorf("could not find listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
return fmt.Errorf("could not find blb listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
}
listenerInfo := describeHTTPSListenersResp.ListenerList[0]
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'blb.UpdateHTTPSListener': %w", err)
if lo.SomeBy(listenerInfo.CertIds, func(item string) bool { return item == cloudCertId }) {
d.logger.Info("no need to update blb listener default certificate")
return nil
}
return d.updateHttpsListenerDefaultCertificate(ctx, cloudLoadbalancerId, &listenerInfo, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateHttpsListenerSniCertificate(ctx, cloudLoadbalancerId, &listenerInfo, cloudCertId)
}
}
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: describeHTTPSListenersResp.ListenerList[0].CertIds,
AdditionalCertDomains: lo.Map(describeHTTPSListenersResp.ListenerList[0].AdditionalCertDomains, func(domain bceblb.AdditionalCertDomainsModel, _ int) bceblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: cloudCertId,
}
}
func (d *Deployer) updateHttpsListenerDefaultCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerInfo *bceblb.HTTPSListenerModel, cloudCertId string) error {
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: cloudHttpsListenerInfo.ListenerPort,
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'blb.UpdateHTTPSListener': %w", err)
}
return nil
}
func (d *Deployer) updateHttpsListenerSniCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerInfo *bceblb.HTTPSListenerModel, cloudCertId string) error {
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: security.RandomString(32),
ListenerPort: cloudHttpsListenerInfo.ListenerPort,
CertIds: cloudHttpsListenerInfo.CertIds,
AdditionalCertDomains: lo.Map(cloudHttpsListenerInfo.AdditionalCertDomains, func(domain bceblb.AdditionalCertDomainsModel, _ int) bceblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
CertId: cloudCertId,
}
}),
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'blb.UpdateHTTPSListener': %w", err)
}
}
return bceblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
}
}),
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'blb.UpdateHTTPSListener': %w", err)
}
return nil
@@ -172,7 +172,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no alb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found alb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -219,46 +219,55 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerI
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 修改指定监听器
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
ListenerId: bp.String(cloudListenerId),
CertificateSource: bp.String("cert_center"),
CertCenterCertificateId: bp.String(cloudCertId),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
if bp.StringValue(describeListenerAttributesResp.CertificateId) == cloudCertId {
d.logger.Info("no need to update alb listener default certificate")
return nil
}
return d.updateListenerDefaultCertificate(ctx, *describeListenerAttributesResp, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateListenerSniCertificate(ctx, *describeListenerAttributesResp, cloudCertId)
}
}
// 修改指定监听器
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
ListenerId: bp.String(cloudListenerId),
DomainExtensions: lo.Map(
lo.Filter(
describeListenerAttributesResp.DomainExtensions,
func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) bool {
return *domain.Domain == d.config.Domain
},
),
func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) *bpalb.DomainExtensionForModifyListenerAttributesInput {
return &bpalb.DomainExtensionForModifyListenerAttributesInput{
DomainExtensionId: domain.DomainExtensionId,
Domain: domain.Domain,
CertificateSource: bp.String("cert_center"),
CertCenterCertificateId: bp.String(cloudCertId),
Action: bp.String("modify"),
}
}),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerInfo bpalb.DescribeListenerAttributesOutput, cloudCertId string) error {
// 修改指定监听器
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
ListenerId: cloudListenerInfo.ListenerId,
CertificateSource: bp.String("cert_center"),
CertCenterCertificateId: bp.String(cloudCertId),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerInfo bpalb.DescribeListenerAttributesOutput, cloudCertId string) error {
// 修改指定监听器
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
ListenerId: cloudListenerInfo.ListenerId,
DomainExtensions: lo.Map(
lo.Filter(cloudListenerInfo.DomainExtensions, func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) bool {
return bp.StringValue(domain.Domain) == d.config.Domain
}),
func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) *bpalb.DomainExtensionForModifyListenerAttributesInput {
return &bpalb.DomainExtensionForModifyListenerAttributesInput{
DomainExtensionId: domain.DomainExtensionId,
Domain: domain.Domain,
CertificateSource: bp.String("cert_center"),
CertCenterCertificateId: bp.String(cloudCertId),
Action: bp.String("modify"),
}
}),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
return nil
@@ -169,7 +169,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no clb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found clb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -247,7 +247,8 @@ func (d *Deployer) updateDomainCertificate(ctx context.Context, cloudDomainId in
return fmt.Errorf("failed to execute sdk request 'ecdn.DescribeCdnCertificateDetail': %w", err)
} else {
if xcert.EqualCertificatesFromPEM(certPEM, lo.FromPtr(describeCdnCertificateDetailResp.Body.Certificate)) {
d.logger.Info("ssl certificate already deployed")
d.logger.Info("no need to update cdn certificate")
return nil
}
}
}
@@ -165,9 +165,9 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
// 遍历更新监听证书
if len(listenerIds) == 0 {
d.logger.Info("no elb listeners to deploy")
d.logger.Info("no vlb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found vlb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -248,52 +248,58 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerI
listLoadBalanceHTTPSListenerPage++
}
if listenerInfo == nil {
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
return fmt.Errorf("could not find vlb listener '%s'", cloudListenerId)
}
if d.config.Domain == "" {
// 未指定 SNI,只需部署到默认证书
if lo.FromPtr(listenerInfo.DefaultTlsContainerId) == cloudCertId {
d.logger.Info("ssl certificate already deployed")
d.logger.Info("no need to update vlb default certificate")
return nil
}
// 修改 HTTPS 监听器
// REF: https://ecloud.10086.cn/op-help-center/doc/article/97024
updateListenerReq := &model.UpdateListenerRequest{
&model.UpdateListenerBody{
Id: lo.ToPtr(cloudListenerId),
DefaultTlsContainerId: lo.ToPtr(cloudCertId),
},
}
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'vlb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'vlb.UpdateListener': %w", err)
}
return d.updateListenerDefaultCertificate(ctx, *listenerInfo, cloudCertId)
} else {
// 指定 SNI,需部署到 SNI 证书
if lo.Contains(listenerInfo.SniContainerIdList, cloudCertId) {
d.logger.Info("ssl certificate already deployed")
d.logger.Info("no need to update vlb sni certificate")
return nil
}
return d.updateListenerSniCertificate(ctx, *listenerInfo, cloudCertId)
}
}
// 修改 HTTPS 监听器
// REF: https://ecloud.10086.cn/op-help-center/doc/article/97024
updateListenerReq := &model.UpdateListenerRequest{
&model.UpdateListenerBody{
Id: lo.ToPtr(cloudListenerId),
SniUp: lo.ToPtr(true),
SniContainerIds: append(listenerInfo.SniContainerIdList, cloudCertId),
},
}
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'vlb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'vlb.UpdateListener': %w", err)
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerInfo model.ListLoadBalanceHTTPSListenerResponseContent, cloudCertId string) error {
// 修改 HTTPS 监听器
// REF: https://ecloud.10086.cn/op-help-center/doc/article/97024
updateListenerReq := &model.UpdateListenerRequest{
&model.UpdateListenerBody{
Id: cloudListenerInfo.Id,
DefaultTlsContainerId: lo.ToPtr(cloudCertId),
},
}
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'vlb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'vlb.UpdateListener': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerInfo model.ListLoadBalanceHTTPSListenerResponseContent, cloudCertId string) error {
// 修改 HTTPS 监听器
// REF: https://ecloud.10086.cn/op-help-center/doc/article/97024
updateListenerReq := &model.UpdateListenerRequest{
&model.UpdateListenerBody{
Id: cloudListenerInfo.Id,
SniUp: lo.ToPtr(true),
SniContainerIds: append(cloudListenerInfo.SniContainerIdList, cloudCertId),
},
}
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'vlb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'vlb.UpdateListener': %w", err)
}
return nil
@@ -140,7 +140,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no elb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found elb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -186,9 +186,9 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, certPEM, privkeyPEM
// 遍历更新监听器证书
if len(listenerIds) == 0 {
d.logger.Info("no listeners to deploy")
d.logger.Info("no elb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found elb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -171,9 +171,9 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
// 遍历更新监听器证书
if len(listenerIds) == 0 {
d.logger.Info("no listeners to deploy")
d.logger.Info("no alb listeners to deploy")
} else {
d.logger.Info("found https/tls listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found alb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
@@ -210,6 +210,32 @@ func (d *Deployer) deployToListener(ctx context.Context, cloudCertId string) err
}
func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
return d.updateListenerDefaultCertificate(ctx, cloudListenerId, cloudCertId)
} else {
// 指定 SNI,需部署到扩展证书
return d.updateListenerSniCertificate(ctx, cloudListenerId, cloudCertId)
}
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 修改监听器信息
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistener
updateListenerReq := jdlbapis.NewUpdateListenerRequestWithoutParam()
updateListenerReq.SetRegionId(d.config.RegionId)
updateListenerReq.SetListenerId(cloudListenerId)
updateListenerReq.SetCertificateSpecs([]jdlbmodels.CertificateSpec{{CertificateId: cloudCertId}})
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'lb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'lb.UpdateListener': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听器详情
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describelistener
describeListenerReq := jdlbapis.NewDescribeListenerRequestWithoutParam()
@@ -221,49 +247,46 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerI
return fmt.Errorf("failed to execute sdk request 'lb.DescribeListener': %w", err)
}
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 修改监听器信息
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistener
updateListenerReq := jdlbapis.NewUpdateListenerRequestWithoutParam()
updateListenerReq.SetRegionId(d.config.RegionId)
updateListenerReq.SetListenerId(cloudListenerId)
updateListenerReq.SetCertificateSpecs([]jdlbmodels.CertificateSpec{{CertificateId: cloudCertId}})
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'lb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'lb.UpdateListener': %w", err)
}
} else {
// 指定 SNI,需部署到扩展证书
extCertSpecs := lo.Filter(describeListenerResp.Result.Listener.ExtensionCertificateSpecs, func(extCertSpec jdlbmodels.ExtensionCertificateSpec, _ int) bool {
return extCertSpec.Domain == d.config.Domain
// 如果不存在,则添加扩展证书
// REF: https://docs.jdcloud.com/cn/load-balancer/api/addlistenercertificates
extCertSpecs := lo.Filter(describeListenerResp.Result.Listener.ExtensionCertificateSpecs, func(extCertSpec jdlbmodels.ExtensionCertificateSpec, _ int) bool {
return extCertSpec.Domain == d.config.Domain
})
if len(extCertSpecs) == 0 {
addListenerCertificatesReq := jdlbapis.NewAddListenerCertificatesRequestWithoutParam()
addListenerCertificatesReq.SetRegionId(d.config.RegionId)
addListenerCertificatesReq.SetListenerId(cloudListenerId)
addListenerCertificatesReq.SetCertificates([]jdlbmodels.ExtCertificateSpec{
{
CertificateId: cloudCertId,
Domain: d.config.Domain,
},
})
if len(extCertSpecs) == 0 {
return fmt.Errorf("could not find any extension certificates")
}
// 批量修改扩展证书
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistenercertificates
updateListenerCertificatesReq := jdlbapis.NewUpdateListenerCertificatesRequestWithoutParam()
updateListenerCertificatesReq.SetRegionId(d.config.RegionId)
updateListenerCertificatesReq.SetListenerId(cloudListenerId)
updateListenerCertificatesReq.SetCertificates(lo.Map(extCertSpecs, func(extCertSpec jdlbmodels.ExtensionCertificateSpec, _ int) jdlbmodels.ExtCertificateUpdateSpec {
return jdlbmodels.ExtCertificateUpdateSpec{
CertificateBindId: extCertSpec.CertificateBindId,
CertificateId: &cloudCertId,
Domain: &extCertSpec.Domain,
}
}))
updateListenerCertificatesResp, err := d.sdkClient.UpdateListenerCertificates(updateListenerCertificatesReq)
d.logger.Debug("sdk request 'lb.UpdateListenerCertificates'", slog.Any("request", updateListenerCertificatesReq), slog.Any("response", updateListenerCertificatesResp))
addListenerCertificatesResp, err := d.sdkClient.AddListenerCertificates(addListenerCertificatesReq)
d.logger.Debug("sdk request 'lb.AddListenerCertificates'", slog.Any("request", addListenerCertificatesReq), slog.Any("response", addListenerCertificatesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'lb.UpdateListenerCertificates': %w", err)
return fmt.Errorf("failed to execute sdk request 'lb.AddListenerCertificates': %w", err)
}
}
// 批量修改扩展证书
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistenercertificates
updateListenerCertificatesReq := jdlbapis.NewUpdateListenerCertificatesRequestWithoutParam()
updateListenerCertificatesReq.SetRegionId(d.config.RegionId)
updateListenerCertificatesReq.SetListenerId(cloudListenerId)
updateListenerCertificatesReq.SetCertificates(lo.Map(extCertSpecs, func(extCertSpec jdlbmodels.ExtensionCertificateSpec, _ int) jdlbmodels.ExtCertificateUpdateSpec {
return jdlbmodels.ExtCertificateUpdateSpec{
CertificateBindId: extCertSpec.CertificateBindId,
CertificateId: &cloudCertId,
Domain: &extCertSpec.Domain,
}
}))
updateListenerCertificatesResp, err := d.sdkClient.UpdateListenerCertificates(updateListenerCertificatesReq)
d.logger.Debug("sdk request 'lb.UpdateListenerCertificates'", slog.Any("request", updateListenerCertificatesReq), slog.Any("response", updateListenerCertificatesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'lb.UpdateListenerCertificates': %w", err)
}
return nil
}
@@ -156,9 +156,9 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, certPEM, privkeyPEM
// 遍历更新监听器证书
if len(listenerIds) == 0 {
d.logger.Info("no listeners to deploy")
d.logger.Info("no lb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found lb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -160,7 +160,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no clb listeners to deploy")
} else {
d.logger.Info("found https/tcpssl/quic listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found clb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -240,10 +240,10 @@ func (d *Deployer) deployToRuleDomain(ctx context.Context, cloudCertId string) e
case 0:
return true, nil
case 1:
return false, fmt.Errorf("unexpected tencentcloud task status")
return false, fmt.Errorf("unexpected deployment task status")
}
d.logger.Info("waiting for tencentcloud task completion ...")
d.logger.Info("waiting for deployment task completion ...")
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -263,7 +263,7 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudLoadbalan
if err != nil {
return fmt.Errorf("failed to execute sdk request 'clb.DescribeListeners': %w", err)
} else if len(describeListenersResp.Response.Listeners) == 0 {
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
return fmt.Errorf("could not find clb listener '%s'", cloudListenerId)
}
// 修改监听器属性
@@ -299,10 +299,10 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudLoadbalan
case 0:
return true, nil
case 1:
return false, fmt.Errorf("unexpected tencentcloud task status")
return false, fmt.Errorf("unexpected deployment task status")
}
d.logger.Info("waiting for tencentcloud task completion ...")
d.logger.Info("waiting for deployment task completion ...")
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -105,7 +105,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
// 避免多次部署,否则会报错 https://github.com/certimate-go/certimate/issues/897#issuecomment-3182904098
if bind, _ := d.checkIsBind(ctx, upres.CertId); bind {
d.logger.Info("ssl certificate already deployed")
d.logger.Info("no need to update cos custom domain certificate")
return &DeployResult{}, nil
}
@@ -135,7 +135,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
return false, fmt.Errorf("unexpected deployment deployment job status")
} else {
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
@@ -145,13 +145,13 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
if succeededCount+failedCount == totalCount {
if failedCount > 0 {
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
return false, fmt.Errorf("unexpected deployment deployment job status (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
}
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))
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
return false, nil
}, 10*time.Second); err != nil {
return nil, err
@@ -174,7 +174,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
return domain == lo.FromPtr(domainInfo.DomainName)
})
if domainInfo != nil && domainInfo.Certificate != nil {
deployed = lo.ContainsBy(domainInfo.Certificate.List, func(certInfo *tceo.CertificateInfo) bool {
deployed = lo.SomeBy(domainInfo.Certificate.List, func(certInfo *tceo.CertificateInfo) bool {
return upres.CertId == lo.FromPtr(certInfo.CertId)
})
}
@@ -160,7 +160,7 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudAccelerat
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ga2.DescribeListeners': %w", err)
} else if len(describeListenersResp.Response.ListenerSet) == 0 {
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
return fmt.Errorf("could not find ga2 listener '%s'", cloudListenerId)
}
// 获取证书信息,避免重复绑定
@@ -134,7 +134,7 @@ func (d *Deployer) updateHttpsListenerCertificate(ctx context.Context, cloudList
if err != nil {
return fmt.Errorf("failed to execute sdk request 'gaap.DescribeHTTPSListeners': %w", err)
} else if len(describeHTTPSListenersResp.Response.ListenerSet) == 0 {
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
return fmt.Errorf("could not find gaap listener '%s'", cloudListenerId)
}
// 修改 HTTPS 监听器配置
@@ -131,7 +131,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
return false, fmt.Errorf("unexpected deployment deployment job status")
} else {
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
@@ -141,13 +141,13 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
if succeededCount+failedCount == totalCount {
if failedCount > 0 {
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
return false, fmt.Errorf("unexpected deployment deployment job status (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
}
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))
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
return false, nil
}, 10*time.Second); err != nil {
return nil, err
@@ -161,7 +161,7 @@ func (d *Deployer) executeUpdateCertificateInstance(ctx context.Context, certPEM
var pendingCount, runningCount, succeededCount, failedCount, totalCount int64
if describeHostUpdateRecordDetailResp.Response.TotalCount == nil {
return false, fmt.Errorf("unexpected tencentcloud deployment job status")
return false, fmt.Errorf("unexpected deployment job status")
} else {
pendingCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.PendingTotalCount)
runningCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.RunningTotalCount)
@@ -171,13 +171,13 @@ func (d *Deployer) executeUpdateCertificateInstance(ctx context.Context, certPEM
if succeededCount+failedCount == totalCount {
if failedCount > 0 {
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
return false, fmt.Errorf("unexpected deployment deployment job status (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
}
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))
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (pending: %d, running: %d, succeeded: %d, failed: %d, total: %d) ...", pendingCount, runningCount, succeededCount, failedCount, totalCount))
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -240,13 +240,13 @@ func (d *Deployer) executeUploadUpdateCertificateInstance(ctx context.Context, c
if succeededCount+failedCount == totalCount {
if failedCount > 0 {
return false, fmt.Errorf("tencentcloud deployment job failed (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
return false, fmt.Errorf("unexpected deployment deployment job status (succeeded: %d, failed: %d, total: %d)", succeededCount, failedCount, totalCount)
}
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))
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -163,7 +163,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no alb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found alb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -212,89 +212,102 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudLoadbalan
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.DescribeListeners': %w", err)
} else if len(describeListenerResp.Listeners) == 0 {
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
return fmt.Errorf("could not find alb listener '%s'", cloudListenerId)
}
// 跳过已部署过的监听器
listenerInfo := describeListenerResp.Listeners[0]
if d.config.Domain == "" {
if lo.ContainsBy(listenerInfo.Certificates, func(item ulb.Certificate) bool { return item.SSLId == cloudCertId && item.IsDefault }) {
return nil
}
} else {
if lo.ContainsBy(listenerInfo.Certificates, func(item ulb.Certificate) bool { return item.SSLId == cloudCertId && !item.IsDefault }) {
return nil
}
if len(listenerInfo.Certificates) > 0 {
d.logger.Info("found alb listener certificates in used", slog.Any("certificates", listenerInfo.Certificates))
}
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
updateListenerAttributeReq := d.sdkClient.NewUpdateListenerAttributeRequest()
updateListenerAttributeReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
updateListenerAttributeReq.ListenerId = ucloud.String(cloudListenerId)
updateListenerAttributeReq.Certificates = []string{cloudCertId}
updateListenerResp, err := d.sdkClient.UpdateListenerAttribute(updateListenerAttributeReq)
d.logger.Debug("sdk request 'ulb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.UpdateListenerAttribute': %w", err)
if lo.SomeBy(listenerInfo.Certificates, func(item ulb.Certificate) bool { return item.SSLId == cloudCertId && item.IsDefault }) {
d.logger.Info("no need to update alb listener default certificate")
return nil
}
return d.updateListenerDefaultCertificate(ctx, cloudLoadbalancerId, cloudListenerId, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
if lo.SomeBy(listenerInfo.Certificates, func(item ulb.Certificate) bool { return item.SSLId == cloudCertId && !item.IsDefault }) {
d.logger.Info("no need to add alb listener sni certificate")
return nil
}
return d.updateListenerSniCertificate(ctx, cloudLoadbalancerId, listenerInfo, cloudCertId)
}
}
// 新增监听器扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/add_ssl_binding_json
addSSLBindingReq := d.sdkClient.NewAddSSLBindingRequest()
addSSLBindingReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
addSSLBindingReq.ListenerId = ucloud.String(cloudListenerId)
addSSLBindingReq.SSLIds = []string{cloudCertId}
addSSLBindingResp, err := d.sdkClient.AddSSLBinding(addSSLBindingReq)
d.logger.Debug("sdk request 'ulb.AddSSLBinding'", slog.Any("request", addSSLBindingReq), slog.Any("response", addSSLBindingResp))
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudLoadbalancerId, cloudListenerId string, cloudCertId string) error {
// 更新应用型负载均衡监听器属性
// REF: https://docs.ucloud.cn/api/ulb-api/update_listener_attribute_json
updateListenerAttributeReq := d.sdkClient.NewUpdateListenerAttributeRequest()
updateListenerAttributeReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
updateListenerAttributeReq.ListenerId = ucloud.String(cloudListenerId)
updateListenerAttributeReq.Certificates = []string{cloudCertId}
updateListenerResp, err := d.sdkClient.UpdateListenerAttribute(updateListenerAttributeReq)
d.logger.Debug("sdk request 'ulb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.UpdateListenerAttribute': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerInfo ulb.Listener, cloudCertId string) error {
// 新增监听器扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/add_ssl_binding_json
addSSLBindingReq := d.sdkClient.NewAddSSLBindingRequest()
addSSLBindingReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
addSSLBindingReq.ListenerId = ucloud.String(cloudListenerInfo.ListenerId)
addSSLBindingReq.SSLIds = []string{cloudCertId}
addSSLBindingResp, err := d.sdkClient.AddSSLBinding(addSSLBindingReq)
d.logger.Debug("sdk request 'ulb.AddSSLBinding'", slog.Any("request", addSSLBindingReq), slog.Any("response", addSSLBindingResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.AddSSLBinding': %w", err)
}
// 找出需要删除绑定的扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/describe_sslv2
sslIdsToDelete := make([]string, 0)
for _, certItem := range cloudListenerInfo.Certificates {
if certItem.IsDefault {
continue
}
describeSSLV2Req := d.sdkClient.NewDescribeSSLV2Request()
describeSSLV2Req.SSLId = ucloud.String(certItem.SSLId)
describeSSLV2Req.Limit = ucloud.Int(1)
describeSSLV2Resp, err := d.sdkClient.DescribeSSLV2(describeSSLV2Req)
d.logger.Debug("sdk request 'ulb.DescribeSSLV2'", slog.Any("request", describeSSLV2Req), slog.Any("response", describeSSLV2Resp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.AddSSLBinding': %w", err)
continue
} else if len(describeSSLV2Resp.DataSet) == 0 {
continue
}
// 找出需要删除绑定的扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/describe_sslv2
sslIdsToDelete := make([]string, 0)
for _, certItem := range listenerInfo.Certificates {
if certItem.IsDefault {
continue
}
describeSSLV2Req := d.sdkClient.NewDescribeSSLV2Request()
describeSSLV2Req.SSLId = ucloud.String(certItem.SSLId)
describeSSLV2Req.Limit = ucloud.Int(1)
describeSSLV2Resp, err := d.sdkClient.DescribeSSLV2(describeSSLV2Req)
d.logger.Debug("sdk request 'ulb.DescribeSSLV2'", slog.Any("request", describeSSLV2Req), slog.Any("response", describeSSLV2Resp))
if err != nil {
continue
} else if len(describeSSLV2Resp.DataSet) == 0 {
continue
}
sslItem := describeSSLV2Resp.DataSet[0]
if sslItem.NotAfter != 0 && int64(sslItem.NotAfter) < time.Now().Unix() {
sslIdsToDelete = append(sslIdsToDelete, sslItem.SSLId) // 过期证书需要删除
continue
} else if sslItem.Domains == d.config.Domain {
sslIdsToDelete = append(sslIdsToDelete, sslItem.SSLId) // 同域名证书需要删除
continue
}
sslItem := describeSSLV2Resp.DataSet[0]
if sslItem.Domains == d.config.Domain {
sslIdsToDelete = append(sslIdsToDelete, sslItem.SSLId) // 同域名证书需要删除
continue
} else if sslItem.NotAfter != 0 && int64(sslItem.NotAfter) < time.Now().Unix() {
sslIdsToDelete = append(sslIdsToDelete, sslItem.SSLId) // 过期证书需要删除。TODO: remove on v0.5
continue
}
}
// 删除监听器绑定的扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/delete_ssl_binding_json
if len(sslIdsToDelete) > 0 {
deleteSSLBindingReq := d.sdkClient.NewDeleteSSLBindingRequest()
deleteSSLBindingReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
deleteSSLBindingReq.ListenerId = ucloud.String(cloudListenerId)
deleteSSLBindingReq.SSLIds = sslIdsToDelete
deleteSSLBindingResp, err := d.sdkClient.DeleteSSLBinding(deleteSSLBindingReq)
d.logger.Debug("sdk request 'ulb.DeleteSSLBinding'", slog.Any("request", deleteSSLBindingReq), slog.Any("response", deleteSSLBindingResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.DeleteSSLBinding': %w", err)
}
// 删除监听器绑定的扩展证书
// REF: https://docs.ucloud.cn/api/ulb-api/delete_ssl_binding_json
if len(sslIdsToDelete) > 0 {
d.logger.Info("found alb listener certificates to unbind", slog.Any("sslIds", sslIdsToDelete))
deleteSSLBindingReq := d.sdkClient.NewDeleteSSLBindingRequest()
deleteSSLBindingReq.LoadBalancerId = ucloud.String(cloudLoadbalancerId)
deleteSSLBindingReq.ListenerId = ucloud.String(cloudListenerInfo.ListenerId)
deleteSSLBindingReq.SSLIds = sslIdsToDelete
deleteSSLBindingResp, err := d.sdkClient.DeleteSSLBinding(deleteSSLBindingReq)
d.logger.Debug("sdk request 'ulb.DeleteSSLBinding'", slog.Any("request", deleteSSLBindingReq), slog.Any("response", deleteSSLBindingResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.DeleteSSLBinding': %w", err)
}
}
@@ -170,7 +170,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(vserverIds) == 0 {
d.logger.Info("no clb vservers to deploy")
} else {
d.logger.Info("found https vservers to deploy", slog.Any("vserverIds", vserverIds))
d.logger.Info("found clb vservers to deploy", slog.Any("vserverIds", vserverIds))
var errs []error
for _, vserverId := range vserverIds {
@@ -219,12 +219,12 @@ func (d *Deployer) updateVServerCertificate(ctx context.Context, cloudLoadbalanc
if err != nil {
return fmt.Errorf("failed to execute sdk request 'ulb.DescribeVServer': %w", err)
} else if len(describeVServerResp.DataSet) == 0 {
return fmt.Errorf("could not find vserver '%s'", cloudVServerId)
return fmt.Errorf("could not find uclb vserver '%s'", cloudVServerId)
}
// 跳过已部署过的 VServer
vserverInfo := describeVServerResp.DataSet[0]
if lo.ContainsBy(vserverInfo.SSLSet, func(item ulb.ULBSSLSet) bool { return item.SSLId == cloudCertId }) {
if lo.SomeBy(vserverInfo.SSLSet, func(item ulb.ULBSSLSet) bool { return item.SSLId == cloudCertId }) {
return nil
}
@@ -174,7 +174,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no alb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found alb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -222,48 +222,57 @@ func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerI
if d.config.Domain == "" {
// 未指定 SNI,只需部署到监听器
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: ve.String(cloudListenerId),
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
if ve.StringValue(describeListenerAttributesResp.CertificateId) == cloudCertId {
d.logger.Info("no need to update alb listener default certificate")
return nil
}
return d.updateListenerDefaultCertificate(ctx, *describeListenerAttributesResp, cloudCertId)
} else {
// 指定 SNI,需部署到扩展域名
return d.updateListenerSniCertificate(ctx, *describeListenerAttributesResp, cloudCertId)
}
}
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: ve.String(cloudListenerId),
DomainExtensions: lo.Map(
lo.Filter(
describeListenerAttributesResp.DomainExtensions,
func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput, _ int) bool {
return *domain.Domain == d.config.Domain
},
),
func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput, _ int) *vealb.DomainExtensionForModifyListenerAttributesInput {
return &vealb.DomainExtensionForModifyListenerAttributesInput{
DomainExtensionId: domain.DomainExtensionId,
Domain: domain.Domain,
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
Action: ve.String("modify"),
}
}),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
func (d *Deployer) updateListenerDefaultCertificate(ctx context.Context, cloudListenerInfo vealb.DescribeListenerAttributesOutput, cloudCertId string) error {
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: cloudListenerInfo.ListenerId,
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
return nil
}
func (d *Deployer) updateListenerSniCertificate(ctx context.Context, cloudListenerInfo vealb.DescribeListenerAttributesOutput, cloudCertId string) error {
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: cloudListenerInfo.ListenerId,
DomainExtensions: lo.Map(
lo.Filter(cloudListenerInfo.DomainExtensions, func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput, _ int) bool {
return *domain.Domain == d.config.Domain
}),
func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput, _ int) *vealb.DomainExtensionForModifyListenerAttributesInput {
return &vealb.DomainExtensionForModifyListenerAttributesInput{
DomainExtensionId: domain.DomainExtensionId,
Domain: domain.Domain,
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
Action: ve.String("modify"),
}
}),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
}
return nil
@@ -169,7 +169,7 @@ func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string)
if len(listenerIds) == 0 {
d.logger.Info("no clb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
d.logger.Info("found clb listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
@@ -203,12 +203,12 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*Dep
}
if getDeploymentTaskDetailResp.Status == "failed" {
return false, fmt.Errorf("unexpected wangsu deployment task status")
return false, fmt.Errorf("unexpected deployment task status")
} else if getDeploymentTaskDetailResp.Status == "succeeded" || getDeploymentTaskDetailResp.FinishTime != "" {
return true, nil
}
d.logger.Info(fmt.Sprintf("waiting for wangsu deployment task completion (current status: %s) ...", getDeploymentTaskDetailResp.Status))
d.logger.Info(fmt.Sprintf("waiting for deployment task completion (current status: %s) ...", getDeploymentTaskDetailResp.Status))
return false, nil
}, 10*time.Second); err != nil {
return nil, err
@@ -318,10 +318,10 @@ func (d *Deployer) updateDomainCertificate(ctx context.Context, cloudDomainId st
case "DEPLOYED":
return true, nil
case "FAILED":
return false, fmt.Errorf("unexpected zenlayer domain status")
return false, fmt.Errorf("unexpected domain status")
}
d.logger.Info("waiting for zenlayer domain deploying completion ...")
d.logger.Info("waiting for domain deploying completion ...")
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -162,10 +162,10 @@ func (d *Deployer) deployToAccelerator(ctx context.Context, certPEM, privkeyPEM
case "Accelerating":
return true, nil
case "NotAccelerate", "StopAccelerate", "AccelerateFailure":
return false, fmt.Errorf("unexpected zenlayer accelerator status")
return false, fmt.Errorf("unexpected accelerator status")
}
d.logger.Info("waiting for zenlayer accelerator deploying completion ...")
d.logger.Info("waiting for accelerator deploying completion ...")
return false, nil
}, 10*time.Second); err != nil {
return err
@@ -35,6 +35,25 @@ func (c *LbClient) DisableLogger() {
c.Logger = core.NewDummyLogger()
}
func (c *LbClient) AddListenerCertificates(request *lb.AddListenerCertificatesRequest) (*lb.AddListenerCertificatesResponse, error) {
if request == nil {
return nil, errors.New("Request object is nil.")
}
resp, err := c.Send(request, c.ServiceName)
if err != nil {
return nil, err
}
jdResp := &lb.AddListenerCertificatesResponse{}
err = json.Unmarshal(resp, jdResp)
if err != nil {
c.Logger.Log(core.LogError, "Unmarshal json failed, resp: %s", string(resp))
return nil, err
}
return jdResp, err
}
func (c *LbClient) DescribeListener(request *lb.DescribeListenerRequest) (*lb.DescribeListenerResponse, error) {
if request == nil {
return nil, errors.New("Request object is nil.")