mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
refactor: clean code
This commit is contained in:
@@ -17,9 +17,10 @@ func init() {
|
||||
}
|
||||
|
||||
provider, err := baishancdn.NewSSLDeployerProvider(&baishancdn.SSLDeployerProviderConfig{
|
||||
ApiToken: credentials.ApiToken,
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"),
|
||||
ApiToken: credentials.ApiToken,
|
||||
DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"),
|
||||
})
|
||||
return provider, err
|
||||
})
|
||||
|
||||
@@ -20,9 +20,10 @@ func init() {
|
||||
}
|
||||
|
||||
provider, err := wangsucdn.NewSSLDeployerProvider(&wangsucdn.SSLDeployerProviderConfig{
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
AccessKeySecret: credentials.AccessKeySecret,
|
||||
Domains: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "domains"), ";"), func(s string, _ int) bool { return s != "" }),
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
AccessKeySecret: credentials.AccessKeySecret,
|
||||
DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"),
|
||||
Domains: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "domains"), ";"), func(s string, _ int) bool { return s != "" }),
|
||||
})
|
||||
return provider, err
|
||||
})
|
||||
|
||||
@@ -17,13 +17,14 @@ func init() {
|
||||
}
|
||||
|
||||
provider, err := wangsucdnpro.NewSSLDeployerProvider(&wangsucdnpro.SSLDeployerProviderConfig{
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
AccessKeySecret: credentials.AccessKeySecret,
|
||||
ApiKey: credentials.ApiKey,
|
||||
Environment: xmaps.GetOrDefaultString(options.ProviderExtendedConfig, "environment", "production"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"),
|
||||
WebhookId: xmaps.GetString(options.ProviderExtendedConfig, "webhookId"),
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
AccessKeySecret: credentials.AccessKeySecret,
|
||||
ApiKey: credentials.ApiKey,
|
||||
Environment: xmaps.GetOrDefaultString(options.ProviderExtendedConfig, "environment", "production"),
|
||||
DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"),
|
||||
WebhookId: xmaps.GetString(options.ProviderExtendedConfig, "webhookId"),
|
||||
})
|
||||
return provider, err
|
||||
})
|
||||
|
||||
@@ -106,7 +106,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
}
|
||||
|
||||
siteName := dns01.UnFqdn(authZone)
|
||||
siteID, err := d.getSiteId(siteName)
|
||||
siteID, err := d.findSiteIdByName(siteName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("alicloud-esa: could not find site for zone %q: %w", siteName, err)
|
||||
}
|
||||
@@ -158,17 +158,17 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||
}
|
||||
|
||||
func (d *DNSProvider) getSiteId(siteName string) (int64, error) {
|
||||
pageNumber := 1
|
||||
pageSize := 500
|
||||
func (d *DNSProvider) findSiteIdByName(siteName string) (int64, error) {
|
||||
aliListSitesPageNumber := 1
|
||||
aliListSitesPageSize := 500
|
||||
for {
|
||||
// REF: https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/api-esa-2024-09-10-listsites
|
||||
aliListSitesReq := &aliesa.ListSitesRequest{
|
||||
SiteName: tea.String(siteName),
|
||||
SiteSearchType: tea.String("exact"),
|
||||
PageNumber: tea.Int32(int32(pageNumber)),
|
||||
PageSize: tea.Int32(int32(pageSize)),
|
||||
AccessType: tea.String("NS"),
|
||||
PageNumber: tea.Int32(int32(aliListSitesPageNumber)),
|
||||
PageSize: tea.Int32(int32(aliListSitesPageSize)),
|
||||
}
|
||||
aliListSitesResp, err := d.client.ListSites(aliListSitesReq)
|
||||
if err != nil {
|
||||
@@ -177,20 +177,20 @@ func (d *DNSProvider) getSiteId(siteName string) (int64, error) {
|
||||
|
||||
if aliListSitesResp.Body == nil {
|
||||
break
|
||||
} else {
|
||||
for _, site := range aliListSitesResp.Body.Sites {
|
||||
if *site.GetSiteName() == siteName {
|
||||
return *site.GetSiteId(), nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(aliListSitesResp.Body.Sites) < pageSize {
|
||||
break
|
||||
}
|
||||
|
||||
pageNumber++
|
||||
}
|
||||
|
||||
for _, siteItem := range aliListSitesResp.Body.Sites {
|
||||
if *siteItem.GetSiteName() == siteName {
|
||||
return *siteItem.GetSiteId(), nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(aliListSitesResp.Body.Sites) < aliListSitesPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
aliListSitesPageNumber++
|
||||
}
|
||||
|
||||
return 0, errors.New("site not found")
|
||||
return 0, fmt.Errorf("could not find site '%s'", siteName)
|
||||
}
|
||||
|
||||
@@ -145,31 +145,31 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||
}
|
||||
|
||||
func (d *DNSProvider) findDNSRecord(zoneName, subDomain, tokenValue string) (*bcedns.Record, error) {
|
||||
pageMarker := ""
|
||||
pageSize := 1000
|
||||
bceListRecordPageMarker := ""
|
||||
for {
|
||||
// REF: https://cloud.baidu.com/doc/DNS/s/El4s7lssr#%E6%9F%A5%E8%AF%A2%E8%A7%A3%E6%9E%90%E8%AE%B0%E5%BD%95%E5%88%97%E8%A1%A8
|
||||
bceListRecordReq := &bcedns.ListRecordRequest{}
|
||||
bceListRecordReq.Rr = subDomain
|
||||
bceListRecordReq.Marker = pageMarker
|
||||
bceListRecordReq.MaxKeys = pageSize
|
||||
bceListRecordReq.Marker = bceListRecordPageMarker
|
||||
bceListRecordReq.MaxKeys = 1000
|
||||
|
||||
ceListRecordResp, err := d.client.ListRecord(zoneName, bceListRecordReq)
|
||||
bceListRecordResp, err := d.client.ListRecord(zoneName, bceListRecordReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, record := range ceListRecordResp.Records {
|
||||
for _, record := range bceListRecordResp.Records {
|
||||
if record.Type == "TXT" && record.Rr == subDomain && record.Value == tokenValue {
|
||||
return &record, nil
|
||||
}
|
||||
}
|
||||
|
||||
pageMarker = ceListRecordResp.NextMarker
|
||||
if pageMarker == "" {
|
||||
if bceListRecordResp.NextMarker == "" {
|
||||
break
|
||||
}
|
||||
|
||||
bceListRecordPageMarker = bceListRecordResp.NextMarker
|
||||
}
|
||||
|
||||
return nil, errors.New("record not found")
|
||||
return nil, errors.New("could not find record")
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
return fmt.Errorf("dnsla: %w", err)
|
||||
}
|
||||
|
||||
zone, err := d.getDNSZone(dns01.UnFqdn(authZone))
|
||||
zone, err := d.findZone(dns01.UnFqdn(authZone))
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnsla: error when list zones: %w", err)
|
||||
}
|
||||
@@ -149,34 +149,36 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||
}
|
||||
|
||||
func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainRecord, error) {
|
||||
pageIndex := int32(1)
|
||||
pageSize := int32(100)
|
||||
func (d *DNSProvider) findZone(zoneName string) (*dnslasdk.DomainRecord, error) {
|
||||
dnslaListDomainsPageIndex := 1
|
||||
dnslaListDomainsPageSize := 100
|
||||
for {
|
||||
// REF: https://www.dnsla.cn/docs/ApiDoc
|
||||
dnslaListDomainsReq := &dnslasdk.ListDomainsRequest{
|
||||
PageIndex: &pageIndex,
|
||||
PageSize: &pageSize,
|
||||
PageIndex: lo.ToPtr(int32(dnslaListDomainsPageIndex)),
|
||||
PageSize: lo.ToPtr(int32(dnslaListDomainsPageSize)),
|
||||
}
|
||||
dnslaListDomainsResp, err := d.client.ListDomains(dnslaListDomainsReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dnslaListDomainsResp.Data != nil {
|
||||
for _, item := range dnslaListDomainsResp.Data.Results {
|
||||
if strings.TrimRight(item.Domain, ".") == zoneName || strings.TrimRight(item.DisplayDomain, ".") == zoneName {
|
||||
return item, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if dnslaListDomainsResp.Data == nil || len(dnslaListDomainsResp.Data.Results) < int(pageSize) {
|
||||
if dnslaListDomainsResp.Data == nil {
|
||||
break
|
||||
}
|
||||
|
||||
pageIndex++
|
||||
for _, domainItem := range dnslaListDomainsResp.Data.Results {
|
||||
if strings.TrimRight(domainItem.Domain, ".") == zoneName || strings.TrimRight(domainItem.DisplayDomain, ".") == zoneName {
|
||||
return domainItem, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(dnslaListDomainsResp.Data.Results) < dnslaListDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
dnslaListDomainsPageIndex++
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("zone '%s' not found", zoneName)
|
||||
return nil, fmt.Errorf("could not find zone '%s'", zoneName)
|
||||
}
|
||||
|
||||
@@ -137,5 +137,5 @@ func (d *DNSProvider) findDNSRecord(zoneName, subDomain, tokenValue string) (lib
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("record not found")
|
||||
return nil, errors.New("could not find record")
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
return fmt.Errorf("jdcloud: %w", err)
|
||||
}
|
||||
|
||||
zone, err := d.getDNSZone(dns01.UnFqdn(authZone))
|
||||
zone, err := d.findZone(dns01.UnFqdn(authZone))
|
||||
if err != nil {
|
||||
return fmt.Errorf("jdcloud: error when list zones: %w", err)
|
||||
}
|
||||
@@ -144,7 +144,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
return fmt.Errorf("jdcloud: unknown record ID for '%s'", info.EffectiveFQDN)
|
||||
}
|
||||
|
||||
zone, err := d.getDNSZone(dns01.UnFqdn(authZone))
|
||||
zone, err := d.findZone(dns01.UnFqdn(authZone))
|
||||
if err != nil {
|
||||
return fmt.Errorf("jdcloud: error when list zones: %w", err)
|
||||
}
|
||||
@@ -166,15 +166,15 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||
return d.config.PropagationTimeout, d.config.PollingInterval
|
||||
}
|
||||
|
||||
func (d *DNSProvider) getDNSZone(zoneName string) (*jddnsmodel.DomainInfo, error) {
|
||||
pageNumber := 1
|
||||
pageSize := 10
|
||||
func (d *DNSProvider) findZone(zoneName string) (*jddnsmodel.DomainInfo, error) {
|
||||
jddnsDescribeDomainsPageNumber := 1
|
||||
jddnsDescribeDomainsPageSize := 10
|
||||
for {
|
||||
// REF: https://docs.jdcloud.com/cn/jd-cloud-dns/api/describedomains
|
||||
jddnsDescribeDomainsReq := jddns.NewDescribeDomainsRequestWithoutParam()
|
||||
jddnsDescribeDomainsReq.SetRegionId(d.config.RegionId)
|
||||
jddnsDescribeDomainsReq.SetPageNumber(pageNumber)
|
||||
jddnsDescribeDomainsReq.SetPageSize(pageSize)
|
||||
jddnsDescribeDomainsReq.SetPageNumber(jddnsDescribeDomainsPageNumber)
|
||||
jddnsDescribeDomainsReq.SetPageSize(jddnsDescribeDomainsPageSize)
|
||||
jddnsDescribeDomainsReq.SetDomainName(zoneName)
|
||||
|
||||
jddnsDescribeDomainsResp, err := d.client.DescribeDomains(jddnsDescribeDomainsReq)
|
||||
@@ -182,18 +182,18 @@ func (d *DNSProvider) getDNSZone(zoneName string) (*jddnsmodel.DomainInfo, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, item := range jddnsDescribeDomainsResp.Result.DataList {
|
||||
if item.DomainName == zoneName {
|
||||
return &item, nil
|
||||
for _, domainItem := range jddnsDescribeDomainsResp.Result.DataList {
|
||||
if domainItem.DomainName == zoneName {
|
||||
return &domainItem, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(jddnsDescribeDomainsResp.Result.DataList) < pageSize {
|
||||
if len(jddnsDescribeDomainsResp.Result.DataList) < jddnsDescribeDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
pageNumber++
|
||||
jddnsDescribeDomainsPageNumber++
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("jdcloud: zone %s not found", zoneName)
|
||||
return nil, fmt.Errorf("could not find zone '%s'", zoneName)
|
||||
}
|
||||
|
||||
@@ -144,8 +144,7 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询 HTTPS 监听列表
|
||||
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlisteners
|
||||
listenerIds := make([]string, 0)
|
||||
listListenersLimit := int32(100)
|
||||
var listListenersToken *string = nil
|
||||
listListenersToken := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -154,9 +153,9 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
}
|
||||
|
||||
listListenersReq := &alialb.ListListenersRequest{
|
||||
MaxResults: tea.Int32(listListenersLimit),
|
||||
NextToken: listListenersToken,
|
||||
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
|
||||
MaxResults: tea.Int32(100),
|
||||
LoadBalancerIds: tea.StringSlice([]string{d.config.LoadbalancerId}),
|
||||
ListenerProtocol: tea.String("HTTPS"),
|
||||
}
|
||||
listListenersResp, err := d.sdkClients.ALB.ListListenersWithContext(context.TODO(), listListenersReq, &dara.RuntimeOptions{})
|
||||
@@ -165,17 +164,19 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.ListListeners': %w", err)
|
||||
}
|
||||
|
||||
if listListenersResp.Body.Listeners != nil {
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
if listListenersResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
|
||||
if len(listListenersResp.Body.Listeners) == 0 || listListenersResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
// 查询 QUIC 监听列表
|
||||
@@ -189,9 +190,9 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
}
|
||||
|
||||
listListenersReq := &alialb.ListListenersRequest{
|
||||
MaxResults: tea.Int32(listListenersLimit),
|
||||
NextToken: listListenersToken,
|
||||
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
|
||||
MaxResults: tea.Int32(100),
|
||||
LoadBalancerIds: tea.StringSlice([]string{d.config.LoadbalancerId}),
|
||||
ListenerProtocol: tea.String("QUIC"),
|
||||
}
|
||||
listListenersResp, err := d.sdkClients.ALB.ListListenersWithContext(context.TODO(), listListenersReq, &dara.RuntimeOptions{})
|
||||
@@ -200,17 +201,19 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.ListListeners': %w", err)
|
||||
}
|
||||
|
||||
if listListenersResp.Body.Listeners != nil {
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
if listListenersResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
|
||||
if len(listListenersResp.Body.Listeners) == 0 || listListenersResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
@@ -286,8 +289,7 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
// 查询监听证书列表
|
||||
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
|
||||
listenerCertificates := make([]alialb.ListListenerCertificatesResponseBodyCertificates, 0)
|
||||
listListenerCertificatesLimit := int32(100)
|
||||
var listListenerCertificatesToken *string = nil
|
||||
listListenerCertificatesToken := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -297,7 +299,7 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
|
||||
listListenerCertificatesReq := &alialb.ListListenerCertificatesRequest{
|
||||
NextToken: listListenerCertificatesToken,
|
||||
MaxResults: tea.Int32(listListenerCertificatesLimit),
|
||||
MaxResults: tea.Int32(100),
|
||||
ListenerId: tea.String(cloudListenerId),
|
||||
CertificateType: tea.String("Server"),
|
||||
}
|
||||
@@ -307,17 +309,19 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.ListListenerCertificates': %w", err)
|
||||
}
|
||||
|
||||
if listListenerCertificatesResp.Body.Certificates != nil {
|
||||
for _, listenerCertificate := range listListenerCertificatesResp.Body.Certificates {
|
||||
listenerCertificates = append(listenerCertificates, *listenerCertificate)
|
||||
}
|
||||
if listListenerCertificatesResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listenerCertificate := range listListenerCertificatesResp.Body.Certificates {
|
||||
listenerCertificates = append(listenerCertificates, *listenerCertificate)
|
||||
}
|
||||
|
||||
if len(listListenerCertificatesResp.Body.Certificates) == 0 || listListenerCertificatesResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listListenerCertificatesToken = listListenerCertificatesResp.Body.NextToken
|
||||
}
|
||||
|
||||
listListenerCertificatesToken = listListenerCertificatesResp.Body.NextToken
|
||||
}
|
||||
|
||||
// 查询监听证书,并找出需要解除关联的证书
|
||||
|
||||
@@ -146,52 +146,10 @@ func (d *SSLDeployerProvider) deployToCloudNative(ctx context.Context, certPEM s
|
||||
return errors.New("config `domain` is required")
|
||||
}
|
||||
|
||||
// 查询域名列表,获取域名 ID
|
||||
// REF: https://help.aliyun.com/zh/api-gateway/cloud-native-api-gateway/developer-reference/api-apig-2024-03-27-listdomains
|
||||
var domainId string
|
||||
listDomainsPageNumber := int32(1)
|
||||
listDomainsPageSize := int32(10)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
listDomainsReq := &aliapig.ListDomainsRequest{
|
||||
ResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId),
|
||||
GatewayId: tea.String(d.config.GatewayId),
|
||||
NameLike: tea.String(d.config.Domain),
|
||||
PageNumber: tea.Int32(listDomainsPageNumber),
|
||||
PageSize: tea.Int32(listDomainsPageSize),
|
||||
}
|
||||
listDomainsResp, err := d.sdkClients.CloudNativeAPIGateway.ListDomainsWithContext(context.TODO(), listDomainsReq, make(map[string]*string), &dara.RuntimeOptions{})
|
||||
d.logger.Debug("sdk request 'apig.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'apig.ListDomains': %w", err)
|
||||
}
|
||||
|
||||
if listDomainsResp.Body.Data.Items != nil {
|
||||
for _, domainInfo := range listDomainsResp.Body.Data.Items {
|
||||
if strings.EqualFold(tea.StringValue(domainInfo.Name), d.config.Domain) {
|
||||
domainId = tea.StringValue(domainInfo.DomainId)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if domainId != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if listDomainsResp.Body.Data.Items == nil || len(listDomainsResp.Body.Data.Items) < int(listDomainsPageSize) {
|
||||
break
|
||||
} else {
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
}
|
||||
if domainId == "" {
|
||||
return errors.New("domain not found")
|
||||
// 获取域名 ID
|
||||
domainId, err := d.findCloudNativeDomainIdByDomain(ctx, d.config.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 查询域名
|
||||
@@ -232,6 +190,51 @@ func (d *SSLDeployerProvider) deployToCloudNative(ctx context.Context, certPEM s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) findCloudNativeDomainIdByDomain(ctx context.Context, domain string) (string, error) {
|
||||
// 查询域名列表
|
||||
// REF: https://help.aliyun.com/zh/api-gateway/cloud-native-api-gateway/developer-reference/api-apig-2024-03-27-listdomains
|
||||
listDomainsPageNumber := 1
|
||||
listDomainsPageSize := 10
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
listDomainsReq := &aliapig.ListDomainsRequest{
|
||||
ResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId),
|
||||
GatewayId: tea.String(d.config.GatewayId),
|
||||
NameLike: tea.String(d.config.Domain),
|
||||
PageNumber: tea.Int32(int32(listDomainsPageNumber)),
|
||||
PageSize: tea.Int32(int32(listDomainsPageSize)),
|
||||
}
|
||||
listDomainsResp, err := d.sdkClients.CloudNativeAPIGateway.ListDomainsWithContext(context.TODO(), listDomainsReq, make(map[string]*string), &dara.RuntimeOptions{})
|
||||
d.logger.Debug("sdk request 'apig.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to execute sdk request 'apig.ListDomains': %w", err)
|
||||
}
|
||||
|
||||
if listDomainsResp.Body == nil || listDomainsResp.Body.Data == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, domainItem := range listDomainsResp.Body.Data.Items {
|
||||
if strings.EqualFold(tea.StringValue(domainItem.Name), d.config.Domain) {
|
||||
return tea.StringValue(domainItem.DomainId), nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(listDomainsResp.Body.Data.Items) < listDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not find domain '%s'", domain)
|
||||
}
|
||||
|
||||
func createSDKClients(accessKeyId, accessKeySecret, region string) (*wSDKClients, error) {
|
||||
// 接入点一览 https://api.aliyun.com/product/APIG
|
||||
var cloudNativeAPIGEndpoint string
|
||||
|
||||
@@ -146,11 +146,10 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.DescribeDeploymentJob': %w", err)
|
||||
}
|
||||
|
||||
if describeDeploymentJobResp.Body.Status == nil || *describeDeploymentJobResp.Body.Status == "editing" {
|
||||
status := tea.StringValue(describeDeploymentJobResp.Body.Status)
|
||||
if status == "" || status == "editing" {
|
||||
return nil, errors.New("unexpected aliyun deployment job status")
|
||||
}
|
||||
|
||||
if *describeDeploymentJobResp.Body.Status == "success" || *describeDeploymentJobResp.Body.Status == "error" {
|
||||
} else if status == "success" || status == "error" {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
@@ -187,8 +187,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-describeuserdomains
|
||||
describeUserDomainsPageNumber := int32(1)
|
||||
describeUserDomainsPageSize := int32(500)
|
||||
describeUserDomainsPageNumber := 1
|
||||
describeUserDomainsPageSize := 500
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -198,8 +198,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
describeUserDomainsReq := &alicdn.DescribeUserDomainsRequest{
|
||||
ResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId),
|
||||
PageNumber: tea.Int32(describeUserDomainsPageNumber),
|
||||
PageSize: tea.Int32(describeUserDomainsPageSize),
|
||||
PageNumber: tea.Int32(int32(describeUserDomainsPageNumber)),
|
||||
PageSize: tea.Int32(int32(describeUserDomainsPageSize)),
|
||||
}
|
||||
describeUserDomainsResp, err := d.sdkClient.DescribeUserDomainsWithContext(ctx, describeUserDomainsReq, &dara.RuntimeOptions{})
|
||||
d.logger.Debug("sdk request 'cdn.DescribeUserDomains'", slog.Any("request", describeUserDomainsReq), slog.Any("response", describeUserDomainsResp))
|
||||
@@ -207,22 +207,24 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeUserDomains': %w", err)
|
||||
}
|
||||
|
||||
if describeUserDomainsResp.Body.Domains != nil {
|
||||
ignoredStatuses := []string{"offline", "checking", "check_failed", "stopping", "deleting"}
|
||||
for _, domainInfo := range describeUserDomainsResp.Body.Domains.PageData {
|
||||
if lo.Contains(ignoredStatuses, tea.StringValue(domainInfo.DomainStatus)) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, tea.StringValue(domainInfo.DomainName))
|
||||
}
|
||||
}
|
||||
|
||||
if len(describeUserDomainsResp.Body.Domains.PageData) < int(describeUserDomainsPageNumber) {
|
||||
if describeUserDomainsResp.Body == nil || describeUserDomainsResp.Body.Domains == nil {
|
||||
break
|
||||
} else {
|
||||
describeUserDomainsPageNumber++
|
||||
}
|
||||
|
||||
ignoredStatuses := []string{"offline", "checking", "check_failed", "stopping", "deleting"}
|
||||
for _, domainItem := range describeUserDomainsResp.Body.Domains.PageData {
|
||||
if lo.Contains(ignoredStatuses, tea.StringValue(domainItem.DomainStatus)) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, tea.StringValue(domainItem.DomainName))
|
||||
}
|
||||
|
||||
if len(describeUserDomainsResp.Body.Domains.PageData) < describeUserDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
describeUserDomainsPageNumber++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -132,8 +132,7 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询 HTTPS 监听列表
|
||||
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerlisteners
|
||||
listenerPorts := make([]int32, 0)
|
||||
describeLoadBalancerListenersLimit := int32(100)
|
||||
var describeLoadBalancerListenersToken *string = nil
|
||||
describeLoadBalancerListenersToken := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -143,9 +142,9 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
|
||||
describeLoadBalancerListenersReq := &alislb.DescribeLoadBalancerListenersRequest{
|
||||
RegionId: tea.String(d.config.Region),
|
||||
MaxResults: tea.Int32(describeLoadBalancerListenersLimit),
|
||||
NextToken: describeLoadBalancerListenersToken,
|
||||
LoadBalancerId: []*string{tea.String(d.config.LoadbalancerId)},
|
||||
MaxResults: tea.Int32(100),
|
||||
LoadBalancerId: tea.StringSlice([]string{d.config.LoadbalancerId}),
|
||||
ListenerProtocol: tea.String("https"),
|
||||
}
|
||||
describeLoadBalancerListenersResp, err := d.sdkClient.DescribeLoadBalancerListeners(describeLoadBalancerListenersReq)
|
||||
@@ -154,17 +153,19 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
return fmt.Errorf("failed to execute sdk request 'slb.DescribeLoadBalancerListeners': %w", err)
|
||||
}
|
||||
|
||||
if describeLoadBalancerListenersResp.Body.Listeners != nil {
|
||||
for _, listener := range describeLoadBalancerListenersResp.Body.Listeners {
|
||||
listenerPorts = append(listenerPorts, *listener.ListenerPort)
|
||||
}
|
||||
if describeLoadBalancerListenersResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listener := range describeLoadBalancerListenersResp.Body.Listeners {
|
||||
listenerPorts = append(listenerPorts, *listener.ListenerPort)
|
||||
}
|
||||
|
||||
if len(describeLoadBalancerListenersResp.Body.Listeners) == 0 || describeLoadBalancerListenersResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
describeLoadBalancerListenersToken = describeLoadBalancerListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
describeLoadBalancerListenersToken = describeLoadBalancerListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
|
||||
@@ -187,8 +187,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-describedcdnuserdomains
|
||||
describeUserDomainsPageNumber := int32(1)
|
||||
describeUserDomainsPageSize := int32(500)
|
||||
describeUserDomainsPageNumber := 1
|
||||
describeUserDomainsPageSize := 500
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -199,8 +199,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
describeDcdnUserDomainsReq := &alidcdn.DescribeDcdnUserDomainsRequest{
|
||||
ResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId),
|
||||
CheckDomainShow: tea.Bool(true),
|
||||
PageNumber: tea.Int32(describeUserDomainsPageNumber),
|
||||
PageSize: tea.Int32(describeUserDomainsPageSize),
|
||||
PageNumber: tea.Int32(int32(describeUserDomainsPageNumber)),
|
||||
PageSize: tea.Int32(int32(describeUserDomainsPageSize)),
|
||||
}
|
||||
describeDcdnUserDomainsResp, err := d.sdkClient.DescribeDcdnUserDomainsWithContext(ctx, describeDcdnUserDomainsReq, &dara.RuntimeOptions{})
|
||||
d.logger.Debug("sdk request 'dcdn.DescribeDcdnUserDomains'", slog.Any("request", describeDcdnUserDomainsReq), slog.Any("response", describeDcdnUserDomainsResp))
|
||||
@@ -208,20 +208,24 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'dcdn.DescribeDcdnUserDomains': %w", err)
|
||||
}
|
||||
|
||||
if describeDcdnUserDomainsResp.Body == nil || describeDcdnUserDomainsResp.Body.Domains == nil {
|
||||
break
|
||||
}
|
||||
|
||||
ignoredStatuses := []string{"offline", "checking", "check_failed", "stopping", "deleting"}
|
||||
for _, domainInfo := range describeDcdnUserDomainsResp.Body.Domains.PageData {
|
||||
if lo.Contains(ignoredStatuses, tea.StringValue(domainInfo.DomainStatus)) {
|
||||
for _, domainItem := range describeDcdnUserDomainsResp.Body.Domains.PageData {
|
||||
if lo.Contains(ignoredStatuses, tea.StringValue(domainItem.DomainStatus)) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, tea.StringValue(domainInfo.DomainName))
|
||||
domains = append(domains, tea.StringValue(domainItem.DomainName))
|
||||
}
|
||||
|
||||
if len(describeDcdnUserDomainsResp.Body.Domains.PageData) < int(describeUserDomainsPageNumber) {
|
||||
if len(describeDcdnUserDomainsResp.Body.Domains.PageData) < describeUserDomainsPageNumber {
|
||||
break
|
||||
} else {
|
||||
describeUserDomainsPageNumber++
|
||||
}
|
||||
|
||||
describeUserDomainsPageNumber++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -119,8 +119,8 @@ func (d *SSLDeployerProvider) deployToAccelerator(ctx context.Context, cloudCert
|
||||
// 查询 HTTPS 监听列表
|
||||
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-listlisteners
|
||||
listenerIds := make([]string, 0)
|
||||
listListenersPageNumber := int32(1)
|
||||
listListenersPageSize := int32(50)
|
||||
listListenersPageNumber := 1
|
||||
listListenersPageSize := 50
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -131,8 +131,8 @@ func (d *SSLDeployerProvider) deployToAccelerator(ctx context.Context, cloudCert
|
||||
listListenersReq := &aliga.ListListenersRequest{
|
||||
RegionId: tea.String("cn-hangzhou"),
|
||||
AcceleratorId: tea.String(d.config.AcceleratorId),
|
||||
PageNumber: tea.Int32(listListenersPageNumber),
|
||||
PageSize: tea.Int32(listListenersPageSize),
|
||||
PageNumber: tea.Int32(int32(listListenersPageNumber)),
|
||||
PageSize: tea.Int32(int32(listListenersPageSize)),
|
||||
}
|
||||
listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
|
||||
d.logger.Debug("sdk request 'ga.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp))
|
||||
@@ -140,19 +140,21 @@ func (d *SSLDeployerProvider) deployToAccelerator(ctx context.Context, cloudCert
|
||||
return fmt.Errorf("failed to execute sdk request 'ga.ListListeners': %w", err)
|
||||
}
|
||||
|
||||
if listListenersResp.Body.Listeners != nil {
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
if strings.EqualFold(tea.StringValue(listener.Protocol), "https") {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
if listListenersResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
if strings.EqualFold(tea.StringValue(listener.Protocol), "https") {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
}
|
||||
|
||||
if len(listListenersResp.Body.Listeners) < int(listListenersPageSize) {
|
||||
if len(listListenersResp.Body.Listeners) < listListenersPageSize {
|
||||
break
|
||||
} else {
|
||||
listListenersPageNumber++
|
||||
}
|
||||
|
||||
listListenersPageNumber++
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
@@ -200,9 +202,9 @@ func (d *SSLDeployerProvider) deployToListener(ctx context.Context, cloudCertId
|
||||
func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, cloudAcceleratorId string, cloudListenerId string, cloudCertId string) error {
|
||||
// 查询监听绑定的证书列表
|
||||
// REF: https://help.aliyun.com/zh/ga/developer-reference/api-ga-2019-11-20-listlistenercertificates
|
||||
var listenerDefaultCertificate *aliga.ListListenerCertificatesResponseBodyCertificates
|
||||
var listenerAdditionalCertificates []*aliga.ListListenerCertificatesResponseBodyCertificates = make([]*aliga.ListListenerCertificatesResponseBodyCertificates, 0)
|
||||
var listListenerCertificatesNextToken *string
|
||||
listenerDefaultCertificate := (*aliga.ListListenerCertificatesResponseBodyCertificates)(nil)
|
||||
listenerAdditionalCertificates := make([]*aliga.ListListenerCertificatesResponseBodyCertificates, 0)
|
||||
listListenerCertificatesNextToken := (*string)(nil)
|
||||
for {
|
||||
listListenerCertificatesReq := &aliga.ListListenerCertificatesRequest{
|
||||
RegionId: tea.String("cn-hangzhou"),
|
||||
@@ -217,21 +219,23 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
return fmt.Errorf("failed to execute sdk request 'ga.ListListenerCertificates': %w", err)
|
||||
}
|
||||
|
||||
if listListenerCertificatesResp.Body.Certificates != nil {
|
||||
for _, certificate := range listListenerCertificatesResp.Body.Certificates {
|
||||
if tea.BoolValue(certificate.IsDefault) {
|
||||
listenerDefaultCertificate = certificate
|
||||
} else {
|
||||
listenerAdditionalCertificates = append(listenerAdditionalCertificates, certificate)
|
||||
}
|
||||
if listListenerCertificatesResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, certItem := range listListenerCertificatesResp.Body.Certificates {
|
||||
if tea.BoolValue(certItem.IsDefault) {
|
||||
listenerDefaultCertificate = certItem
|
||||
} else {
|
||||
listenerAdditionalCertificates = append(listenerAdditionalCertificates, certItem)
|
||||
}
|
||||
}
|
||||
|
||||
if listListenerCertificatesResp.Body.NextToken == nil {
|
||||
if len(listListenerCertificatesResp.Body.Certificates) == 0 || listListenerCertificatesResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listListenerCertificatesNextToken = listListenerCertificatesResp.Body.NextToken
|
||||
}
|
||||
|
||||
listListenerCertificatesNextToken = listListenerCertificatesResp.Body.NextToken
|
||||
}
|
||||
|
||||
if d.config.Domain == "" {
|
||||
|
||||
@@ -133,8 +133,7 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询 TCPSSL 监听列表
|
||||
// REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-listlisteners
|
||||
listenerIds := make([]string, 0)
|
||||
listListenersLimit := int32(100)
|
||||
var listListenersToken *string = nil
|
||||
listListenersToken := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -143,9 +142,9 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
}
|
||||
|
||||
listListenersReq := &alinlb.ListListenersRequest{
|
||||
MaxResults: tea.Int32(listListenersLimit),
|
||||
NextToken: listListenersToken,
|
||||
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
|
||||
MaxResults: tea.Int32(100),
|
||||
LoadBalancerIds: tea.StringSlice([]string{d.config.LoadbalancerId}),
|
||||
ListenerProtocol: tea.String("TCPSSL"),
|
||||
}
|
||||
listListenersResp, err := d.sdkClient.ListListenersWithContext(context.TODO(), listListenersReq, &dara.RuntimeOptions{})
|
||||
@@ -154,17 +153,19 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
return fmt.Errorf("failed to execute sdk request 'nlb.ListListeners': %w", err)
|
||||
}
|
||||
|
||||
if listListenersResp.Body.Listeners != nil {
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
if listListenersResp.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, listener := range listListenersResp.Body.Listeners {
|
||||
listenerIds = append(listenerIds, tea.StringValue(listener.ListenerId))
|
||||
}
|
||||
|
||||
if len(listListenersResp.Body.Listeners) == 0 || listListenersResp.Body.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
listListenersToken = listListenersResp.Body.NextToken
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
|
||||
@@ -255,7 +255,7 @@ func (d *SSLDeployerProvider) updateHttpsListenerCertificate(ctx context.Context
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'appblb.DescribeAppHTTPSListeners': %w", err)
|
||||
} else if len(describeAppHTTPSListenersResp.ListenerList) == 0 {
|
||||
return fmt.Errorf("listener %s:%d not found", cloudLoadbalancerId, cloudHttpsListenerPort)
|
||||
return fmt.Errorf("cloud not find listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
|
||||
}
|
||||
|
||||
if d.config.Domain == "" {
|
||||
|
||||
@@ -255,7 +255,7 @@ func (d *SSLDeployerProvider) updateHttpsListenerCertificate(ctx context.Context
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'blb.DescribeHTTPSListeners': %w", err)
|
||||
} else if len(describeHTTPSListenersResp.ListenerList) == 0 {
|
||||
return fmt.Errorf("listener %s:%d not found", cloudLoadbalancerId, cloudHttpsListenerPort)
|
||||
return fmt.Errorf("could not find listener '%s:%d'", cloudLoadbalancerId, cloudHttpsListenerPort)
|
||||
}
|
||||
|
||||
if d.config.Domain == "" {
|
||||
|
||||
@@ -171,9 +171,9 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
if listDomainsNextMarker == "" {
|
||||
break
|
||||
} else {
|
||||
listDomainsMarker = listDomainsNextMarker
|
||||
}
|
||||
|
||||
listDomainsMarker = listDomainsNextMarker
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
type SSLDeployerProviderConfig struct {
|
||||
// 白山云 API Token。
|
||||
ApiToken string `json:"apiToken"`
|
||||
// 域名匹配模式。暂时只支持精确匹配。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 加速域名(支持泛域名)。
|
||||
Domain string `json:"domain"`
|
||||
// 证书 ID。
|
||||
@@ -103,7 +106,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'baishan.GetDomainConfig': %w", err)
|
||||
} else if len(getDomainConfigResp.Data) == 0 {
|
||||
return nil, fmt.Errorf("domain %s not found", d.config.Domain)
|
||||
return nil, fmt.Errorf("could not find domain '%s'", d.config.Domain)
|
||||
}
|
||||
|
||||
// 设置域名配置
|
||||
|
||||
@@ -49,8 +49,9 @@ func TestDeploy(t *testing.T) {
|
||||
}, "\n"))
|
||||
|
||||
deployer, err := provider.NewSSLDeployerProvider(&provider.SSLDeployerProviderConfig{
|
||||
ApiToken: fApiToken,
|
||||
Domain: fDomain,
|
||||
ApiToken: fApiToken,
|
||||
DomainMatchPattern: provider.DOMAIN_MATCH_PATTERN_EXACT,
|
||||
Domain: fDomain,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("err: %+v", err)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package baishancdn
|
||||
|
||||
const (
|
||||
// 匹配模式:精确匹配。
|
||||
DOMAIN_MATCH_PATTERN_EXACT = "exact"
|
||||
)
|
||||
@@ -74,48 +74,10 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'bt.PanelGetConfig': %w", err)
|
||||
}
|
||||
|
||||
// 查询网站列表,获取网站 ID
|
||||
var siteId int32
|
||||
datalistGetDataListPage := int32(1)
|
||||
datalistGetDataListLimit := int32(10)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
datalistGetDataListReq := &btsdk.DatalistGetDataListRequest{
|
||||
Table: lo.ToPtr("sites"),
|
||||
SearchString: lo.ToPtr(d.config.SiteName),
|
||||
Page: lo.ToPtr(datalistGetDataListPage),
|
||||
Limit: lo.ToPtr(datalistGetDataListLimit),
|
||||
}
|
||||
datalistGetDataListResp, err := d.sdkClient.DatalistGetDataList(datalistGetDataListReq)
|
||||
d.logger.Debug("sdk request 'bt.DatalistGetDataList'", slog.Any("request", datalistGetDataListReq), slog.Any("response", datalistGetDataListResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'bt.DatalistGetDataList': %w", err)
|
||||
}
|
||||
|
||||
for _, siteInfo := range datalistGetDataListResp.Data {
|
||||
if strings.EqualFold(siteInfo.Name, d.config.SiteName) {
|
||||
siteId = siteInfo.Id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if siteId != 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(datalistGetDataListResp.Data) < int(datalistGetDataListLimit) {
|
||||
break
|
||||
} else {
|
||||
datalistGetDataListPage++
|
||||
}
|
||||
}
|
||||
if siteId == 0 {
|
||||
return nil, errors.New("website not found")
|
||||
// 获取网站 ID
|
||||
siteId, err := d.findSiteIdByName(ctx, d.config.SiteName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if panelGetConfigResp.Site != nil && strings.EqualFold(panelGetConfigResp.Site.WebServer, "iis") {
|
||||
@@ -174,6 +136,45 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
return &core.SSLDeployResult{}, nil
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) findSiteIdByName(ctx context.Context, siteName string) (int32, error) {
|
||||
// 查询网站列表
|
||||
datalistGetDataListPage := 1
|
||||
datalistGetDataListLimit := 10
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
datalistGetDataListReq := &btsdk.DatalistGetDataListRequest{
|
||||
Table: lo.ToPtr("sites"),
|
||||
SearchString: lo.ToPtr(d.config.SiteName),
|
||||
Page: lo.ToPtr(int32(datalistGetDataListPage)),
|
||||
Limit: lo.ToPtr(int32(datalistGetDataListLimit)),
|
||||
}
|
||||
datalistGetDataListResp, err := d.sdkClient.DatalistGetDataList(datalistGetDataListReq)
|
||||
d.logger.Debug("sdk request 'bt.DatalistGetDataList'", slog.Any("request", datalistGetDataListReq), slog.Any("response", datalistGetDataListResp))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to execute sdk request 'bt.DatalistGetDataList': %w", err)
|
||||
}
|
||||
|
||||
for _, siteItem := range datalistGetDataListResp.Data {
|
||||
if strings.EqualFold(siteItem.Name, d.config.SiteName) {
|
||||
return siteItem.Id, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(datalistGetDataListResp.Data) < datalistGetDataListLimit {
|
||||
break
|
||||
}
|
||||
|
||||
datalistGetDataListPage++
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("could not find site '%s'", siteName)
|
||||
}
|
||||
|
||||
func createSDKClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
|
||||
client, err := btsdk.NewClient(serverUrl, apiKey)
|
||||
if err != nil {
|
||||
|
||||
@@ -68,46 +68,10 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
d.config.SitePort = 443
|
||||
}
|
||||
|
||||
// 查询网站列表,获取网站 ID
|
||||
// REF: https://support.huaweicloud.com/api-waf/ListHost.html
|
||||
siteId := ""
|
||||
getSitListPage := int32(1)
|
||||
getSitListPageSize := int32(100)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
getSiteListReq := &btwafsdk.GetSiteListRequest{
|
||||
SiteName: lo.ToPtr(d.config.SiteName),
|
||||
Page: lo.ToPtr(getSitListPage),
|
||||
PageSize: lo.ToPtr(getSitListPageSize),
|
||||
}
|
||||
getSiteListResp, err := d.sdkClient.GetSiteList(getSiteListReq)
|
||||
d.logger.Debug("sdk request 'bt.GetSiteList'", slog.Any("request", getSiteListReq), slog.Any("response", getSiteListResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'bt.GetSiteList': %w", err)
|
||||
}
|
||||
|
||||
if getSiteListResp.Result != nil && getSiteListResp.Result.List != nil {
|
||||
for _, siteItem := range getSiteListResp.Result.List {
|
||||
if siteItem.SiteName == d.config.SiteName {
|
||||
siteId = siteItem.SiteId
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if getSiteListResp.Result == nil || len(getSiteListResp.Result.List) < int(getSitListPageSize) {
|
||||
break
|
||||
} else {
|
||||
getSitListPage++
|
||||
}
|
||||
}
|
||||
if siteId == "" {
|
||||
return nil, errors.New("site not found")
|
||||
// 获取网站 ID
|
||||
siteId, err := d.findSiteIdByName(ctx, d.config.SiteName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 修改站点配置
|
||||
@@ -132,6 +96,48 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
return &core.SSLDeployResult{}, nil
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) findSiteIdByName(ctx context.Context, siteName string) (string, error) {
|
||||
// 查询网站列表
|
||||
getSiteListPage := 1
|
||||
getSiteListPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
getSiteListReq := &btwafsdk.GetSiteListRequest{
|
||||
SiteName: lo.ToPtr(d.config.SiteName),
|
||||
Page: lo.ToPtr(int32(getSiteListPage)),
|
||||
PageSize: lo.ToPtr(int32(getSiteListPageSize)),
|
||||
}
|
||||
getSiteListResp, err := d.sdkClient.GetSiteList(getSiteListReq)
|
||||
d.logger.Debug("sdk request 'bt.GetSiteList'", slog.Any("request", getSiteListReq), slog.Any("response", getSiteListResp))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to execute sdk request 'bt.GetSiteList': %w", err)
|
||||
}
|
||||
|
||||
if getSiteListResp.Result == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, siteItem := range getSiteListResp.Result.List {
|
||||
if siteItem.SiteName == d.config.SiteName {
|
||||
return siteItem.SiteId, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(getSiteListResp.Result.List) < getSiteListPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
getSiteListPage++
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not find site '%s'", siteName)
|
||||
}
|
||||
|
||||
func createSDKClient(serverUrl, apiKey string, skipTlsVerify bool) (*btwafsdk.Client, error) {
|
||||
client, err := btwafsdk.NewClient(serverUrl, apiKey)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ type SSLDeployerProviderConfig struct {
|
||||
ApiKey string `json:"apiKey"`
|
||||
// Bunny Pull Zone ID。
|
||||
PullZoneId string `json:"pullZoneId"`
|
||||
// Bunny CDN Hostname(支持泛域名)。
|
||||
// Bunny CDN Hostname。
|
||||
Hostname string `json:"hostname"`
|
||||
}
|
||||
|
||||
|
||||
@@ -155,8 +155,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
|
||||
// 查询加速域名列表,获取匹配的域名
|
||||
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/ListCdnDomains_en-us
|
||||
listCdnDomainsPageNum := int64(1)
|
||||
listCdnDomainsPageSize := int64(100)
|
||||
listCdnDomainsPageNum := 1
|
||||
listCdnDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -167,8 +167,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
listCdnDomainsReq := &bpcdn.ListCdnDomainsRequest{
|
||||
Domain: bp.String(strings.TrimPrefix(wildcardDomain, "*.")),
|
||||
Status: bp.String("online"),
|
||||
PageNum: bp.Int64(listCdnDomainsPageNum),
|
||||
PageSize: bp.Int64(listCdnDomainsPageSize),
|
||||
PageNum: bp.Int64(int64(listCdnDomainsPageNum)),
|
||||
PageSize: bp.Int64(int64(listCdnDomainsPageSize)),
|
||||
}
|
||||
listCdnDomainsResp, err := d.sdkClient.ListCdnDomains(listCdnDomainsReq)
|
||||
d.logger.Debug("sdk request 'cdn.ListCdnDomains'", slog.Any("request", listCdnDomainsReq), slog.Any("response", listCdnDomainsResp))
|
||||
@@ -176,17 +176,17 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.ListCdnDomains': %w", err)
|
||||
}
|
||||
|
||||
for _, domainInfo := range listCdnDomainsResp.Result.Data {
|
||||
if xcerthostname.IsMatch(wildcardDomain, domainInfo.Domain) {
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
for _, domainItem := range listCdnDomainsResp.Result.Data {
|
||||
if xcerthostname.IsMatch(wildcardDomain, domainItem.Domain) {
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if len(listCdnDomainsResp.Result.Data) < int(listCdnDomainsPageSize) {
|
||||
if len(listCdnDomainsResp.Result.Data) < listCdnDomainsPageSize {
|
||||
break
|
||||
} else {
|
||||
listCdnDomainsPageSize++
|
||||
}
|
||||
|
||||
listCdnDomainsPageSize++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -171,8 +171,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13816&data=174&isNormal=1&vid=167
|
||||
queryDomainsPage := int32(1)
|
||||
queryDomainsPageSize := int32(100)
|
||||
queryDomainsPage := 1
|
||||
queryDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -181,8 +181,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
}
|
||||
|
||||
queryDomainsReq := &ctyunao.QueryDomainsRequest{
|
||||
Page: lo.ToPtr(queryDomainsPage),
|
||||
PageSize: lo.ToPtr(queryDomainsPageSize),
|
||||
Page: lo.ToPtr(int32(queryDomainsPage)),
|
||||
PageSize: lo.ToPtr(int32(queryDomainsPageSize)),
|
||||
ProductCode: lo.ToPtr("020"),
|
||||
}
|
||||
queryDomainsResp, err := d.sdkClient.QueryDomains(queryDomainsReq)
|
||||
@@ -191,22 +191,24 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryDomains': %w", err)
|
||||
}
|
||||
|
||||
if queryDomainsResp.ReturnObj != nil {
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainInfo := range queryDomainsResp.ReturnObj.Results {
|
||||
if lo.Contains(ignoredStatuses, domainInfo.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if queryDomainsResp.ReturnObj == nil || len(queryDomainsResp.ReturnObj.Results) < int(queryDomainsPageSize) {
|
||||
if queryDomainsResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryDomainsPage++
|
||||
}
|
||||
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainItem := range queryDomainsResp.ReturnObj.Results {
|
||||
if lo.Contains(ignoredStatuses, domainItem.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
|
||||
if len(queryDomainsResp.ReturnObj.Results) < queryDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
queryDomainsPage++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -170,8 +170,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=108&api=11307&data=161&isNormal=1&vid=154
|
||||
queryDomainListPage := int32(1)
|
||||
queryDomainListPageSize := int32(100)
|
||||
queryDomainListPage := 1
|
||||
queryDomainListPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -180,8 +180,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
}
|
||||
|
||||
queryDomainListReq := &ctyuncdn.QueryDomainListRequest{
|
||||
Page: lo.ToPtr(queryDomainListPage),
|
||||
PageSize: lo.ToPtr(queryDomainListPageSize),
|
||||
Page: lo.ToPtr(int32(queryDomainListPage)),
|
||||
PageSize: lo.ToPtr(int32(queryDomainListPageSize)),
|
||||
ProductCode: lo.ToPtr("020"),
|
||||
}
|
||||
queryDomainListResp, err := d.sdkClient.QueryDomainList(queryDomainListReq)
|
||||
@@ -190,26 +190,28 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryDomainList': %w", err)
|
||||
}
|
||||
|
||||
if queryDomainListResp.ReturnObj != nil {
|
||||
filteredProductCodes := []string{"001", "003", "004", "008"}
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainInfo := range queryDomainListResp.ReturnObj.Results {
|
||||
if !lo.Contains(filteredProductCodes, domainInfo.ProductCode) {
|
||||
continue
|
||||
}
|
||||
if lo.Contains(ignoredStatuses, domainInfo.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if queryDomainListResp.ReturnObj == nil || len(queryDomainListResp.ReturnObj.Results) < int(queryDomainListPageSize) {
|
||||
if queryDomainListResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryDomainListPage++
|
||||
}
|
||||
|
||||
filteredProductCodes := []string{"001", "003", "004", "008"}
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainItem := range queryDomainListResp.ReturnObj.Results {
|
||||
if !lo.Contains(filteredProductCodes, domainItem.ProductCode) {
|
||||
continue
|
||||
}
|
||||
if lo.Contains(ignoredStatuses, domainItem.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
|
||||
if len(queryDomainListResp.ReturnObj.Results) < queryDomainListPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
queryDomainListPage++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -111,13 +111,7 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询监听列表
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=24&api=5654&data=88&isNormal=1&vid=82
|
||||
listenerIds := make([]string, 0)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
{
|
||||
listListenersReq := &ctyunelb.ListListenersRequest{
|
||||
RegionID: lo.ToPtr(d.config.RegionId),
|
||||
LoadBalancerID: lo.ToPtr(d.config.LoadbalancerId),
|
||||
@@ -133,8 +127,6 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
listenerIds = append(listenerIds, listener.ID)
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
|
||||
@@ -170,8 +170,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10852&data=173&isNormal=1&vid=166
|
||||
queryDomainsPage := int32(1)
|
||||
queryDomainsPageSize := int32(100)
|
||||
queryDomainsPage := 1
|
||||
queryDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -180,8 +180,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
}
|
||||
|
||||
queryDomainListReq := &ctyunicdn.QueryDomainListRequest{
|
||||
Page: lo.ToPtr(queryDomainsPage),
|
||||
PageSize: lo.ToPtr(queryDomainsPageSize),
|
||||
Page: lo.ToPtr(int32(queryDomainsPage)),
|
||||
PageSize: lo.ToPtr(int32(queryDomainsPageSize)),
|
||||
ProductCode: lo.ToPtr("006"),
|
||||
}
|
||||
queryDomainListResp, err := d.sdkClient.QueryDomainList(queryDomainListReq)
|
||||
@@ -190,22 +190,24 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryDomainList': %w", err)
|
||||
}
|
||||
|
||||
if queryDomainListResp.ReturnObj != nil {
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainInfo := range queryDomainListResp.ReturnObj.Results {
|
||||
if lo.Contains(ignoredStatuses, domainInfo.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if queryDomainListResp.ReturnObj == nil || len(queryDomainListResp.ReturnObj.Results) < int(queryDomainsPageSize) {
|
||||
if queryDomainListResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryDomainsPage++
|
||||
}
|
||||
|
||||
ignoredStatuses := []int32{1, 5, 6, 7, 8, 9, 11, 12}
|
||||
for _, domainItem := range queryDomainListResp.ReturnObj.Results {
|
||||
if lo.Contains(ignoredStatuses, domainItem.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
|
||||
if len(queryDomainListResp.ReturnObj.Results) < queryDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
queryDomainsPage++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -185,8 +185,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://support.huaweicloud.com/api-cdn/ListDomains.html
|
||||
listDomainsPageNumber := int32(1)
|
||||
listDomainsPageSize := int32(100)
|
||||
listDomainsPageNumber := 1
|
||||
listDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -196,8 +196,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
listDomainsReq := &hccdnmodel.ListDomainsRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(d.config.EnterpriseProjectId),
|
||||
PageNumber: lo.ToPtr(listDomainsPageNumber),
|
||||
PageSize: lo.ToPtr(listDomainsPageSize),
|
||||
PageNumber: lo.ToPtr(int32(listDomainsPageNumber)),
|
||||
PageSize: lo.ToPtr(int32(listDomainsPageSize)),
|
||||
}
|
||||
listDomainsResp, err := d.sdkClient.ListDomains(listDomainsReq)
|
||||
d.logger.Debug("sdk request 'cdn.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
|
||||
@@ -205,22 +205,24 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.ListDomains': %w", err)
|
||||
}
|
||||
|
||||
if listDomainsResp.Domains != nil {
|
||||
ignoredStatuses := []string{"offline", "checking", "check_failed", "deleting"}
|
||||
for _, domainInfo := range *listDomainsResp.Domains {
|
||||
if lo.Contains(ignoredStatuses, lo.FromPtr(domainInfo.DomainStatus)) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, lo.FromPtr(domainInfo.DomainName))
|
||||
}
|
||||
}
|
||||
|
||||
if listDomainsResp.Domains == nil || len(*listDomainsResp.Domains) < int(listDomainsPageSize) {
|
||||
if listDomainsResp.Domains == nil {
|
||||
break
|
||||
} else {
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
|
||||
ignoredStatuses := []string{"offline", "checking", "check_failed", "deleting"}
|
||||
for _, domainItem := range *listDomainsResp.Domains {
|
||||
if lo.Contains(ignoredStatuses, lo.FromPtr(domainItem.DomainStatus)) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, lo.FromPtr(domainItem.DomainName))
|
||||
}
|
||||
|
||||
if len(*listDomainsResp.Domains) < listDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -160,8 +160,7 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, certPEM
|
||||
// 查询监听器列表
|
||||
// REF: https://support.huaweicloud.com/api-elb/ListListeners.html
|
||||
listenerIds := make([]string, 0)
|
||||
listListenersLimit := int32(2000)
|
||||
var listListenersMarker *string = nil
|
||||
listListenersMarker := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -170,8 +169,8 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, certPEM
|
||||
}
|
||||
|
||||
listListenersReq := &hcelbmodel.ListListenersRequest{
|
||||
Limit: lo.ToPtr(listListenersLimit),
|
||||
Marker: listListenersMarker,
|
||||
Limit: lo.ToPtr(int32(2000)),
|
||||
Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"},
|
||||
LoadbalancerId: &[]string{showLoadBalancerResp.Loadbalancer.Id},
|
||||
}
|
||||
@@ -184,17 +183,19 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, certPEM
|
||||
return fmt.Errorf("failed to execute sdk request 'elb.ListListeners': %w", err)
|
||||
}
|
||||
|
||||
if listListenersResp.Listeners != nil {
|
||||
for _, listener := range *listListenersResp.Listeners {
|
||||
listenerIds = append(listenerIds, listener.Id)
|
||||
}
|
||||
if listListenersResp.Listeners == nil {
|
||||
break
|
||||
}
|
||||
|
||||
if listListenersResp.Listeners == nil || len(*listListenersResp.Listeners) < int(listListenersLimit) {
|
||||
break
|
||||
} else {
|
||||
listListenersMarker = listListenersResp.PageInfo.NextMarker
|
||||
for _, listener := range *listListenersResp.Listeners {
|
||||
listenerIds = append(listenerIds, listener.Id)
|
||||
}
|
||||
|
||||
if len(*listListenersResp.Listeners) == 0 || listListenersResp.PageInfo.NextMarker == nil {
|
||||
break
|
||||
}
|
||||
|
||||
listListenersMarker = listListenersResp.PageInfo.NextMarker
|
||||
}
|
||||
|
||||
// 上传证书
|
||||
|
||||
@@ -174,8 +174,8 @@ func (d *SSLDeployerProvider) deployToCloudServer(ctx context.Context, certPEM s
|
||||
// 查询云模式防护域名列表,获取防护域名 ID
|
||||
// REF: https://support.huaweicloud.com/api-waf/ListHost.html
|
||||
hostId := ""
|
||||
listHostPage := int32(1)
|
||||
listHostPageSize := int32(100)
|
||||
listHostPage := 1
|
||||
listHostPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -186,8 +186,8 @@ func (d *SSLDeployerProvider) deployToCloudServer(ctx context.Context, certPEM s
|
||||
listHostReq := &hcwafmodel.ListHostRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(d.config.EnterpriseProjectId),
|
||||
Hostname: lo.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
|
||||
Page: lo.ToPtr(listHostPage),
|
||||
Pagesize: lo.ToPtr(listHostPageSize),
|
||||
Page: lo.ToPtr(int32(listHostPage)),
|
||||
Pagesize: lo.ToPtr(int32(listHostPageSize)),
|
||||
}
|
||||
listHostResp, err := d.sdkClient.ListHost(listHostReq)
|
||||
d.logger.Debug("sdk request 'waf.ListHost'", slog.Any("request", listHostReq), slog.Any("response", listHostResp))
|
||||
@@ -195,23 +195,25 @@ func (d *SSLDeployerProvider) deployToCloudServer(ctx context.Context, certPEM s
|
||||
return fmt.Errorf("failed to execute sdk request 'waf.ListHost': %w", err)
|
||||
}
|
||||
|
||||
if listHostResp.Items != nil {
|
||||
for _, hostItem := range *listHostResp.Items {
|
||||
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
|
||||
hostId = *hostItem.Id
|
||||
break
|
||||
}
|
||||
if listHostResp.Items == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, hostItem := range *listHostResp.Items {
|
||||
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
|
||||
hostId = *hostItem.Id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if listHostResp.Items == nil || len(*listHostResp.Items) < int(listHostPageSize) {
|
||||
if len(*listHostResp.Items) < listHostPageSize {
|
||||
break
|
||||
} else {
|
||||
listHostPage++
|
||||
}
|
||||
|
||||
listHostPage++
|
||||
}
|
||||
if hostId == "" {
|
||||
return errors.New("host not found")
|
||||
return fmt.Errorf("could not find cloudserver host '%s'", d.config.Domain)
|
||||
}
|
||||
|
||||
// 更新云模式防护域名的配置
|
||||
@@ -249,8 +251,8 @@ func (d *SSLDeployerProvider) deployToPremiumHost(ctx context.Context, certPEM s
|
||||
// 查询独享模式域名列表,获取防护域名 ID
|
||||
// REF: https://support.huaweicloud.com/api-waf/ListPremiumHost.html
|
||||
hostId := ""
|
||||
listPremiumHostPage := int32(1)
|
||||
listPremiumHostPageSize := int32(100)
|
||||
listPremiumHostPage := 1
|
||||
listPremiumHostPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -270,23 +272,25 @@ func (d *SSLDeployerProvider) deployToPremiumHost(ctx context.Context, certPEM s
|
||||
return fmt.Errorf("failed to execute sdk request 'waf.ListPremiumHost': %w", err)
|
||||
}
|
||||
|
||||
if listPremiumHostResp.Items != nil {
|
||||
for _, hostItem := range *listPremiumHostResp.Items {
|
||||
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
|
||||
hostId = *hostItem.Id
|
||||
break
|
||||
}
|
||||
if listPremiumHostResp.Items == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, hostItem := range *listPremiumHostResp.Items {
|
||||
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
|
||||
hostId = *hostItem.Id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if listPremiumHostResp.Items == nil || len(*listPremiumHostResp.Items) < int(listPremiumHostPageSize) {
|
||||
if len(*listPremiumHostResp.Items) < listPremiumHostPageSize {
|
||||
break
|
||||
} else {
|
||||
listPremiumHostPage++
|
||||
}
|
||||
|
||||
listPremiumHostPage++
|
||||
}
|
||||
if hostId == "" {
|
||||
return errors.New("host not found")
|
||||
return fmt.Errorf("could not find premium host '%s'", d.config.Domain)
|
||||
}
|
||||
|
||||
// 修改独享模式域名配置
|
||||
|
||||
@@ -156,11 +156,11 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
}
|
||||
}
|
||||
|
||||
if len(describeListenersResp.Result.Listeners) < int(describeListenersPageSize) {
|
||||
if len(describeListenersResp.Result.Listeners) < describeListenersPageSize {
|
||||
break
|
||||
} else {
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
// 遍历更新监听器证书
|
||||
@@ -236,7 +236,7 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
return extCertSpec.Domain == d.config.Domain
|
||||
})
|
||||
if len(extCertSpecs) == 0 {
|
||||
return errors.New("extension certificate spec not found")
|
||||
return errors.New("could not find any extension certificates")
|
||||
}
|
||||
|
||||
// 批量修改扩展证书
|
||||
|
||||
@@ -193,19 +193,19 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
}
|
||||
|
||||
ignoredStatuses := []string{"offline"}
|
||||
for _, domainInfo := range getDomainListResp.Result.Domains {
|
||||
if lo.Contains(ignoredStatuses, domainInfo.Status) {
|
||||
for _, domainItem := range getDomainListResp.Result.Domains {
|
||||
if lo.Contains(ignoredStatuses, domainItem.Status) {
|
||||
continue
|
||||
}
|
||||
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
|
||||
if len(getDomainListResp.Result.Domains) < getDomainListPageSize {
|
||||
break
|
||||
} else {
|
||||
getDomainListPageNumber++
|
||||
}
|
||||
|
||||
getDomainListPageNumber++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -58,42 +58,10 @@ func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) {
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) {
|
||||
// 查询域名列表
|
||||
// REF: https://docs.jdcloud.com/cn/video-on-demand/api/listdomains
|
||||
var domainId int
|
||||
listDomainsPageNumber := 1
|
||||
listDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
listDomainsReq := jdvod.NewListDomainsRequestWithoutParam()
|
||||
listDomainsReq.SetPageNumber(listDomainsPageNumber)
|
||||
listDomainsReq.SetPageSize(listDomainsPageSize)
|
||||
listDomainsResp, err := d.sdkClient.ListDomains(listDomainsReq)
|
||||
d.logger.Debug("sdk request 'vod.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'vod.ListDomains': %w", err)
|
||||
}
|
||||
|
||||
for _, domainInfo := range listDomainsResp.Result.Content {
|
||||
if domainInfo.Name == d.config.Domain {
|
||||
domainId, _ = strconv.Atoi(domainInfo.Id)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(listDomainsResp.Result.Content) < listDomainsPageSize {
|
||||
break
|
||||
} else {
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
}
|
||||
if domainId == 0 {
|
||||
return nil, errors.New("domain not found")
|
||||
// 获取域名 ID
|
||||
domainId, err := d.findDomainIdByDomain(ctx, d.config.Domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 查询域名 SSL 配置
|
||||
@@ -125,6 +93,44 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
return &core.SSLDeployResult{}, nil
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) findDomainIdByDomain(ctx context.Context, domain string) (int, error) {
|
||||
// 查询域名列表
|
||||
// REF: https://docs.jdcloud.com/cn/video-on-demand/api/listdomains
|
||||
listDomainsPageNumber := 1
|
||||
listDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
listDomainsReq := jdvod.NewListDomainsRequestWithoutParam()
|
||||
listDomainsReq.SetPageNumber(listDomainsPageNumber)
|
||||
listDomainsReq.SetPageSize(listDomainsPageSize)
|
||||
listDomainsResp, err := d.sdkClient.ListDomains(listDomainsReq)
|
||||
d.logger.Debug("sdk request 'vod.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to execute sdk request 'vod.ListDomains': %w", err)
|
||||
}
|
||||
|
||||
for _, domainItem := range listDomainsResp.Result.Content {
|
||||
if domainItem.Name == d.config.Domain {
|
||||
domainId, _ := strconv.Atoi(domainItem.Id)
|
||||
return domainId, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(listDomainsResp.Result.Content) < listDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
listDomainsPageNumber++
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("could not find domain '%s'", domain)
|
||||
}
|
||||
|
||||
func createSDKClient(accessKeyId, accessKeySecret string) (*internal.VodClient, error) {
|
||||
clientCredentials := jdcore.NewCredentials(accessKeyId, accessKeySecret)
|
||||
client := internal.NewVodClient(clientCredentials)
|
||||
|
||||
@@ -20,7 +20,7 @@ type SSLDeployerProviderConfig struct {
|
||||
AccessKeyId string `json:"accessKeyId"`
|
||||
// 金山云 SecretAccessKey。
|
||||
SecretAccessKey string `json:"secretAccessKey"`
|
||||
// 域名匹配模式。
|
||||
// 域名匹配模式。暂时只支持精确匹配。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 加速域名(支持泛域名)。
|
||||
@@ -83,69 +83,10 @@ func (d *SSLDeployerProvider) deployToDomain(ctx context.Context, certPEM string
|
||||
return errors.New("config `domain` is required")
|
||||
}
|
||||
|
||||
// 查询域名列表,获取域名 ID
|
||||
// https://docs.ksyun.com/documents/198
|
||||
var domainId string
|
||||
getCdnDomainsPageNumber := int32(1)
|
||||
getCdnDomainsPageSize := int32(100)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
getCdnDomainsInput := map[string]any{
|
||||
"PageNumber": getCdnDomainsPageNumber,
|
||||
"PageSize": getCdnDomainsPageSize,
|
||||
"DomainName": d.config.Domain,
|
||||
"FuzzyMatch": "off",
|
||||
}
|
||||
getCdnDomainsReq, getCdnDomainsOutput := d.sdkClient.GetCdnDomainsPostRequest(&getCdnDomainsInput)
|
||||
getCdnDomainsErr := getCdnDomainsReq.Send()
|
||||
d.logger.Debug("sdk request 'cdn.GetCdnDomains'", slog.Any("request", getCdnDomainsInput), slog.Any("response", getCdnDomainsOutput))
|
||||
if getCdnDomainsErr != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'cdn.GetCdnDomains': %w", getCdnDomainsErr)
|
||||
}
|
||||
|
||||
type GetCdnDomainsResponse struct {
|
||||
PageNumber int32 `json:"PageNumber"`
|
||||
PageSize int32 `json:"PageSize"`
|
||||
TotalCount int32 `json:"TotalCount"`
|
||||
Domains []*struct {
|
||||
DomainId string `json:"DomainId"`
|
||||
DomainName string `json:"DomainName"`
|
||||
Cname string `json:"Cname"`
|
||||
CdnType string `json:"CdnType"`
|
||||
CreatedTime string `json:"CreatedTime"`
|
||||
ModifiedTime string `json:"ModifiedTime"`
|
||||
Region string `json:"Region"`
|
||||
} `json:"Domains"`
|
||||
}
|
||||
var getCdnDomainsResp *GetCdnDomainsResponse
|
||||
mapstructure.Decode(getCdnDomainsOutput, &getCdnDomainsResp)
|
||||
|
||||
if getCdnDomainsResp != nil {
|
||||
for _, domainItem := range getCdnDomainsResp.Domains {
|
||||
if strings.EqualFold(domainItem.DomainName, d.config.Domain) {
|
||||
domainId = domainItem.DomainId
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if domainId != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if getCdnDomainsResp == nil || len(getCdnDomainsResp.Domains) < int(getCdnDomainsPageSize) {
|
||||
break
|
||||
} else {
|
||||
getCdnDomainsPageNumber++
|
||||
}
|
||||
}
|
||||
if domainId == "" {
|
||||
return errors.New("domain not found")
|
||||
// 获取域名 ID
|
||||
domainId, err := d.findDomainIdByDomain(ctx, d.config.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.updateDomainCertificate(ctx, domainId, certPEM, privkeyPEM); err != nil {
|
||||
@@ -178,6 +119,67 @@ func (d *SSLDeployerProvider) deployToCertificate(ctx context.Context, certPEM s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) findDomainIdByDomain(ctx context.Context, domain string) (string, error) {
|
||||
// 查询域名列表
|
||||
// https://docs.ksyun.com/documents/198
|
||||
getCdnDomainsPageNumber := 1
|
||||
getCdnDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
getCdnDomainsInput := map[string]any{
|
||||
"PageNumber": getCdnDomainsPageNumber,
|
||||
"PageSize": getCdnDomainsPageSize,
|
||||
"DomainName": domain,
|
||||
"FuzzyMatch": "off",
|
||||
}
|
||||
getCdnDomainsReq, getCdnDomainsOutput := d.sdkClient.GetCdnDomainsPostRequest(&getCdnDomainsInput)
|
||||
getCdnDomainsErr := getCdnDomainsReq.Send()
|
||||
d.logger.Debug("sdk request 'cdn.GetCdnDomains'", slog.Any("request", getCdnDomainsInput), slog.Any("response", getCdnDomainsOutput))
|
||||
if getCdnDomainsErr != nil {
|
||||
return "", fmt.Errorf("failed to execute sdk request 'cdn.GetCdnDomains': %w", getCdnDomainsErr)
|
||||
}
|
||||
|
||||
type GetCdnDomainsResponse struct {
|
||||
PageNumber int32 `json:"PageNumber"`
|
||||
PageSize int32 `json:"PageSize"`
|
||||
TotalCount int32 `json:"TotalCount"`
|
||||
Domains []*struct {
|
||||
DomainId string `json:"DomainId"`
|
||||
DomainName string `json:"DomainName"`
|
||||
Cname string `json:"Cname"`
|
||||
CdnType string `json:"CdnType"`
|
||||
CreatedTime string `json:"CreatedTime"`
|
||||
ModifiedTime string `json:"ModifiedTime"`
|
||||
Region string `json:"Region"`
|
||||
} `json:"Domains"`
|
||||
}
|
||||
var getCdnDomainsResp *GetCdnDomainsResponse
|
||||
mapstructure.Decode(getCdnDomainsOutput, &getCdnDomainsResp)
|
||||
if getCdnDomainsResp == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, domainItem := range getCdnDomainsResp.Domains {
|
||||
if strings.EqualFold(domainItem.DomainName, domain) {
|
||||
return domainItem.DomainId, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(getCdnDomainsResp.Domains) < getCdnDomainsPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
getCdnDomainsPageNumber++
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("could not find domain '%s'", domain)
|
||||
}
|
||||
|
||||
func (d *SSLDeployerProvider) updateDomainCertificate(ctx context.Context, domainId string, certPEM string, privkeyPEM string) error {
|
||||
// 为加速域名配置证书接口
|
||||
// https://docs.ksyun.com/documents/261
|
||||
|
||||
@@ -164,8 +164,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
|
||||
// 查询域名基本信息,获取匹配的域名
|
||||
// REF: https://cloud.tencent.com/document/api/228/41118
|
||||
describeDomainsOffset := int64(0)
|
||||
describeDomainsLimit := int64(100)
|
||||
describeDomainsOffset := 0
|
||||
describeDomainsLimit := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -181,27 +181,29 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
Fuzzy: common.BoolPtr(true),
|
||||
},
|
||||
}
|
||||
describeDomainsReq.Offset = common.Int64Ptr(describeDomainsOffset)
|
||||
describeDomainsReq.Limit = common.Int64Ptr(describeDomainsLimit)
|
||||
describeDomainsReq.Offset = common.Int64Ptr(int64(describeDomainsOffset))
|
||||
describeDomainsReq.Limit = common.Int64Ptr(int64(describeDomainsLimit))
|
||||
describeDomainsResp, err := d.sdkClient.DescribeDomains(describeDomainsReq)
|
||||
d.logger.Debug("sdk request 'cdn.DescribeDomains'", slog.Any("request", describeDomainsReq), slog.Any("response", describeDomainsResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomains': %w", err)
|
||||
}
|
||||
|
||||
if describeDomainsResp.Response.Domains != nil {
|
||||
for _, domainInfo := range describeDomainsResp.Response.Domains {
|
||||
if lo.FromPtr(domainInfo.Product) == "cdn" && xcerthostname.IsMatch(wildcardDomain, lo.FromPtr(domainInfo.Domain)) {
|
||||
domains = append(domains, *domainInfo.Domain)
|
||||
}
|
||||
if describeDomainsResp.Response == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, domainItem := range describeDomainsResp.Response.Domains {
|
||||
if lo.FromPtr(domainItem.Product) == "cdn" && xcerthostname.IsMatch(wildcardDomain, lo.FromPtr(domainItem.Domain)) {
|
||||
domains = append(domains, lo.FromPtr(domainItem.Domain))
|
||||
}
|
||||
}
|
||||
|
||||
if len(describeDomainsResp.Response.Domains) < int(describeDomainsLimit) {
|
||||
if len(describeDomainsResp.Response.Domains) < describeDomainsLimit {
|
||||
break
|
||||
} else {
|
||||
describeDomainsOffset += describeDomainsLimit
|
||||
}
|
||||
|
||||
describeDomainsOffset += describeDomainsLimit
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
@@ -246,7 +248,7 @@ func (d *SSLDeployerProvider) updateDomainCertificate(ctx context.Context, domai
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomainsConfig': %w", err)
|
||||
} else if len(describeDomainsConfigResp.Response.Domains) == 0 {
|
||||
return fmt.Errorf("domain %s not found", domain)
|
||||
return fmt.Errorf("could not find domain '%s'", domain)
|
||||
}
|
||||
|
||||
domainConfig := describeDomainsConfigResp.Response.Domains[0]
|
||||
|
||||
@@ -233,9 +233,10 @@ func (d *SSLDeployerProvider) deployToRuleDomain(ctx context.Context, cloudCertI
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
}
|
||||
|
||||
if describeTaskStatusResp.Response.Status == nil || *describeTaskStatusResp.Response.Status == 1 {
|
||||
status := lo.FromPtr(describeTaskStatusResp.Response.Status)
|
||||
if status == 1 {
|
||||
return errors.New("unexpected tencentcloud task status")
|
||||
} else if *describeTaskStatusResp.Response.Status == 0 {
|
||||
} else if status == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -257,7 +258,7 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
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("listener %s not found", cloudListenerId)
|
||||
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
|
||||
}
|
||||
|
||||
// 修改监听器属性
|
||||
@@ -295,9 +296,10 @@ func (d *SSLDeployerProvider) updateListenerCertificate(ctx context.Context, clo
|
||||
return fmt.Errorf("failed to execute sdk request 'clb.DescribeTaskStatus': %w", err)
|
||||
}
|
||||
|
||||
if describeTaskStatusResp.Response.Status == nil || *describeTaskStatusResp.Response.Status == 1 {
|
||||
status := lo.FromPtr(describeTaskStatusResp.Response.Status)
|
||||
if status == 1 {
|
||||
return errors.New("unexpected tencentcloud task status")
|
||||
} else if *describeTaskStatusResp.Response.Status == 0 {
|
||||
} else if status == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||
tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
|
||||
@@ -134,21 +135,11 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||
return nil, errors.New("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
if describeHostDeployRecordDetailResp.Response.PendingTotalCount != nil {
|
||||
pendingCount = *describeHostDeployRecordDetailResp.Response.PendingTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||
}
|
||||
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
|
||||
succeededCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.SuccessTotalCount)
|
||||
failedCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.FailedTotalCount)
|
||||
totalCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.TotalCount)
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
@@ -168,8 +159,8 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
func (d *SSLDeployerProvider) checkIsBind(ctx context.Context, cloudCertId string) (bool, error) {
|
||||
// 查询证书 COS 云资源部署实例列表
|
||||
// REF: https://cloud.tencent.com/document/api/400/91661
|
||||
describeHostCosInstanceListLimit := int64(100)
|
||||
describeHostCosInstanceListOffset := int64(0)
|
||||
describeHostCosInstanceListLimit := 100
|
||||
describeHostCosInstanceListOffset := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -181,33 +172,39 @@ func (d *SSLDeployerProvider) checkIsBind(ctx context.Context, cloudCertId strin
|
||||
describeHostCosInstanceListReq.OldCertificateId = common.StringPtr(cloudCertId)
|
||||
describeHostCosInstanceListReq.ResourceType = common.StringPtr("cos")
|
||||
describeHostCosInstanceListReq.IsCache = common.Uint64Ptr(0)
|
||||
describeHostCosInstanceListReq.Offset = common.Int64Ptr(describeHostCosInstanceListOffset)
|
||||
describeHostCosInstanceListReq.Limit = common.Int64Ptr(describeHostCosInstanceListLimit)
|
||||
describeHostCosInstanceListReq.Offset = common.Int64Ptr(int64(describeHostCosInstanceListOffset))
|
||||
describeHostCosInstanceListReq.Limit = common.Int64Ptr(int64(describeHostCosInstanceListLimit))
|
||||
describeHostCosInstanceListResp, err := d.sdkClient.SSL.DescribeHostCosInstanceList(describeHostCosInstanceListReq)
|
||||
d.logger.Debug("sdk request 'ssl.DescribeHostCosInstanceList'", slog.Any("request", describeHostCosInstanceListReq), slog.Any("response", describeHostCosInstanceListResp))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostCosInstanceList': %w", err)
|
||||
}
|
||||
|
||||
if describeHostCosInstanceListResp.Response == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, instance := range describeHostCosInstanceListResp.Response.InstanceList {
|
||||
if instance.Bucket == nil || *instance.Bucket != d.config.Bucket {
|
||||
if lo.FromPtr(instance.Bucket) != d.config.Bucket {
|
||||
continue
|
||||
}
|
||||
if instance.Domain == nil || *instance.Domain != d.config.Domain {
|
||||
if lo.FromPtr(instance.Domain) != d.config.Domain {
|
||||
continue
|
||||
}
|
||||
if instance.Status == nil || *instance.Status != "ENABLED" {
|
||||
if lo.FromPtr(instance.Status) != "ENABLED" {
|
||||
continue
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if len(describeHostCosInstanceListResp.Response.InstanceList) < int(describeHostCosInstanceListLimit) {
|
||||
return false, nil
|
||||
} else {
|
||||
describeHostCosInstanceListOffset += describeHostCosInstanceListLimit
|
||||
if len(describeHostCosInstanceListResp.Response.InstanceList) < describeHostCosInstanceListLimit {
|
||||
break
|
||||
}
|
||||
|
||||
describeHostCosInstanceListOffset += describeHostCosInstanceListLimit
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func createSDKClients(secretId, secretKey, region string) (*wSDKClients, error) {
|
||||
|
||||
@@ -164,8 +164,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
|
||||
// 查询域名基本信息,获取匹配的域名
|
||||
// REF: https://cloud.tencent.com/document/api/228/41118
|
||||
describeDomainsOffset := int64(0)
|
||||
describeDomainsLimit := int64(100)
|
||||
describeDomainsOffset := 0
|
||||
describeDomainsLimit := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -181,27 +181,29 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
Fuzzy: common.BoolPtr(true),
|
||||
},
|
||||
}
|
||||
describeDomainsReq.Offset = common.Int64Ptr(describeDomainsOffset)
|
||||
describeDomainsReq.Limit = common.Int64Ptr(describeDomainsLimit)
|
||||
describeDomainsReq.Offset = common.Int64Ptr(int64(describeDomainsOffset))
|
||||
describeDomainsReq.Limit = common.Int64Ptr(int64(describeDomainsLimit))
|
||||
describeDomainsResp, err := d.sdkClient.DescribeDomains(describeDomainsReq)
|
||||
d.logger.Debug("sdk request 'cdn.DescribeDomains'", slog.Any("request", describeDomainsReq), slog.Any("response", describeDomainsResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomains': %w", err)
|
||||
}
|
||||
|
||||
if describeDomainsResp.Response.Domains != nil {
|
||||
for _, domainInfo := range describeDomainsResp.Response.Domains {
|
||||
if lo.FromPtr(domainInfo.Product) == "ecdn" && xcerthostname.IsMatch(wildcardDomain, lo.FromPtr(domainInfo.Domain)) {
|
||||
domains = append(domains, *domainInfo.Domain)
|
||||
}
|
||||
if describeDomainsResp.Response == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, domainItem := range describeDomainsResp.Response.Domains {
|
||||
if lo.FromPtr(domainItem.Product) == "ecdn" && xcerthostname.IsMatch(wildcardDomain, lo.FromPtr(domainItem.Domain)) {
|
||||
domains = append(domains, *domainItem.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if len(describeDomainsResp.Response.Domains) < int(describeDomainsLimit) {
|
||||
if len(describeDomainsResp.Response.Domains) < describeDomainsLimit {
|
||||
break
|
||||
} else {
|
||||
describeDomainsOffset += describeDomainsLimit
|
||||
}
|
||||
|
||||
describeDomainsOffset += describeDomainsLimit
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
@@ -246,7 +248,7 @@ func (d *SSLDeployerProvider) updateDomainHttpsServerCert(ctx context.Context, d
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'cdn.DescribeDomainsConfig': %w", err)
|
||||
} else if len(describeDomainsConfigResp.Response.Domains) == 0 {
|
||||
return fmt.Errorf("domain %s not found", domain)
|
||||
return fmt.Errorf("could not find domain '%s'", domain)
|
||||
}
|
||||
|
||||
domainConfig := describeDomainsConfigResp.Response.Domains[0]
|
||||
|
||||
@@ -195,11 +195,12 @@ func (d *SSLDeployerProvider) getAllDomainsInZone(ctx context.Context, zoneId st
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'teo.DescribeAccelerationDomains': %w", err)
|
||||
}
|
||||
|
||||
for _, accelerationDomain := range describeAccelerationDomainsResp.Response.AccelerationDomains {
|
||||
if accelerationDomain == nil || accelerationDomain.DomainName == nil {
|
||||
for _, domainItem := range describeAccelerationDomainsResp.Response.AccelerationDomains {
|
||||
if domainItem == nil || domainItem.DomainName == nil {
|
||||
continue
|
||||
}
|
||||
domainsInZone = append(domainsInZone, *accelerationDomain.DomainName)
|
||||
|
||||
domainsInZone = append(domainsInZone, *domainItem.DomainName)
|
||||
}
|
||||
|
||||
if len(describeAccelerationDomainsResp.Response.AccelerationDomains) < pageSize {
|
||||
|
||||
@@ -130,7 +130,7 @@ func (d *SSLDeployerProvider) updateHttpsListenerCertificate(ctx context.Context
|
||||
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("listener %s not found", cloudListenerId)
|
||||
return fmt.Errorf("could not find listener '%s'", cloudListenerId)
|
||||
}
|
||||
|
||||
// 修改 HTTPS 监听器配置
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||
tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
|
||||
@@ -130,21 +131,11 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||
return nil, errors.New("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
if describeHostDeployRecordDetailResp.Response.PendingTotalCount != nil {
|
||||
pendingCount = *describeHostDeployRecordDetailResp.Response.PendingTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||
}
|
||||
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||
}
|
||||
pendingCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.RunningTotalCount)
|
||||
succeededCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.SuccessTotalCount)
|
||||
failedCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.FailedTotalCount)
|
||||
totalCount = lo.FromPtr(describeHostDeployRecordDetailResp.Response.TotalCount)
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
|
||||
+10
-27
@@ -8,6 +8,7 @@ import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||
tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
|
||||
@@ -163,21 +164,11 @@ func (d *SSLDeployerProvider) executeUpdateCertificateInstance(ctx context.Conte
|
||||
if describeHostUpdateRecordDetailResp.Response.TotalCount == nil {
|
||||
return errors.New("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
if describeHostUpdateRecordDetailResp.Response.PendingTotalCount != nil {
|
||||
pendingCount = *describeHostUpdateRecordDetailResp.Response.PendingTotalCount
|
||||
}
|
||||
if describeHostUpdateRecordDetailResp.Response.RunningTotalCount != nil {
|
||||
runningCount = *describeHostUpdateRecordDetailResp.Response.RunningTotalCount
|
||||
}
|
||||
if describeHostUpdateRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||
succeededCount = *describeHostUpdateRecordDetailResp.Response.SuccessTotalCount
|
||||
}
|
||||
if describeHostUpdateRecordDetailResp.Response.FailedTotalCount != nil {
|
||||
failedCount = *describeHostUpdateRecordDetailResp.Response.FailedTotalCount
|
||||
}
|
||||
if describeHostUpdateRecordDetailResp.Response.TotalCount != nil {
|
||||
totalCount = *describeHostUpdateRecordDetailResp.Response.TotalCount
|
||||
}
|
||||
pendingCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.PendingTotalCount)
|
||||
runningCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.RunningTotalCount)
|
||||
succeededCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.SuccessTotalCount)
|
||||
failedCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.FailedTotalCount)
|
||||
totalCount = lo.FromPtr(describeHostUpdateRecordDetailResp.Response.TotalCount)
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
if failedCount > 0 {
|
||||
@@ -250,18 +241,10 @@ func (d *SSLDeployerProvider) executeUploadUpdateCertificateInstance(ctx context
|
||||
return errors.New("unexpected tencentcloud deployment job status")
|
||||
} else {
|
||||
for _, record := range describeHostUploadUpdateRecordDetailResp.Response.DeployRecordDetail {
|
||||
if record.RunningTotalCount != nil {
|
||||
runningCount = *record.RunningTotalCount
|
||||
}
|
||||
if record.SuccessTotalCount != nil {
|
||||
succeededCount = *record.SuccessTotalCount
|
||||
}
|
||||
if record.FailedTotalCount != nil {
|
||||
failedCount = *record.FailedTotalCount
|
||||
}
|
||||
if record.TotalCount != nil {
|
||||
totalCount = *record.TotalCount
|
||||
}
|
||||
runningCount += lo.FromPtr(record.RunningTotalCount)
|
||||
succeededCount += lo.FromPtr(record.SuccessTotalCount)
|
||||
failedCount += lo.FromPtr(record.FailedTotalCount)
|
||||
totalCount += lo.FromPtr(record.TotalCount)
|
||||
}
|
||||
|
||||
if succeededCount+failedCount == totalCount {
|
||||
|
||||
@@ -97,7 +97,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ucdn.GetUcdnDomainConfig': %w", err)
|
||||
} else if len(getUcdnDomainConfigResp.DomainList) == 0 {
|
||||
return nil, fmt.Errorf("domain %s not found", d.config.DomainId)
|
||||
return nil, fmt.Errorf("could not find domain '%s'", d.config.DomainId)
|
||||
}
|
||||
|
||||
// 更新 HTTPS 加速配置
|
||||
|
||||
@@ -129,8 +129,8 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询 HTTPS 监听器列表
|
||||
// REF: https://www.volcengine.com/docs/6767/113684
|
||||
listenerIds := make([]string, 0)
|
||||
describeListenersPageSize := int64(100)
|
||||
describeListenersPageNumber := int64(1)
|
||||
describeListenersPageSize := 100
|
||||
describeListenersPageNumber := 1
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -141,8 +141,8 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
describeListenersReq := &vealb.DescribeListenersInput{
|
||||
LoadBalancerId: ve.String(d.config.LoadbalancerId),
|
||||
Protocol: ve.String("HTTPS"),
|
||||
PageNumber: ve.Int64(describeListenersPageNumber),
|
||||
PageSize: ve.Int64(describeListenersPageSize),
|
||||
PageNumber: ve.Int64(int64(describeListenersPageNumber)),
|
||||
PageSize: ve.Int64(int64(describeListenersPageSize)),
|
||||
}
|
||||
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
|
||||
d.logger.Debug("sdk request 'alb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
|
||||
@@ -154,11 +154,11 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
listenerIds = append(listenerIds, *listener.ListenerId)
|
||||
}
|
||||
|
||||
if len(describeListenersResp.Listeners) < int(describeListenersPageSize) {
|
||||
if len(describeListenersResp.Listeners) < describeListenersPageSize {
|
||||
break
|
||||
} else {
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
|
||||
@@ -158,8 +158,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
|
||||
// 查询加速域名列表,获取匹配的域名
|
||||
// REF: https://www.volcengine.com/docs/6454/75269
|
||||
listCdnDomainsPageNum := int64(1)
|
||||
listCdnDomainsPageSize := int64(100)
|
||||
listCdnDomainsPageNum := 1
|
||||
listCdnDomainsPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -170,8 +170,8 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
listCdnDomainsReq := &vecdn.ListCdnDomainsInput{
|
||||
Domain: ve.String(strings.TrimPrefix(wildcardDomain, "*.")),
|
||||
Status: ve.String("online"),
|
||||
PageNum: ve.Int64(listCdnDomainsPageNum),
|
||||
PageSize: ve.Int64(listCdnDomainsPageSize),
|
||||
PageNum: ve.Int64(int64(listCdnDomainsPageNum)),
|
||||
PageSize: ve.Int64(int64(listCdnDomainsPageSize)),
|
||||
}
|
||||
listCdnDomainsResp, err := d.sdkClient.ListCdnDomains(listCdnDomainsReq)
|
||||
d.logger.Debug("sdk request 'cdn.ListCdnDomains'", slog.Any("request", listCdnDomainsReq), slog.Any("response", listCdnDomainsResp))
|
||||
@@ -179,19 +179,17 @@ func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, w
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.ListCdnDomains': %w", err)
|
||||
}
|
||||
|
||||
if listCdnDomainsResp.Data != nil {
|
||||
for _, domainInfo := range listCdnDomainsResp.Data {
|
||||
if xcerthostname.IsMatch(wildcardDomain, ve.StringValue(domainInfo.Domain)) {
|
||||
domains = append(domains, ve.StringValue(domainInfo.Domain))
|
||||
}
|
||||
for _, domainItem := range listCdnDomainsResp.Data {
|
||||
if xcerthostname.IsMatch(wildcardDomain, ve.StringValue(domainItem.Domain)) {
|
||||
domains = append(domains, ve.StringValue(domainItem.Domain))
|
||||
}
|
||||
}
|
||||
|
||||
if len(listCdnDomainsResp.Data) < int(listCdnDomainsPageSize) {
|
||||
if len(listCdnDomainsResp.Data) < listCdnDomainsPageSize {
|
||||
break
|
||||
} else {
|
||||
listCdnDomainsPageSize++
|
||||
}
|
||||
|
||||
listCdnDomainsPageSize++
|
||||
}
|
||||
|
||||
if len(domains) == 0 {
|
||||
|
||||
@@ -125,8 +125,8 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
// 查询 HTTPS 监听器列表
|
||||
// REF: https://www.volcengine.com/docs/6406/71776
|
||||
listenerIds := make([]string, 0)
|
||||
describeListenersPageSize := int64(100)
|
||||
describeListenersPageNumber := int64(1)
|
||||
describeListenersPageSize := 100
|
||||
describeListenersPageNumber := 1
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -137,8 +137,8 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
describeListenersReq := &veclb.DescribeListenersInput{
|
||||
LoadBalancerId: ve.String(d.config.LoadbalancerId),
|
||||
Protocol: ve.String("HTTPS"),
|
||||
PageNumber: ve.Int64(describeListenersPageNumber),
|
||||
PageSize: ve.Int64(describeListenersPageSize),
|
||||
PageNumber: ve.Int64(int64(describeListenersPageNumber)),
|
||||
PageSize: ve.Int64(int64(describeListenersPageSize)),
|
||||
}
|
||||
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
|
||||
d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
|
||||
@@ -150,11 +150,11 @@ func (d *SSLDeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCer
|
||||
listenerIds = append(listenerIds, *listener.ListenerId)
|
||||
}
|
||||
|
||||
if len(describeListenersResp.Listeners) < int(describeListenersPageSize) {
|
||||
if len(describeListenersResp.Listeners) < describeListenersPageSize {
|
||||
break
|
||||
} else {
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
|
||||
@@ -23,7 +23,7 @@ type SSLDeployerProviderConfig struct {
|
||||
AccessKeySecret string `json:"accessKeySecret"`
|
||||
// 火山引擎地域。
|
||||
Region string `json:"region"`
|
||||
// 域名匹配模式。
|
||||
// 域名匹配模式。暂时只支持精确匹配。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 加速域名(支持泛域名)。
|
||||
|
||||
@@ -172,8 +172,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
// 查询域名列表
|
||||
// REF: https://www.volcengine.com/docs/6469/1126815
|
||||
listDomainDetailPageNum := int32(1)
|
||||
listDomainDetailPageSize := int32(1000)
|
||||
listDomainDetailPageNum := 1
|
||||
listDomainDetailPageSize := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -183,8 +183,8 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
|
||||
listDomainDetailReq := &velive.ListDomainDetailBody{
|
||||
DomainStatusList: ve.Int32Slice([]int32{0}),
|
||||
PageNum: listDomainDetailPageNum,
|
||||
PageSize: listDomainDetailPageSize,
|
||||
PageNum: int32(listDomainDetailPageNum),
|
||||
PageSize: int32(listDomainDetailPageSize),
|
||||
}
|
||||
listDomainDetailResp, err := d.sdkClient.ListDomainDetail(ctx, listDomainDetailReq)
|
||||
d.logger.Debug("sdk request 'live.ListDomainDetail'", slog.Any("request", listDomainDetailReq), slog.Any("response", listDomainDetailResp))
|
||||
@@ -192,17 +192,19 @@ func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, erro
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'live.ListDomainDetail': %w", err)
|
||||
}
|
||||
|
||||
if listDomainDetailResp.Result.DomainList != nil {
|
||||
for _, domainInfo := range listDomainDetailResp.Result.DomainList {
|
||||
domains = append(domains, domainInfo.Domain)
|
||||
}
|
||||
if listDomainDetailResp.Result == nil {
|
||||
break
|
||||
}
|
||||
|
||||
if len(listDomainDetailResp.Result.DomainList) < int(listDomainDetailPageSize) {
|
||||
break
|
||||
} else {
|
||||
listDomainDetailPageNum++
|
||||
for _, domainItem := range listDomainDetailResp.Result.DomainList {
|
||||
domains = append(domains, domainItem.Domain)
|
||||
}
|
||||
|
||||
if len(listDomainDetailResp.Result.DomainList) < listDomainDetailPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
listDomainDetailPageNum++
|
||||
}
|
||||
|
||||
return domains, nil
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package wangsucdn
|
||||
|
||||
const (
|
||||
// 匹配模式:精确匹配。
|
||||
DOMAIN_MATCH_PATTERN_EXACT = "exact"
|
||||
)
|
||||
@@ -20,6 +20,9 @@ type SSLDeployerProviderConfig struct {
|
||||
AccessKeyId string `json:"accessKeyId"`
|
||||
// 网宿云 AccessKeySecret。
|
||||
AccessKeySecret string `json:"accessKeySecret"`
|
||||
// 域名匹配模式。暂时只支持精确匹配。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 加速域名数组(支持泛域名)。
|
||||
Domains []string `json:"domains"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package wangsucdnpro
|
||||
|
||||
const (
|
||||
// 匹配模式:精确匹配。
|
||||
DOMAIN_MATCH_PATTERN_EXACT = "exact"
|
||||
)
|
||||
@@ -32,6 +32,9 @@ type SSLDeployerProviderConfig struct {
|
||||
ApiKey string `json:"apiKey"`
|
||||
// 网宿云环境。
|
||||
Environment string `json:"environment"`
|
||||
// 域名匹配模式。暂时只支持精确匹配。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 加速域名(支持泛域名)。
|
||||
Domain string `json:"domain"`
|
||||
// 证书 ID。
|
||||
|
||||
@@ -60,7 +60,7 @@ func (m *SSLManagerProvider) SetLogger(logger *slog.Logger) {
|
||||
|
||||
func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 避免重复上传
|
||||
if res, err := m.findCertIfExists(ctx, certPEM, privkeyPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM, privkeyPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res != nil {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
@@ -107,19 +107,19 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
// 获取刚刚上传证书 ID
|
||||
if res, err := m.findCertIfExists(ctx, certPEM, privkeyPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM, privkeyPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res == nil {
|
||||
return nil, fmt.Errorf("no ssl certificate found, may be upload failed")
|
||||
return nil, fmt.Errorf("could not find ssl certificate, may be upload failed")
|
||||
} else {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
searchWebsiteSSLPageNumber := int32(1)
|
||||
searchWebsiteSSLPageSize := int32(100)
|
||||
searchWebsiteSSLItemsCount := int32(0)
|
||||
func (m *SSLManagerProvider) tryFindCert(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
searchWebsiteSSLPageNumber := 1
|
||||
searchWebsiteSSLPageSize := 100
|
||||
searchWebsiteSSLItemsCount := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -131,8 +131,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
case *onepanelsdk.Client:
|
||||
{
|
||||
searchWebsiteSSLReq := &onepanelsdk.SearchWebsiteSSLRequest{
|
||||
Page: searchWebsiteSSLPageNumber,
|
||||
PageSize: searchWebsiteSSLPageSize,
|
||||
Page: int32(searchWebsiteSSLPageNumber),
|
||||
PageSize: int32(searchWebsiteSSLPageSize),
|
||||
}
|
||||
searchWebsiteSSLResp, err := sdkClient.SearchWebsiteSSL(searchWebsiteSSLReq)
|
||||
m.logger.Debug("sdk request '1panel.SearchWebsiteSSL'", slog.Any("request", searchWebsiteSSLReq), slog.Any("response", searchWebsiteSSLResp))
|
||||
@@ -140,27 +140,29 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
return nil, fmt.Errorf("failed to execute sdk request '1panel.SearchWebsiteSSL': %w", err)
|
||||
}
|
||||
|
||||
if searchWebsiteSSLResp.Data != nil {
|
||||
for _, sslItem := range searchWebsiteSSLResp.Data.Items {
|
||||
if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) &&
|
||||
strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) {
|
||||
// 如果已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslItem.ID),
|
||||
CertName: sslItem.Description,
|
||||
}, nil
|
||||
}
|
||||
if searchWebsiteSSLResp.Data == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, sslItem := range searchWebsiteSSLResp.Data.Items {
|
||||
if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) &&
|
||||
strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) {
|
||||
// 如果已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslItem.ID),
|
||||
CertName: sslItem.Description,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
searchWebsiteSSLItemsCount = searchWebsiteSSLResp.Data.Total
|
||||
searchWebsiteSSLItemsCount = int(searchWebsiteSSLResp.Data.Total)
|
||||
}
|
||||
|
||||
case *onepanelsdkv2.Client:
|
||||
{
|
||||
searchWebsiteSSLReq := &onepanelsdkv2.SearchWebsiteSSLRequest{
|
||||
Page: searchWebsiteSSLPageNumber,
|
||||
PageSize: searchWebsiteSSLPageSize,
|
||||
Page: int32(searchWebsiteSSLPageNumber),
|
||||
PageSize: int32(searchWebsiteSSLPageSize),
|
||||
}
|
||||
searchWebsiteSSLResp, err := sdkClient.SearchWebsiteSSL(searchWebsiteSSLReq)
|
||||
m.logger.Debug("sdk request '1panel.SearchWebsiteSSL'", slog.Any("request", searchWebsiteSSLReq), slog.Any("response", searchWebsiteSSLResp))
|
||||
@@ -168,20 +170,22 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
return nil, fmt.Errorf("failed to execute sdk request '1panel.SearchWebsiteSSL': %w", err)
|
||||
}
|
||||
|
||||
if searchWebsiteSSLResp.Data != nil {
|
||||
for _, sslItem := range searchWebsiteSSLResp.Data.Items {
|
||||
if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) &&
|
||||
strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) {
|
||||
// 如果已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslItem.ID),
|
||||
CertName: sslItem.Description,
|
||||
}, nil
|
||||
}
|
||||
if searchWebsiteSSLResp.Data == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, sslItem := range searchWebsiteSSLResp.Data.Items {
|
||||
if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) &&
|
||||
strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) {
|
||||
// 如果已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslItem.ID),
|
||||
CertName: sslItem.Description,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
searchWebsiteSSLItemsCount = searchWebsiteSSLResp.Data.Total
|
||||
searchWebsiteSSLItemsCount = int(searchWebsiteSSLResp.Data.Total)
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -73,8 +73,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listusercertificateorder
|
||||
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getusercertificatedetail
|
||||
listUserCertificateOrderPage := int64(1)
|
||||
listUserCertificateOrderLimit := int64(50)
|
||||
listUserCertificateOrderPage := 1
|
||||
listUserCertificateOrderLimit := 50
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -84,8 +84,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
listUserCertificateOrderReq := &alicas.ListUserCertificateOrderRequest{
|
||||
ResourceGroupId: lo.EmptyableToPtr(m.config.ResourceGroupId),
|
||||
CurrentPage: tea.Int64(listUserCertificateOrderPage),
|
||||
ShowSize: tea.Int64(listUserCertificateOrderLimit),
|
||||
CurrentPage: tea.Int64(int64(listUserCertificateOrderPage)),
|
||||
ShowSize: tea.Int64(int64(listUserCertificateOrderLimit)),
|
||||
OrderType: tea.String("CERT"),
|
||||
}
|
||||
listUserCertificateOrderResp, err := m.sdkClient.ListUserCertificateOrderWithContext(context.TODO(), listUserCertificateOrderReq, &dara.RuntimeOptions{})
|
||||
@@ -94,53 +94,55 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.ListUserCertificateOrder': %w", err)
|
||||
}
|
||||
|
||||
if listUserCertificateOrderResp.Body.CertificateOrderList != nil {
|
||||
for _, certOrder := range listUserCertificateOrderResp.Body.CertificateOrderList {
|
||||
// 先对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, tea.StringValue(certOrder.CommonName)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书序列号
|
||||
// 注意阿里云 CAS 会在序列号前补零,需去除后再比较
|
||||
oldCertSN := strings.TrimLeft(tea.StringValue(certOrder.SerialNo), "0")
|
||||
newCertSN := strings.TrimLeft(certX509.SerialNumber.Text(16), "0")
|
||||
if !strings.EqualFold(newCertSN, oldCertSN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
getUserCertificateDetailReq := &alicas.GetUserCertificateDetailRequest{
|
||||
CertId: certOrder.CertificateId,
|
||||
}
|
||||
getUserCertificateDetailResp, err := m.sdkClient.GetUserCertificateDetailWithContext(context.TODO(), getUserCertificateDetailReq, &dara.RuntimeOptions{})
|
||||
m.logger.Debug("sdk request 'cas.GetUserCertificateDetail'", slog.Any("request", getUserCertificateDetailReq), slog.Any("response", getUserCertificateDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.GetUserCertificateDetail': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, tea.StringValue(getUserCertificateDetailResp.Body.Cert)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", tea.Int64Value(certOrder.CertificateId)),
|
||||
CertName: *certOrder.Name,
|
||||
ExtendedData: map[string]any{
|
||||
"InstanceId": tea.StringValue(getUserCertificateDetailResp.Body.InstanceId),
|
||||
"CertIdentifier": tea.StringValue(getUserCertificateDetailResp.Body.CertIdentifier),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) {
|
||||
if listUserCertificateOrderResp.Body == nil {
|
||||
break
|
||||
} else {
|
||||
listUserCertificateOrderPage++
|
||||
}
|
||||
|
||||
for _, certItem := range listUserCertificateOrderResp.Body.CertificateOrderList {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, tea.StringValue(certItem.CommonName)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书序列号
|
||||
// 注意阿里云 CAS 会在序列号前补零,需去除后再比较
|
||||
oldCertSN := strings.TrimLeft(tea.StringValue(certItem.SerialNo), "0")
|
||||
newCertSN := strings.TrimLeft(certX509.SerialNumber.Text(16), "0")
|
||||
if !strings.EqualFold(newCertSN, oldCertSN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
getUserCertificateDetailReq := &alicas.GetUserCertificateDetailRequest{
|
||||
CertId: certItem.CertificateId,
|
||||
}
|
||||
getUserCertificateDetailResp, err := m.sdkClient.GetUserCertificateDetailWithContext(context.TODO(), getUserCertificateDetailReq, &dara.RuntimeOptions{})
|
||||
m.logger.Debug("sdk request 'cas.GetUserCertificateDetail'", slog.Any("request", getUserCertificateDetailReq), slog.Any("response", getUserCertificateDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cas.GetUserCertificateDetail': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, tea.StringValue(getUserCertificateDetailResp.Body.Cert)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", tea.Int64Value(certItem.CertificateId)),
|
||||
CertName: *certItem.Name,
|
||||
ExtendedData: map[string]any{
|
||||
"InstanceId": tea.StringValue(getUserCertificateDetailResp.Body.InstanceId),
|
||||
"CertIdentifier": tea.StringValue(getUserCertificateDetailResp.Body.CertIdentifier),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(listUserCertificateOrderResp.Body.CertificateOrderList) < listUserCertificateOrderLimit {
|
||||
break
|
||||
}
|
||||
|
||||
listUserCertificateOrderPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合阿里云命名规则)
|
||||
|
||||
@@ -87,22 +87,22 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
if describeServerCertificatesResp.Body.ServerCertificates != nil && describeServerCertificatesResp.Body.ServerCertificates.ServerCertificate != nil {
|
||||
fingerprint := sha256.Sum256(certX509.Raw)
|
||||
fingerprintHex := hex.EncodeToString(fingerprint[:])
|
||||
for _, serverCert := range describeServerCertificatesResp.Body.ServerCertificates.ServerCertificate {
|
||||
if tea.Int32Value(serverCert.IsAliCloudCertificate) != 0 {
|
||||
for _, certItem := range describeServerCertificatesResp.Body.ServerCertificates.ServerCertificate {
|
||||
if tea.Int32Value(certItem.IsAliCloudCertificate) != 0 {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, tea.StringValue(serverCert.CommonName)) {
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, tea.StringValue(certItem.CommonName)) {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(fingerprintHex, strings.ReplaceAll(tea.StringValue(serverCert.Fingerprint), ":", "")) {
|
||||
if !strings.EqualFold(fingerprintHex, strings.ReplaceAll(tea.StringValue(certItem.Fingerprint), ":", "")) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: *serverCert.ServerCertificateId,
|
||||
CertName: *serverCert.ServerCertificateName,
|
||||
CertId: *certItem.ServerCertificateId,
|
||||
CertName: *certItem.ServerCertificateName,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 获取证书列表,避免重复上传
|
||||
// REF: https://docs.aws.amazon.com/en_us/acm/latest/APIReference/API_ListCertificates.html
|
||||
var listCertificatesNextToken *string = nil
|
||||
var listCertificatesMaxItems int32 = 1000
|
||||
// REF: https://docs.aws.amazon.com/en_us/acm/latest/APIReference/API_GetCertificate.html
|
||||
listCertificatesNextToken := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -84,7 +84,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
listCertificatesReq := &awsacm.ListCertificatesInput{
|
||||
NextToken: listCertificatesNextToken,
|
||||
MaxItems: aws.Int32(listCertificatesMaxItems),
|
||||
MaxItems: aws.Int32(1000),
|
||||
}
|
||||
listCertificatesResp, err := m.sdkClient.ListCertificates(context.TODO(), listCertificatesReq)
|
||||
m.logger.Debug("sdk request 'acm.ListCertificates'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
|
||||
@@ -92,24 +92,23 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'acm.ListCertificates': %w", err)
|
||||
}
|
||||
|
||||
for _, certSummary := range listCertificatesResp.CertificateSummaryList {
|
||||
// 先对比证书有效期
|
||||
if certSummary.NotBefore == nil || !certSummary.NotBefore.Equal(certX509.NotBefore) {
|
||||
for _, certItem := range listCertificatesResp.CertificateSummaryList {
|
||||
// 对比证书有效期
|
||||
if certItem.NotBefore == nil || !certItem.NotBefore.Equal(certX509.NotBefore) {
|
||||
continue
|
||||
}
|
||||
if certSummary.NotAfter == nil || !certSummary.NotAfter.Equal(certX509.NotAfter) {
|
||||
if certItem.NotAfter == nil || !certItem.NotAfter.Equal(certX509.NotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书多域名
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certSummary.SubjectAlternativeNameSummaries, ",")) {
|
||||
// 对比证书多域名
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certItem.SubjectAlternativeNameSummaries, ",")) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// REF: https://docs.aws.amazon.com/en_us/acm/latest/APIReference/API_GetCertificate.html
|
||||
// 对比证书内容
|
||||
getCertificateReq := &awsacm.GetCertificateInput{
|
||||
CertificateArn: certSummary.CertificateArn,
|
||||
CertificateArn: certItem.CertificateArn,
|
||||
}
|
||||
getCertificateResp, err := m.sdkClient.GetCertificate(context.TODO(), getCertificateReq)
|
||||
if err != nil {
|
||||
@@ -123,15 +122,15 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: *certSummary.CertificateArn,
|
||||
CertId: *certItem.CertificateArn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if listCertificatesResp.NextToken == nil || len(listCertificatesResp.CertificateSummaryList) < int(listCertificatesMaxItems) {
|
||||
if len(listCertificatesResp.CertificateSummaryList) == 0 || listCertificatesResp.NextToken == nil {
|
||||
break
|
||||
} else {
|
||||
listCertificatesNextToken = listCertificatesResp.NextToken
|
||||
}
|
||||
|
||||
listCertificatesNextToken = listCertificatesResp.NextToken
|
||||
}
|
||||
|
||||
// 导入证书
|
||||
|
||||
@@ -76,8 +76,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 获取证书列表,避免重复上传
|
||||
// REF: https://docs.aws.amazon.com/en_us/IAM/latest/APIReference/API_ListServerCertificates.html
|
||||
var listServerCertificatesMarker *string = nil
|
||||
var listServerCertificatesMaxItems int32 = 1000
|
||||
// REF: https://docs.aws.amazon.com/en_us/IAM/latest/APIReference/API_GetServerCertificate.html
|
||||
listServerCertificatesMarker := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -87,7 +87,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
listServerCertificatesReq := &awsiam.ListServerCertificatesInput{
|
||||
Marker: listServerCertificatesMarker,
|
||||
MaxItems: aws.Int32(listServerCertificatesMaxItems),
|
||||
MaxItems: aws.Int32(1000),
|
||||
}
|
||||
if m.config.CertificatePath != "" {
|
||||
listServerCertificatesReq.PathPrefix = aws.String(m.config.CertificatePath)
|
||||
@@ -98,21 +98,20 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'iam.ListServerCertificates': %w", err)
|
||||
}
|
||||
|
||||
for _, certMeta := range listServerCertificatesResp.ServerCertificateMetadataList {
|
||||
// 先对比证书路径
|
||||
if m.config.CertificatePath != "" && aws.ToString(certMeta.Path) != m.config.CertificatePath {
|
||||
for _, certItem := range listServerCertificatesResp.ServerCertificateMetadataList {
|
||||
// 对比证书路径
|
||||
if m.config.CertificatePath != "" && aws.ToString(certItem.Path) != m.config.CertificatePath {
|
||||
continue
|
||||
}
|
||||
|
||||
// 先对比证书有效期
|
||||
if certMeta.Expiration == nil || !certMeta.Expiration.Equal(certX509.NotAfter) {
|
||||
// 对比证书有效期
|
||||
if certItem.Expiration == nil || !certItem.Expiration.Equal(certX509.NotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// REF: https://docs.aws.amazon.com/en_us/IAM/latest/APIReference/API_GetServerCertificate.html
|
||||
// 对比证书内容
|
||||
getServerCertificateReq := &awsiam.GetServerCertificateInput{
|
||||
ServerCertificateName: certMeta.ServerCertificateName,
|
||||
ServerCertificateName: certItem.ServerCertificateName,
|
||||
}
|
||||
getServerCertificateResp, err := m.sdkClient.GetServerCertificate(context.TODO(), getServerCertificateReq)
|
||||
if err != nil {
|
||||
@@ -126,16 +125,16 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: aws.ToString(certMeta.ServerCertificateId),
|
||||
CertName: aws.ToString(certMeta.ServerCertificateName),
|
||||
CertId: aws.ToString(certItem.ServerCertificateId),
|
||||
CertName: aws.ToString(certItem.ServerCertificateName),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if listServerCertificatesResp.Marker == nil || len(listServerCertificatesResp.ServerCertificateMetadataList) < int(listServerCertificatesMaxItems) {
|
||||
if len(listServerCertificatesResp.ServerCertificateMetadataList) == 0 || listServerCertificatesResp.Marker == nil {
|
||||
break
|
||||
} else {
|
||||
listServerCertificatesMarker = listServerCertificatesResp.Marker
|
||||
}
|
||||
|
||||
listServerCertificatesMarker = listServerCertificatesResp.Marker
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合 AWS IAM 命名规则)
|
||||
|
||||
@@ -86,35 +86,35 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'keyvault.GetCertificates': %w", err)
|
||||
}
|
||||
|
||||
for _, certProp := range page.Value {
|
||||
// 先对比证书有效期
|
||||
if certProp.Attributes == nil {
|
||||
for _, certItem := range page.Value {
|
||||
// 对比证书有效期
|
||||
if certItem.Attributes == nil {
|
||||
continue
|
||||
}
|
||||
if certProp.Attributes.NotBefore == nil || !certProp.Attributes.NotBefore.Equal(certX509.NotBefore) {
|
||||
if certItem.Attributes.NotBefore == nil || !certItem.Attributes.NotBefore.Equal(certX509.NotBefore) {
|
||||
continue
|
||||
}
|
||||
if certProp.Attributes.Expires == nil || !certProp.Attributes.Expires.Equal(certX509.NotAfter) {
|
||||
if certItem.Attributes.Expires == nil || !certItem.Attributes.Expires.Equal(certX509.NotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比 Tag 中的通用名称
|
||||
if v, ok := certProp.Tags[TAG_CERTCN]; !ok || v == nil {
|
||||
// 对比 Tag 中的通用名称
|
||||
if v, ok := certItem.Tags[TAG_CERTCN]; !ok || v == nil {
|
||||
continue
|
||||
} else if *v != certCN {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比 Tag 中的序列号
|
||||
if v, ok := certProp.Tags[TAG_CERTSN]; !ok || v == nil {
|
||||
// 对比 Tag 中的序列号
|
||||
if v, ok := certItem.Tags[TAG_CERTSN]; !ok || v == nil {
|
||||
continue
|
||||
} else if *v != certSN {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
getCertificateResp, err := m.sdkClient.GetCertificate(context.TODO(), certProp.ID.Name(), certProp.ID.Version(), nil)
|
||||
m.logger.Debug("sdk request 'keyvault.GetCertificate'", slog.String("request.certificateName", certProp.ID.Name()), slog.String("request.certificateVersion", certProp.ID.Version()), slog.Any("response", getCertificateResp))
|
||||
// 对比证书内容
|
||||
getCertificateResp, err := m.sdkClient.GetCertificate(context.TODO(), certItem.ID.Name(), certItem.ID.Version(), nil)
|
||||
m.logger.Debug("sdk request 'keyvault.GetCertificate'", slog.String("request.certificateName", certItem.ID.Name()), slog.String("request.certificateVersion", certItem.ID.Version()), slog.Any("response", getCertificateResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'keyvault.GetCertificate': %w", err)
|
||||
} else {
|
||||
@@ -126,8 +126,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: string(*certProp.ID),
|
||||
CertName: certProp.ID.Name(),
|
||||
CertId: string(*certItem.ID),
|
||||
CertName: certItem.ID.Name(),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,27 +67,27 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cert.ListCertDetail': %w", err)
|
||||
} else {
|
||||
for _, certDetail := range listCertDetail.Certs {
|
||||
// 先对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certDetail.CertCommonName) {
|
||||
for _, certItem := range listCertDetail.Certs {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CertCommonName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse("2006-01-02T15:04:05Z", certDetail.CertStartTime)
|
||||
oldCertNotAfter, _ := time.Parse("2006-01-02T15:04:05Z", certDetail.CertStopTime)
|
||||
// 对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse("2006-01-02T15:04:05Z", certItem.CertStartTime)
|
||||
oldCertNotAfter, _ := time.Parse("2006-01-02T15:04:05Z", certItem.CertStopTime)
|
||||
if !certX509.NotBefore.Equal(oldCertNotBefore) || !certX509.NotAfter.Equal(oldCertNotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书多域名
|
||||
if certDetail.CertDNSNames != strings.Join(certX509.DNSNames, ",") {
|
||||
// 对比证书多域名
|
||||
if certItem.CertDNSNames != strings.Join(certX509.DNSNames, ",") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
getCertDetailResp, err := m.sdkClient.GetCertRawData(certDetail.CertId)
|
||||
m.logger.Debug("sdk request 'cert.GetCertRawData'", slog.Any("certId", certDetail.CertId), slog.Any("response", getCertDetailResp))
|
||||
// 对比证书内容
|
||||
getCertDetailResp, err := m.sdkClient.GetCertRawData(certItem.CertId)
|
||||
m.logger.Debug("sdk request 'cert.GetCertRawData'", slog.Any("certId", certItem.CertId), slog.Any("response", getCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cert.GetCertRawData': %w", err)
|
||||
} else {
|
||||
@@ -99,8 +99,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certDetail.CertId,
|
||||
CertName: certDetail.CertName,
|
||||
CertId: certItem.CertId,
|
||||
CertName: certItem.CertName,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,14 +65,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-listcertinfo
|
||||
listCertInfoPageNum := int64(1)
|
||||
listCertInfoPageSize := int64(100)
|
||||
listCertInfoTotal := 0
|
||||
listCertInfoReq := &bytepluscdn.ListCertInfoRequest{
|
||||
PageNum: bytepluscdn.GetInt64Ptr(listCertInfoPageNum),
|
||||
PageSize: bytepluscdn.GetInt64Ptr(listCertInfoPageSize),
|
||||
Source: bytepluscdn.GetStrPtr("cert_center"),
|
||||
}
|
||||
listCertInfoPageNum := 1
|
||||
listCertInfoPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -80,36 +74,43 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
default:
|
||||
}
|
||||
|
||||
listCertInfoReq := &bytepluscdn.ListCertInfoRequest{
|
||||
PageNum: bytepluscdn.GetInt64Ptr(int64(listCertInfoPageNum)),
|
||||
PageSize: bytepluscdn.GetInt64Ptr(int64(listCertInfoPageSize)),
|
||||
Source: bytepluscdn.GetStrPtr("cert_center"),
|
||||
}
|
||||
listCertInfoResp, err := m.sdkClient.ListCertInfo(listCertInfoReq)
|
||||
m.logger.Debug("sdk request 'cdn.ListCertInfo'", slog.Any("request", listCertInfoReq), slog.Any("response", listCertInfoResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.ListCertInfo': %w", err)
|
||||
}
|
||||
|
||||
if listCertInfoResp.Result.CertInfo != nil {
|
||||
for _, certInfo := range listCertInfoResp.Result.CertInfo {
|
||||
fingerprintSha1 := sha1.Sum(certX509.Raw)
|
||||
fingerprintSha256 := sha256.Sum256(certX509.Raw)
|
||||
isSameCert := strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), certInfo.CertFingerprint.Sha1) &&
|
||||
strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), certInfo.CertFingerprint.Sha256)
|
||||
// 如果已存在相同证书,直接返回
|
||||
if isSameCert {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certInfo.CertId,
|
||||
CertName: certInfo.Desc,
|
||||
}, nil
|
||||
}
|
||||
for _, certItem := range listCertInfoResp.Result.CertInfo {
|
||||
// 对比证书 SHA-1 摘要
|
||||
fingerprintSha1 := sha1.Sum(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), certItem.CertFingerprint.Sha1) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书 SHA-256 摘要
|
||||
fingerprintSha256 := sha256.Sum256(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), certItem.CertFingerprint.Sha256) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.CertId,
|
||||
CertName: certItem.Desc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
listCertInfoLen := len(listCertInfoResp.Result.CertInfo)
|
||||
if listCertInfoLen < int(listCertInfoPageSize) || int(listCertInfoResp.Result.Total) <= listCertInfoTotal+listCertInfoLen {
|
||||
if len(listCertInfoResp.Result.CertInfo) < listCertInfoPageSize {
|
||||
break
|
||||
} else {
|
||||
listCertInfoPageNum++
|
||||
listCertInfoTotal += listCertInfoLen
|
||||
}
|
||||
|
||||
listCertInfoPageNum++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合 BytePlus 命名规则)
|
||||
|
||||
@@ -65,8 +65,9 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询用户名下证书列表,避免重复上传
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13175&data=174&isNormal=1&vid=167
|
||||
listCertPage := int32(1)
|
||||
listCertPerPage := int32(1000)
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13015&data=174&isNormal=1&vid=167
|
||||
listCertPage := 1
|
||||
listCertPerPage := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -75,8 +76,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
listCertsReq := &ctyunao.ListCertsRequest{
|
||||
Page: lo.ToPtr(listCertPage),
|
||||
PerPage: lo.ToPtr(listCertPerPage),
|
||||
Page: lo.ToPtr(int32(listCertPage)),
|
||||
PerPage: lo.ToPtr(int32(listCertPerPage)),
|
||||
UsageMode: lo.ToPtr(int32(0)),
|
||||
}
|
||||
listCertsResp, err := m.sdkClient.ListCerts(listCertsReq)
|
||||
@@ -85,55 +86,55 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ao.ListCerts': %w", err)
|
||||
}
|
||||
|
||||
if listCertsResp.ReturnObj != nil {
|
||||
for _, certRecord := range listCertsResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certRecord.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certRecord.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certRecord.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certRecord.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// 查询证书详情
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13015&data=174&isNormal=1&vid=167
|
||||
queryCertReq := &ctyunao.QueryCertRequest{
|
||||
Id: lo.ToPtr(certRecord.Id),
|
||||
}
|
||||
queryCertResp, err := m.sdkClient.QueryCert(queryCertReq)
|
||||
m.logger.Debug("sdk request 'ao.QueryCert'", slog.Any("request", queryCertReq), slog.Any("response", queryCertResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ao.QueryCert': %w", err)
|
||||
} else if queryCertResp.ReturnObj != nil && queryCertResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if listCertsResp.ReturnObj == nil || len(listCertsResp.ReturnObj.Results) < int(listCertPerPage) {
|
||||
if listCertsResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
listCertPage++
|
||||
}
|
||||
|
||||
for _, certItem := range listCertsResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certItem.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certItem.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certItem.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
queryCertReq := &ctyunao.QueryCertRequest{
|
||||
Id: lo.ToPtr(certItem.Id),
|
||||
}
|
||||
queryCertResp, err := m.sdkClient.QueryCert(queryCertReq)
|
||||
m.logger.Debug("sdk request 'ao.QueryCert'", slog.Any("request", queryCertReq), slog.Any("response", queryCertResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ao.QueryCert': %w", err)
|
||||
} else if queryCertResp.ReturnObj != nil && queryCertResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(listCertsResp.ReturnObj.Results) < listCertPerPage {
|
||||
break
|
||||
}
|
||||
|
||||
listCertPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合天翼云命名规则)
|
||||
|
||||
@@ -65,8 +65,9 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=108&api=10901&data=161&isNormal=1&vid=154
|
||||
queryCertListPage := int32(1)
|
||||
queryCertListPerPage := int32(1000)
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=108&api=10899&data=161&isNormal=1&vid=154
|
||||
queryCertListPage := 1
|
||||
queryCertListPerPage := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -75,8 +76,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
queryCertListReq := &ctyuncdn.QueryCertListRequest{
|
||||
Page: lo.ToPtr(queryCertListPage),
|
||||
PerPage: lo.ToPtr(queryCertListPerPage),
|
||||
Page: lo.ToPtr(int32(queryCertListPage)),
|
||||
PerPage: lo.ToPtr(int32(queryCertListPerPage)),
|
||||
UsageMode: lo.ToPtr(int32(0)),
|
||||
}
|
||||
queryCertListResp, err := m.sdkClient.QueryCertList(queryCertListReq)
|
||||
@@ -85,55 +86,55 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryCertList': %w", err)
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj != nil {
|
||||
for _, certRecord := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certRecord.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certRecord.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certRecord.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certRecord.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// 查询证书详情
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=108&api=10899&data=161&isNormal=1&vid=154
|
||||
queryCertDetailReq := &ctyuncdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certRecord.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'cdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj == nil || len(queryCertListResp.ReturnObj.Results) < int(queryCertListPerPage) {
|
||||
if queryCertListResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
for _, certItem := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certItem.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certItem.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certItem.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
queryCertDetailReq := &ctyuncdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certItem.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'cdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(queryCertListResp.ReturnObj.Results) < queryCertListPerPage {
|
||||
break
|
||||
}
|
||||
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合天翼云命名规则)
|
||||
|
||||
@@ -59,7 +59,10 @@ func (m *SSLManagerProvider) SetLogger(logger *slog.Logger) {
|
||||
|
||||
func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 避免重复上传
|
||||
if res, _ := m.findCertIfExists(ctx, certPEM); res != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res != nil {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -85,7 +88,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
m.logger.Debug("sdk request 'cms.UploadCertificate'", slog.Any("request", uploadCertificateReq), slog.Any("response", uploadCertificateResp))
|
||||
if err != nil {
|
||||
if uploadCertificateResp != nil && uploadCertificateResp.GetError() == "CCMS_100000067" {
|
||||
if res, err := m.findCertIfExists(ctx, certPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res == nil {
|
||||
return nil, errors.New("ctyun cms: no certificate found")
|
||||
@@ -99,16 +102,16 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
// 获取刚刚上传证书 ID
|
||||
if res, err := m.findCertIfExists(ctx, certPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res == nil {
|
||||
return nil, fmt.Errorf("no ssl certificate found, may be upload failed")
|
||||
return nil, fmt.Errorf("could not find ssl certificate, may be upload failed")
|
||||
} else {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
func (m *SSLManagerProvider) tryFindCert(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 解析证书内容
|
||||
certX509, err := xcert.ParseCertificateFromPEM(certPEM)
|
||||
if err != nil {
|
||||
@@ -117,8 +120,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
|
||||
// 查询用户证书列表
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=152&api=17233&data=204&isNormal=1&vid=283
|
||||
getCertificateListPageNum := int32(1)
|
||||
getCertificateListPageSize := int32(10)
|
||||
getCertificateListPageNum := 1
|
||||
getCertificateListPageSize := 10
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -127,8 +130,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
}
|
||||
|
||||
getCertificateListReq := &ctyuncms.GetCertificateListRequest{
|
||||
PageNum: lo.ToPtr(getCertificateListPageNum),
|
||||
PageSize: lo.ToPtr(getCertificateListPageSize),
|
||||
PageNum: lo.ToPtr(int32(getCertificateListPageNum)),
|
||||
PageSize: lo.ToPtr(int32(getCertificateListPageSize)),
|
||||
Keyword: lo.ToPtr(certX509.Subject.CommonName),
|
||||
Origin: lo.ToPtr("UPLOAD"),
|
||||
}
|
||||
@@ -138,44 +141,45 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cms.GetCertificateList': %w", err)
|
||||
}
|
||||
|
||||
if getCertificateListResp.ReturnObj != nil {
|
||||
if getCertificateListResp.ReturnObj == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, certItem := range getCertificateListResp.ReturnObj.List {
|
||||
// 对比证书名称
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), certItem.DomainName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse("2006-01-02T15:04:05Z", certItem.IssueTime)
|
||||
oldCertNotAfter, _ := time.Parse("2006-01-02T15:04:05Z", certItem.ExpireTime)
|
||||
if !certX509.NotBefore.Equal(oldCertNotBefore) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(oldCertNotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书指纹
|
||||
fingerprint := sha1.Sum(certX509.Raw)
|
||||
fingerprintHex := hex.EncodeToString(fingerprint[:])
|
||||
|
||||
for _, certRecord := range getCertificateListResp.ReturnObj.List {
|
||||
// 对比证书名称
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), certRecord.DomainName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse("2006-01-02T15:04:05Z", certRecord.IssueTime)
|
||||
oldCertNotAfter, _ := time.Parse("2006-01-02T15:04:05Z", certRecord.ExpireTime)
|
||||
if !certX509.NotBefore.Equal(oldCertNotBefore) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(oldCertNotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书指纹
|
||||
if !strings.EqualFold(fingerprintHex, certRecord.Fingerprint) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: string(*&certRecord.Id),
|
||||
CertName: certRecord.Name,
|
||||
}, nil
|
||||
if !strings.EqualFold(fingerprintHex, certItem.Fingerprint) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.Id,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if getCertificateListResp.ReturnObj == nil || len(getCertificateListResp.ReturnObj.List) < int(getCertificateListPageSize) {
|
||||
if len(getCertificateListResp.ReturnObj.List) < getCertificateListPageSize {
|
||||
break
|
||||
} else {
|
||||
getCertificateListPageNum++
|
||||
}
|
||||
|
||||
getCertificateListPageNum++
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -68,13 +68,13 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'elb.ListCertificates': %w", err)
|
||||
} else {
|
||||
for _, certRecord := range listCertificatesResp.ReturnObj {
|
||||
for _, certItem := range listCertificatesResp.ReturnObj {
|
||||
// 如果已存在相同证书,直接返回
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, certRecord.Certificate) {
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, certItem.Certificate) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certRecord.ID,
|
||||
CertName: certRecord.Name,
|
||||
CertId: certItem.ID,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,9 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10838&data=173&isNormal=1&vid=166
|
||||
queryCertListPage := int32(1)
|
||||
queryCertListPerPage := int32(1000)
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10837&data=173&isNormal=1&vid=166
|
||||
queryCertListPage := 1
|
||||
queryCertListPerPage := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -75,8 +76,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
queryCertListReq := &ctyunicdn.QueryCertListRequest{
|
||||
Page: lo.ToPtr(queryCertListPage),
|
||||
PerPage: lo.ToPtr(queryCertListPerPage),
|
||||
Page: lo.ToPtr(int32(queryCertListPage)),
|
||||
PerPage: lo.ToPtr(int32(queryCertListPerPage)),
|
||||
UsageMode: lo.ToPtr(int32(0)),
|
||||
}
|
||||
queryCertListResp, err := m.sdkClient.QueryCertList(queryCertListReq)
|
||||
@@ -85,55 +86,55 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'icdn.QueryCertList': %w", err)
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj != nil {
|
||||
for _, certRecord := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certRecord.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certRecord.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certRecord.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certRecord.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// 查询证书详情
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10837&data=173&isNormal=1&vid=166
|
||||
queryCertDetailReq := &ctyunicdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certRecord.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'icdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'icdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj == nil || len(queryCertListResp.ReturnObj.Results) < int(queryCertListPerPage) {
|
||||
if queryCertListResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
for _, certItem := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certItem.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certItem.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certItem.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
queryCertDetailReq := &ctyunicdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certItem.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'icdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'icdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(queryCertListResp.ReturnObj.Results) < queryCertListPerPage {
|
||||
break
|
||||
}
|
||||
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合天翼云命名规则)
|
||||
|
||||
@@ -65,8 +65,9 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=125&api=11452&data=183&isNormal=1&vid=261
|
||||
queryCertListPage := int32(1)
|
||||
queryCertListPerPage := int32(1000)
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=125&api=11449&data=183&isNormal=1&vid=261
|
||||
queryCertListPage := 1
|
||||
queryCertListPerPage := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -75,8 +76,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
queryCertListReq := &ctyunlvdn.QueryCertListRequest{
|
||||
Page: lo.ToPtr(queryCertListPage),
|
||||
PerPage: lo.ToPtr(queryCertListPerPage),
|
||||
Page: lo.ToPtr(int32(queryCertListPage)),
|
||||
PerPage: lo.ToPtr(int32(queryCertListPerPage)),
|
||||
UsageMode: lo.ToPtr(int32(0)),
|
||||
}
|
||||
queryCertListResp, err := m.sdkClient.QueryCertList(queryCertListReq)
|
||||
@@ -85,55 +86,55 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'lvdn.QueryCertList': %w", err)
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj != nil {
|
||||
for _, certRecord := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certRecord.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certRecord.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certRecord.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certRecord.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// 查询证书详情
|
||||
// REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=125&api=11449&data=183&isNormal=1&vid=261
|
||||
queryCertDetailReq := &ctyunlvdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certRecord.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'lvdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'lvdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if queryCertListResp.ReturnObj == nil || len(queryCertListResp.ReturnObj.Results) < int(queryCertListPerPage) {
|
||||
if queryCertListResp.ReturnObj == nil {
|
||||
break
|
||||
} else {
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
for _, certItem := range queryCertListResp.ReturnObj.Results {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CN) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书扩展名称
|
||||
if !slices.Equal(certX509.DNSNames, certItem.SANs) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if !certX509.NotBefore.Equal(time.Unix(certItem.IssueTime, 0).UTC()) {
|
||||
continue
|
||||
} else if !certX509.NotAfter.Equal(time.Unix(certItem.ExpiresTime, 0).UTC()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
queryCertDetailReq := &ctyunlvdn.QueryCertDetailRequest{
|
||||
Id: lo.ToPtr(certItem.Id),
|
||||
}
|
||||
queryCertDetailResp, err := m.sdkClient.QueryCertDetail(queryCertDetailReq)
|
||||
m.logger.Debug("sdk request 'lvdn.QueryCertDetail'", slog.Any("request", queryCertDetailReq), slog.Any("response", queryCertDetailResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'lvdn.QueryCertDetail': %w", err)
|
||||
} else if queryCertDetailResp.ReturnObj != nil && queryCertDetailResp.ReturnObj.Result != nil {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, queryCertDetailResp.ReturnObj.Result.Certs) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", queryCertDetailResp.ReturnObj.Result.Id),
|
||||
CertName: queryCertDetailResp.ReturnObj.Result.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(queryCertListResp.ReturnObj.Results) < queryCertListPerPage {
|
||||
break
|
||||
}
|
||||
|
||||
queryCertListPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合天翼云命名规则)
|
||||
|
||||
@@ -69,8 +69,7 @@ func (m *SSLManagerProvider) SetLogger(logger *slog.Logger) {
|
||||
func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 查询已有证书,避免重复上传
|
||||
// REF: https://support.huaweicloud.com/api-elb/ListCertificates.html
|
||||
listCertificatesLimit := int32(2000)
|
||||
var listCertificatesMarker *string = nil
|
||||
listCertificatesMarker := (*string)(nil)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -79,9 +78,9 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
listCertificatesReq := &hcelbmodel.ListCertificatesRequest{
|
||||
Limit: lo.ToPtr(listCertificatesLimit),
|
||||
Marker: listCertificatesMarker,
|
||||
Type: &[]string{"server"},
|
||||
Limit: lo.ToPtr(int32(2000)),
|
||||
Type: lo.ToPtr([]string{"server"}),
|
||||
}
|
||||
listCertificatesResp, err := m.sdkClient.ListCertificates(listCertificatesReq)
|
||||
m.logger.Debug("sdk request 'elb.ListCertificates'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
|
||||
@@ -89,24 +88,26 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'elb.ListCertificates': %w", err)
|
||||
}
|
||||
|
||||
if listCertificatesResp.Certificates != nil {
|
||||
for _, certInfo := range *listCertificatesResp.Certificates {
|
||||
// 如果已存在相同证书,直接返回
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, certInfo.Certificate) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certInfo.Id,
|
||||
CertName: certInfo.Name,
|
||||
}, nil
|
||||
}
|
||||
if listCertificatesResp.Certificates == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, certItem := range *listCertificatesResp.Certificates {
|
||||
// 如果已存在相同证书,直接返回
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, certItem.Certificate) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.Id,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if listCertificatesResp.Certificates == nil || len(*listCertificatesResp.Certificates) < int(listCertificatesLimit) {
|
||||
if len(*listCertificatesResp.Certificates) == 0 || listCertificatesResp.PageInfo.NextMarker == nil {
|
||||
break
|
||||
} else {
|
||||
listCertificatesMarker = listCertificatesResp.PageInfo.NextMarker
|
||||
}
|
||||
|
||||
listCertificatesMarker = listCertificatesResp.PageInfo.NextMarker
|
||||
}
|
||||
|
||||
// 获取项目 ID
|
||||
|
||||
@@ -73,8 +73,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 查询已有证书,避免重复上传
|
||||
// REF: https://support.huaweicloud.com/api-ccm/ListCertificates.html
|
||||
// REF: https://support.huaweicloud.com/api-ccm/ExportCertificate_0.html
|
||||
listCertificatesLimit := int32(50)
|
||||
listCertificatesOffset := int32(0)
|
||||
listCertificatesLimit := 50
|
||||
listCertificatesOffset := 0
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -84,8 +84,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
listCertificatesReq := &hcscmmodel.ListCertificatesRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(m.config.EnterpriseProjectId),
|
||||
Limit: lo.ToPtr(listCertificatesLimit),
|
||||
Offset: lo.ToPtr(listCertificatesOffset),
|
||||
Limit: lo.ToPtr(int32(listCertificatesLimit)),
|
||||
Offset: lo.ToPtr(int32(listCertificatesOffset)),
|
||||
SortDir: lo.ToPtr("DESC"),
|
||||
SortKey: lo.ToPtr("certExpiredTime"),
|
||||
}
|
||||
@@ -95,51 +95,51 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'scm.ListCertificates': %w", err)
|
||||
}
|
||||
|
||||
if listCertificatesResp.Certificates != nil {
|
||||
for _, certDetail := range *listCertificatesResp.Certificates {
|
||||
// 先对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certDetail.Domain) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书有效期
|
||||
if certX509.NotAfter.Local().Format(time.DateTime) != strings.TrimSuffix(certDetail.ExpireTime, ".0") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
// 导出证书
|
||||
// REF: https://support.huaweicloud.com/api-ccm/ExportCertificate_0.html
|
||||
exportCertificateReq := &hcscmmodel.ExportCertificateRequest{
|
||||
CertificateId: certDetail.Id,
|
||||
}
|
||||
exportCertificateResp, err := m.sdkClient.ExportCertificate(exportCertificateReq)
|
||||
m.logger.Debug("sdk request 'scm.ExportCertificate'", slog.Any("request", exportCertificateReq), slog.Any("response", exportCertificateResp))
|
||||
if err != nil {
|
||||
if exportCertificateResp != nil && exportCertificateResp.HttpStatusCode == 404 {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'scm.ExportCertificate': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, lo.FromPtr(exportCertificateResp.Certificate)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certDetail.Id,
|
||||
CertName: certDetail.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if listCertificatesResp.Certificates == nil || len(*listCertificatesResp.Certificates) < int(listCertificatesLimit) {
|
||||
if listCertificatesResp.Certificates == nil {
|
||||
break
|
||||
} else {
|
||||
listCertificatesOffset += listCertificatesLimit
|
||||
}
|
||||
|
||||
for _, certItem := range *listCertificatesResp.Certificates {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.Domain) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if certX509.NotAfter.Local().Format(time.DateTime) != strings.TrimSuffix(certItem.ExpireTime, ".0") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
exportCertificateReq := &hcscmmodel.ExportCertificateRequest{
|
||||
CertificateId: certItem.Id,
|
||||
}
|
||||
exportCertificateResp, err := m.sdkClient.ExportCertificate(exportCertificateReq)
|
||||
m.logger.Debug("sdk request 'scm.ExportCertificate'", slog.Any("request", exportCertificateReq), slog.Any("response", exportCertificateResp))
|
||||
if err != nil {
|
||||
if exportCertificateResp != nil && exportCertificateResp.HttpStatusCode == 404 {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'scm.ExportCertificate': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, lo.FromPtr(exportCertificateResp.Certificate)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.Id,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(*listCertificatesResp.Certificates) < listCertificatesLimit {
|
||||
break
|
||||
}
|
||||
|
||||
listCertificatesOffset += listCertificatesLimit
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合华为云命名规则)
|
||||
|
||||
@@ -70,8 +70,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 查询已有证书,避免重复上传
|
||||
// REF: https://support.huaweicloud.com/api-waf/ListCertificates.html
|
||||
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
|
||||
listCertificatesPage := int32(1)
|
||||
listCertificatesPageSize := int32(100)
|
||||
listCertificatesPage := 1
|
||||
listCertificatesPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -81,8 +81,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
listCertificatesReq := &hcwafmodel.ListCertificatesRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(m.config.EnterpriseProjectId),
|
||||
Page: lo.ToPtr(listCertificatesPage),
|
||||
Pagesize: lo.ToPtr(listCertificatesPageSize),
|
||||
Page: lo.ToPtr(int32(listCertificatesPage)),
|
||||
Pagesize: lo.ToPtr(int32(listCertificatesPageSize)),
|
||||
}
|
||||
listCertificatesResp, err := m.sdkClient.ListCertificates(listCertificatesReq)
|
||||
m.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
|
||||
@@ -90,34 +90,36 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'waf.ListCertificates': %w", err)
|
||||
}
|
||||
|
||||
if listCertificatesResp.Items != nil {
|
||||
for _, certItem := range *listCertificatesResp.Items {
|
||||
showCertificateReq := &hcwafmodel.ShowCertificateRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(m.config.EnterpriseProjectId),
|
||||
CertificateId: certItem.Id,
|
||||
}
|
||||
showCertificateResp, err := m.sdkClient.ShowCertificate(showCertificateReq)
|
||||
m.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'waf.ShowCertificate': %w", err)
|
||||
}
|
||||
if listCertificatesResp.Items == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// 如果已存在相同证书,直接返回
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, lo.FromPtr(showCertificateResp.Content)) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.Id,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
for _, certItem := range *listCertificatesResp.Items {
|
||||
showCertificateReq := &hcwafmodel.ShowCertificateRequest{
|
||||
EnterpriseProjectId: lo.EmptyableToPtr(m.config.EnterpriseProjectId),
|
||||
CertificateId: certItem.Id,
|
||||
}
|
||||
showCertificateResp, err := m.sdkClient.ShowCertificate(showCertificateReq)
|
||||
m.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'waf.ShowCertificate': %w", err)
|
||||
}
|
||||
|
||||
// 如果已存在相同证书,直接返回
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, lo.FromPtr(showCertificateResp.Content)) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certItem.Id,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if listCertificatesResp.Items == nil || len(*listCertificatesResp.Items) < int(listCertificatesPageSize) {
|
||||
if len(*listCertificatesResp.Items) < listCertificatesPageSize {
|
||||
break
|
||||
} else {
|
||||
listCertificatesPage++
|
||||
}
|
||||
|
||||
listCertificatesPage++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合华为云命名规则)
|
||||
|
||||
@@ -92,36 +92,36 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeCerts': %w", err)
|
||||
}
|
||||
|
||||
for _, certDetail := range describeCertsResp.Result.CertListDetails {
|
||||
// 先对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certDetail.CommonName) {
|
||||
for _, certItem := range describeCertsResp.Result.CertListDetails {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, certItem.CommonName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书多域名
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certDetail.DnsNames, ",")) {
|
||||
// 对比证书多域名
|
||||
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certItem.DnsNames, ",")) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse(time.RFC3339, certDetail.StartTime)
|
||||
oldCertNotAfter, _ := time.Parse(time.RFC3339, certDetail.EndTime)
|
||||
// 对比证书有效期
|
||||
oldCertNotBefore, _ := time.Parse(time.RFC3339, certItem.StartTime)
|
||||
oldCertNotAfter, _ := time.Parse(time.RFC3339, certItem.EndTime)
|
||||
if !certX509.NotBefore.Equal(oldCertNotBefore) || !certX509.NotAfter.Equal(oldCertNotAfter) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比私钥摘要
|
||||
// 对比私钥 SHA-256 摘要
|
||||
newKeyDigest := sha256.Sum256([]byte(privkeyPEM))
|
||||
newKeyDigestHex := hex.EncodeToString(newKeyDigest[:])
|
||||
if !strings.EqualFold(newKeyDigestHex, certDetail.Digest) {
|
||||
if !strings.EqualFold(newKeyDigestHex, certItem.Digest) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certDetail.CertId,
|
||||
CertName: certDetail.CertName,
|
||||
CertId: certItem.CertId,
|
||||
CertName: certItem.CertName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询已有证书,避免重复上传
|
||||
getSslCertListMarker := ""
|
||||
getSslCertListLimit := int32(200)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -77,62 +76,60 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
default:
|
||||
}
|
||||
|
||||
getSslCertListResp, err := m.sdkClient.GetSslCertList(context.TODO(), getSslCertListMarker, getSslCertListLimit)
|
||||
getSslCertListResp, err := m.sdkClient.GetSslCertList(context.TODO(), getSslCertListMarker, 200)
|
||||
m.logger.Debug("sdk request 'sslcert.GetList'", slog.Any("request.marker", getSslCertListMarker), slog.Any("response", getSslCertListResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'sslcert.GetList': %w", err)
|
||||
}
|
||||
|
||||
if getSslCertListResp.Certs != nil {
|
||||
for _, sslCert := range getSslCertListResp.Certs {
|
||||
// 先对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, sslCert.CommonName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书多域名
|
||||
if !slices.Equal(certX509.DNSNames, sslCert.DnsNames) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书有效期
|
||||
if certX509.NotBefore.Unix() != sslCert.NotBefore || certX509.NotAfter.Unix() != sslCert.NotAfter {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书公钥算法
|
||||
switch certX509.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
if !strings.EqualFold(sslCert.Encrypt, "RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSA:
|
||||
if !strings.EqualFold(sslCert.Encrypt, "ECDSA") {
|
||||
continue
|
||||
}
|
||||
case x509.Ed25519:
|
||||
if !strings.EqualFold(sslCert.Encrypt, "ED25519") {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
// 未知算法,跳过
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: sslCert.CertID,
|
||||
CertName: sslCert.Name,
|
||||
}, nil
|
||||
for _, sslItem := range getSslCertListResp.Certs {
|
||||
// 对比证书通用名称
|
||||
if !strings.EqualFold(certX509.Subject.CommonName, sslItem.CommonName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书多域名
|
||||
if !slices.Equal(certX509.DNSNames, sslItem.DnsNames) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if certX509.NotBefore.Unix() != sslItem.NotBefore || certX509.NotAfter.Unix() != sslItem.NotAfter {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书公钥算法
|
||||
switch certX509.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
if !strings.EqualFold(sslItem.Encrypt, "RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSA:
|
||||
if !strings.EqualFold(sslItem.Encrypt, "ECDSA") {
|
||||
continue
|
||||
}
|
||||
case x509.Ed25519:
|
||||
if !strings.EqualFold(sslItem.Encrypt, "ED25519") {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
// 未知算法,跳过
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: sslItem.CertID,
|
||||
CertName: sslItem.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(getSslCertListResp.Certs) < int(getSslCertListLimit) || getSslCertListResp.Marker == "" {
|
||||
if len(getSslCertListResp.Certs) == 0 || getSslCertListResp.Marker == "" {
|
||||
break
|
||||
} else {
|
||||
getSslCertListMarker = getSslCertListResp.Marker
|
||||
}
|
||||
|
||||
getSslCertListMarker = getSslCertListResp.Marker
|
||||
}
|
||||
|
||||
// 上传新证书
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
rainyunsdk "github.com/certimate-go/certimate/pkg/sdk3rd/rainyun"
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type SSLManagerProviderConfig struct {
|
||||
@@ -52,7 +53,7 @@ func (m *SSLManagerProvider) SetLogger(logger *slog.Logger) {
|
||||
|
||||
func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 避免重复上传
|
||||
if res, err := m.findCertIfExists(ctx, certPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res != nil {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
@@ -72,16 +73,16 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
// 获取刚刚上传证书 ID
|
||||
if res, err := m.findCertIfExists(ctx, certPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res == nil {
|
||||
return nil, errors.New("no ssl certificate found, may be upload failed")
|
||||
return nil, errors.New("could not find ssl certificate, may be upload failed")
|
||||
} else {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
func (m *SSLManagerProvider) tryFindCert(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 解析证书内容
|
||||
certX509, err := xcert.ParseCertificateFromPEM(certPEM)
|
||||
if err != nil {
|
||||
@@ -91,8 +92,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
// 获取 SSL 证书列表
|
||||
// REF: https://apifox.com/apidoc/shared/a4595cc8-44c5-4678-a2a3-eed7738dab03/api-69943046
|
||||
// REF: https://apifox.com/apidoc/shared/a4595cc8-44c5-4678-a2a3-eed7738dab03/api-69943048
|
||||
sslCenterListPage := int32(1)
|
||||
sslCenterListPerPage := int32(100)
|
||||
sslCenterListPage := 1
|
||||
sslCenterListPerPage := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -104,8 +105,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
Filters: &rainyunsdk.SslCenterListFilters{
|
||||
Domain: &certX509.Subject.CommonName,
|
||||
},
|
||||
Page: &sslCenterListPage,
|
||||
PerPage: &sslCenterListPerPage,
|
||||
Page: lo.ToPtr(int32(sslCenterListPage)),
|
||||
PerPage: lo.ToPtr(int32(sslCenterListPerPage)),
|
||||
}
|
||||
sslCenterListResp, err := m.sdkClient.SslCenterList(sslCenterListReq)
|
||||
m.logger.Debug("sdk request 'sslcenter.List'", slog.Any("request", sslCenterListReq), slog.Any("response", sslCenterListResp))
|
||||
@@ -113,40 +114,42 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'sslcenter.List': %w", err)
|
||||
}
|
||||
|
||||
if sslCenterListResp.Data != nil && sslCenterListResp.Data.Records != nil {
|
||||
for _, sslRecord := range sslCenterListResp.Data.Records {
|
||||
// 先对比证书的多域名
|
||||
if sslRecord.Domain != strings.Join(certX509.DNSNames, ", ") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书的有效期
|
||||
if sslRecord.StartDate != certX509.NotBefore.Unix() || sslRecord.ExpireDate != certX509.NotAfter.Unix() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 最后对比证书内容
|
||||
sslCenterGetResp, err := m.sdkClient.SslCenterGet(sslRecord.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'sslcenter.Get': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, sslCenterGetResp.Data.Cert) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslRecord.ID),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if sslCenterListResp.Data == nil || len(sslCenterListResp.Data.Records) < int(sslCenterListPerPage) {
|
||||
if sslCenterListResp.Data == nil {
|
||||
break
|
||||
} else {
|
||||
sslCenterListPage++
|
||||
}
|
||||
|
||||
for _, sslItem := range sslCenterListResp.Data.Records {
|
||||
// 对比证书的多域名
|
||||
if sslItem.Domain != strings.Join(certX509.DNSNames, ", ") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书的有效期
|
||||
if sslItem.StartDate != certX509.NotBefore.Unix() || sslItem.ExpireDate != certX509.NotAfter.Unix() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
sslCenterGetResp, err := m.sdkClient.SslCenterGet(sslItem.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'sslcenter.Get': %w", err)
|
||||
} else {
|
||||
if !xcert.EqualCertificatesFromPEM(certPEM, sslCenterGetResp.Data.Cert) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", sslItem.ID),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(sslCenterListResp.Data.Records) < sslCenterListPerPage {
|
||||
break
|
||||
}
|
||||
|
||||
sslCenterListPage++
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -86,10 +86,10 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
m.logger.Debug("sdk request 'ussl.UploadNormalCertificate'", slog.Any("request", uploadNormalCertificateReq), slog.Any("response", uploadNormalCertificateResp))
|
||||
if err != nil {
|
||||
if uploadNormalCertificateResp != nil && uploadNormalCertificateResp.GetRetCode() == 80035 {
|
||||
if res, err := m.findCertIfExists(ctx, certPEM); err != nil {
|
||||
if res, err := m.tryFindCert(ctx, certPEM); err != nil {
|
||||
return nil, err
|
||||
} else if res == nil {
|
||||
return nil, errors.New("ucloud ssl: no certificate found")
|
||||
return nil, errors.New("could not find ssl certificate, may be upload failed")
|
||||
} else {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return res, nil
|
||||
@@ -108,7 +108,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
func (m *SSLManagerProvider) tryFindCert(ctx context.Context, certPEM string) (*core.SSLManageUploadResult, error) {
|
||||
// 解析证书内容
|
||||
certX509, err := xcert.ParseCertificateFromPEM(certPEM)
|
||||
if err != nil {
|
||||
@@ -118,8 +118,8 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
// 查询用户证书列表
|
||||
// REF: https://docs.ucloud.cn/api/usslcertificate-api/get_certificate_list
|
||||
// REF: https://docs.ucloud.cn/api/usslcertificate-api/download_certificate
|
||||
getCertificateListPage := int(1)
|
||||
getCertificateListLimit := int(1000)
|
||||
getCertificateListPage := 1
|
||||
getCertificateListLimit := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -142,90 +142,88 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ussl.GetCertificateList': %w", err)
|
||||
}
|
||||
|
||||
if getCertificateListResp.CertificateList != nil {
|
||||
for _, certItem := range getCertificateListResp.CertificateList {
|
||||
// 优刻得未提供可唯一标识证书的字段,只能通过多个字段尝试对比来判断是否为同一证书
|
||||
// 先分别对比证书的多域名、品牌、有效期,再对比签名算法
|
||||
for _, certItem := range getCertificateListResp.CertificateList {
|
||||
// 优刻得未提供可唯一标识证书的字段,只能通过多个字段尝试对比来判断是否为同一证书
|
||||
// 先分别对比证书的多域名、品牌、有效期,再对比签名算法
|
||||
|
||||
if len(certX509.DNSNames) == 0 || certItem.Domains != strings.Join(certX509.DNSNames, ",") {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(certX509.Issuer.Organization) == 0 || certItem.Brand != certX509.Issuer.Organization[0] {
|
||||
continue
|
||||
}
|
||||
|
||||
if int64(certItem.NotBefore) != certX509.NotBefore.UnixMilli() || int64(certItem.NotAfter) != certX509.NotAfter.UnixMilli() {
|
||||
continue
|
||||
}
|
||||
|
||||
getCertificateDetailInfoReq := m.sdkClient.NewGetCertificateDetailInfoRequest()
|
||||
getCertificateDetailInfoReq.CertificateID = ucloud.Int(certItem.CertificateID)
|
||||
if m.config.ProjectId != "" {
|
||||
getCertificateDetailInfoReq.ProjectId = ucloud.String(m.config.ProjectId)
|
||||
}
|
||||
getCertificateDetailInfoResp, err := m.sdkClient.GetCertificateDetailInfo(getCertificateDetailInfoReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ussl.GetCertificateDetailInfo': %w", err)
|
||||
}
|
||||
|
||||
switch certX509.SignatureAlgorithm {
|
||||
case x509.SHA256WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA256-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA384WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA384-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA512WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA512-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA256WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA256-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA384WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA384-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA512WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA512-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA256:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA256") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA384:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA384") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA512:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA512") {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
// 未知签名算法,跳过
|
||||
continue
|
||||
}
|
||||
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", certItem.CertificateID),
|
||||
CertName: certItem.Name,
|
||||
ExtendedData: map[string]any{
|
||||
"ResourceId": certItem.CertificateSN,
|
||||
},
|
||||
}, nil
|
||||
if len(certX509.DNSNames) == 0 || certItem.Domains != strings.Join(certX509.DNSNames, ",") {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(certX509.Issuer.Organization) == 0 || certItem.Brand != certX509.Issuer.Organization[0] {
|
||||
continue
|
||||
}
|
||||
|
||||
if int64(certItem.NotBefore) != certX509.NotBefore.UnixMilli() || int64(certItem.NotAfter) != certX509.NotAfter.UnixMilli() {
|
||||
continue
|
||||
}
|
||||
|
||||
getCertificateDetailInfoReq := m.sdkClient.NewGetCertificateDetailInfoRequest()
|
||||
getCertificateDetailInfoReq.CertificateID = ucloud.Int(certItem.CertificateID)
|
||||
if m.config.ProjectId != "" {
|
||||
getCertificateDetailInfoReq.ProjectId = ucloud.String(m.config.ProjectId)
|
||||
}
|
||||
getCertificateDetailInfoResp, err := m.sdkClient.GetCertificateDetailInfo(getCertificateDetailInfoReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'ussl.GetCertificateDetailInfo': %w", err)
|
||||
}
|
||||
|
||||
switch certX509.SignatureAlgorithm {
|
||||
case x509.SHA256WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA256-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA384WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA384-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA512WithRSA:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA512-RSA") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA256WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA256-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA384WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA384-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.SHA512WithRSAPSS:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "SHA512-RSAPSS") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA256:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA256") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA384:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA384") {
|
||||
continue
|
||||
}
|
||||
case x509.ECDSAWithSHA512:
|
||||
if !strings.EqualFold(getCertificateDetailInfoResp.CertificateInfo.Algorithm, "ECDSA-SHA512") {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
// 未知签名算法,跳过
|
||||
continue
|
||||
}
|
||||
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: fmt.Sprintf("%d", certItem.CertificateID),
|
||||
CertName: certItem.Name,
|
||||
ExtendedData: map[string]any{
|
||||
"ResourceId": certItem.CertificateSN,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if getCertificateListResp.CertificateList == nil || len(getCertificateListResp.CertificateList) < int(getCertificateListLimit) {
|
||||
if len(getCertificateListResp.CertificateList) < getCertificateListLimit {
|
||||
break
|
||||
} else {
|
||||
getCertificateListPage++
|
||||
}
|
||||
|
||||
getCertificateListPage++
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -69,14 +69,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
|
||||
// 查询证书列表,避免重复上传
|
||||
// REF: https://www.volcengine.com/docs/6454/125709
|
||||
listCertInfoPageNum := int32(1)
|
||||
listCertInfoPageSize := int32(100)
|
||||
listCertInfoTotal := 0
|
||||
listCertInfoReq := &vecdn.ListCertInfoInput{
|
||||
Source: ve.String("volc_cert_center"),
|
||||
PageNum: ve.Int32(listCertInfoPageNum),
|
||||
PageSize: ve.Int32(listCertInfoPageSize),
|
||||
}
|
||||
listCertInfoPageNum := 1
|
||||
listCertInfoPageSize := 100
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -84,40 +78,43 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
default:
|
||||
}
|
||||
|
||||
listCertInfoReq := &vecdn.ListCertInfoInput{
|
||||
Source: ve.String("volc_cert_center"),
|
||||
PageNum: ve.Int32(int32(listCertInfoPageNum)),
|
||||
PageSize: ve.Int32(int32(listCertInfoPageSize)),
|
||||
}
|
||||
listCertInfoResp, err := m.sdkClient.ListCertInfo(listCertInfoReq)
|
||||
m.logger.Debug("sdk request 'cdn.ListCertInfo'", slog.Any("request", listCertInfoReq), slog.Any("response", listCertInfoResp))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'cdn.ListCertInfo': %w", err)
|
||||
}
|
||||
|
||||
if listCertInfoResp.CertInfo != nil {
|
||||
for _, certInfo := range listCertInfoResp.CertInfo {
|
||||
fingerprintSha1 := sha1.Sum(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), ve.StringValue(certInfo.CertFingerprint.Sha1)) {
|
||||
continue
|
||||
}
|
||||
|
||||
fingerprintSha256 := sha256.Sum256(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), ve.StringValue(certInfo.CertFingerprint.Sha256)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: ve.StringValue(certInfo.CertId),
|
||||
CertName: ve.StringValue(certInfo.Desc),
|
||||
}, nil
|
||||
for _, certItem := range listCertInfoResp.CertInfo {
|
||||
// 对比证书 SHA-1 摘要
|
||||
fingerprintSha1 := sha1.Sum(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha1[:]), ve.StringValue(certItem.CertFingerprint.Sha1)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书 SHA-256 摘要
|
||||
fingerprintSha256 := sha256.Sum256(certX509.Raw)
|
||||
if !strings.EqualFold(hex.EncodeToString(fingerprintSha256[:]), ve.StringValue(certItem.CertFingerprint.Sha256)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: ve.StringValue(certItem.CertId),
|
||||
CertName: ve.StringValue(certItem.Desc),
|
||||
}, nil
|
||||
}
|
||||
|
||||
listCertInfoLen := len(listCertInfoResp.CertInfo)
|
||||
if listCertInfoLen < int(listCertInfoPageSize) || int(ve.Int64Value(listCertInfoResp.Total)) <= listCertInfoTotal+listCertInfoLen {
|
||||
if len(listCertInfoResp.CertInfo) < listCertInfoPageSize {
|
||||
break
|
||||
} else {
|
||||
listCertInfoPageNum++
|
||||
listCertInfoTotal += listCertInfoLen
|
||||
}
|
||||
|
||||
listCertInfoPageNum++
|
||||
}
|
||||
|
||||
// 生成新证书名(需符合火山引擎命名规则)
|
||||
|
||||
@@ -64,11 +64,11 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
return nil, fmt.Errorf("failed to execute sdk request 'live.ListCertV2': %w", err)
|
||||
}
|
||||
if listCertResp.Result.CertList != nil {
|
||||
for _, certInfo := range listCertResp.Result.CertList {
|
||||
for _, certItem := range listCertResp.Result.CertList {
|
||||
// 查询证书详细信息
|
||||
// REF: https://www.volcengine.com/docs/6469/1186278#%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E8%AF%A6%E6%83%85
|
||||
describeCertDetailSecretReq := &velive.DescribeCertDetailSecretV2Body{
|
||||
ChainID: ve.String(certInfo.ChainID),
|
||||
ChainID: ve.String(certItem.ChainID),
|
||||
}
|
||||
describeCertDetailSecretResp, err := m.sdkClient.DescribeCertDetailSecretV2(ctx, describeCertDetailSecretReq)
|
||||
m.logger.Debug("sdk request 'live.DescribeCertDetailSecretV2'", slog.Any("request", describeCertDetailSecretReq), slog.Any("response", describeCertDetailSecretResp))
|
||||
@@ -81,8 +81,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
if xcert.EqualCertificatesFromPEM(certPEM, oldCertPEM) {
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certInfo.ChainID,
|
||||
CertName: certInfo.CertName,
|
||||
CertId: certItem.ChainID,
|
||||
CertName: certItem.CertName,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,16 +72,16 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
}
|
||||
|
||||
if listCertificatesResp.Certificates != nil {
|
||||
for _, certRecord := range listCertificatesResp.Certificates {
|
||||
for _, certItem := range listCertificatesResp.Certificates {
|
||||
// 对比证书序列号
|
||||
if !strings.EqualFold(certX509.SerialNumber.Text(16), certRecord.Serial) {
|
||||
if !strings.EqualFold(certX509.SerialNumber.Text(16), certItem.Serial) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 再对比证书有效期
|
||||
cstzone := time.FixedZone("CST", 8*60*60)
|
||||
oldCertNotBefore, _ := time.ParseInLocation(time.DateTime, certRecord.ValidityFrom, cstzone)
|
||||
oldCertNotAfter, _ := time.ParseInLocation(time.DateTime, certRecord.ValidityTo, cstzone)
|
||||
// 对比证书有效期
|
||||
timezoneOfCST := time.FixedZone("CST", 8*60*60)
|
||||
oldCertNotBefore, _ := time.ParseInLocation(time.DateTime, certItem.ValidityFrom, timezoneOfCST)
|
||||
oldCertNotAfter, _ := time.ParseInLocation(time.DateTime, certItem.ValidityTo, timezoneOfCST)
|
||||
if !certX509.NotBefore.Equal(oldCertNotBefore) || !certX509.NotAfter.Equal(oldCertNotAfter) {
|
||||
continue
|
||||
}
|
||||
@@ -89,8 +89,8 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey
|
||||
// 如果以上信息都一致,则视为已存在相同证书,直接返回
|
||||
m.logger.Info("ssl certificate already exists")
|
||||
return &core.SSLManageUploadResult{
|
||||
CertId: certRecord.CertificateId,
|
||||
CertName: certRecord.Name,
|
||||
CertId: certItem.CertificateId,
|
||||
CertName: certItem.Name,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package baishan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type GetDomainListRequest struct {
|
||||
PageNumber *int32 `json:"page_number,omitempty"`
|
||||
PageSize *int32 `json:"page_size,omitempty"`
|
||||
DomainStatus *string `json:"domain_status,omitempty"`
|
||||
}
|
||||
|
||||
type GetDomainListResponse struct {
|
||||
apiResponseBase
|
||||
|
||||
Data []*struct {
|
||||
List []*DomainRecord `json:"list"`
|
||||
PageNumber json.Number `json:"page_number"`
|
||||
PageSize json.Number `json:"page_size"`
|
||||
TotalNumber json.Number `json:"total_number"`
|
||||
} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Client) GetDomainList(req *GetDomainListRequest) (*GetDomainListResponse, error) {
|
||||
return c.GetDomainListWithContext(context.Background(), req)
|
||||
}
|
||||
|
||||
func (c *Client) GetDomainListWithContext(ctx context.Context, req *GetDomainListRequest) (*GetDomainListResponse, error) {
|
||||
httpreq, err := c.newRequest(http.MethodGet, "/v2/domain/list")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
if req.PageNumber != nil {
|
||||
httpreq.SetQueryParam("page_number", fmt.Sprintf("%d", *req.PageNumber))
|
||||
}
|
||||
if req.PageSize != nil {
|
||||
httpreq.SetQueryParam("page_number", fmt.Sprintf("%d", *req.PageSize))
|
||||
}
|
||||
if req.DomainStatus != nil {
|
||||
httpreq.SetQueryParam("domain_status", *req.DomainStatus)
|
||||
}
|
||||
|
||||
httpreq.SetContext(ctx)
|
||||
}
|
||||
|
||||
result := &GetDomainListResponse{}
|
||||
if _, err := c.doRequestWithResult(httpreq, result); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -30,6 +30,17 @@ func (r *apiResponseBase) GetMessage() string {
|
||||
|
||||
var _ apiResponse = (*apiResponseBase)(nil)
|
||||
|
||||
type DomainRecord struct {
|
||||
Id string `json:"id"`
|
||||
Domain string `json:"domain"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Cname string `json:"cname"`
|
||||
Area string `json:"area"`
|
||||
CreateTime string `json:"create_time"`
|
||||
UpdateTime string `json:"update_time"`
|
||||
}
|
||||
|
||||
type DomainCertificate struct {
|
||||
CertId json.Number `json:"cert_id"`
|
||||
Name string `json:"name"`
|
||||
|
||||
+58
-11
@@ -1,5 +1,5 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input } from "antd";
|
||||
import { Form, Input, Radio } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -7,6 +7,8 @@ import { validDomainName } from "@/utils/validators";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const DOMAIN_MATCH_PATTERN_EXACT = "exact" as const;
|
||||
|
||||
const BizDeployNodeConfigFieldsProviderBaishanCDN = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
@@ -15,10 +17,35 @@ const BizDeployNodeConfigFieldsProviderBaishanCDN = () => {
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const formInst = Form.useFormInstance();
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
const fieldDomainMatchPattern = Form.useWatch([parentNamePath, "domainMatchPattern"], { form: formInst, preserve: true });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domainMatchPattern"]}
|
||||
initialValue={initialValues.domainMatchPattern}
|
||||
label={t("workflow_node.deploy.form.shared_domain_match_pattern.label")}
|
||||
extra={
|
||||
fieldDomainMatchPattern === DOMAIN_MATCH_PATTERN_EXACT ? (
|
||||
<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.shared_domain_match_pattern.help_wildcard") }}></span>
|
||||
) : (
|
||||
void 0
|
||||
)
|
||||
}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Radio.Group
|
||||
options={[DOMAIN_MATCH_PATTERN_EXACT].map((s) => ({
|
||||
key: s,
|
||||
label: t(`workflow_node.deploy.form.shared_domain_match_pattern.option.${s}.label`),
|
||||
value: s,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
@@ -44,6 +71,7 @@ const BizDeployNodeConfigFieldsProviderBaishanCDN = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domain: "",
|
||||
};
|
||||
};
|
||||
@@ -51,16 +79,35 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
|
||||
certificateId: z
|
||||
.union([z.string(), z.number().int()])
|
||||
.nullish()
|
||||
.refine((v) => {
|
||||
if (!v) return true;
|
||||
return /^\d+$/.test(v + "") && +v > 0;
|
||||
}, t("workflow_node.deploy.form.baishan_cdn_certificate_id.placeholder")),
|
||||
});
|
||||
return z
|
||||
.object({
|
||||
domainMatchPattern: z.string().nonempty(t("workflow_node.deploy.form.shared_domain_match_pattern.placeholder")).default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domain: z.string().nullish(),
|
||||
certificateId: z
|
||||
.union([z.string(), z.number().int()])
|
||||
.nullish()
|
||||
.refine((v) => {
|
||||
if (!v) return true;
|
||||
return /^\d+$/.test(v + "") && +v > 0;
|
||||
}, t("workflow_node.deploy.form.baishan_cdn_certificate_id.placeholder")),
|
||||
})
|
||||
.superRefine((values, ctx) => {
|
||||
if (values.domainMatchPattern) {
|
||||
switch (values.domainMatchPattern) {
|
||||
case DOMAIN_MATCH_PATTERN_EXACT:
|
||||
{
|
||||
if (!validDomainName(values.domain!, { allowWildcard: true })) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: t("common.errmsg.domain_invalid"),
|
||||
path: ["domain"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(BizDeployNodeConfigFieldsProviderBaishanCDN, {
|
||||
|
||||
+56
-9
@@ -1,5 +1,5 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form } from "antd";
|
||||
import { Form, Radio } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -10,6 +10,8 @@ import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const MULTIPLE_INPUT_SEPARATOR = ";";
|
||||
|
||||
const DOMAIN_MATCH_PATTERN_EXACT = "exact" as const;
|
||||
|
||||
const BizDeployNodeConfigFieldsProviderWangsuCDN = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
@@ -18,10 +20,35 @@ const BizDeployNodeConfigFieldsProviderWangsuCDN = () => {
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const formInst = Form.useFormInstance();
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
const fieldDomainMatchPattern = Form.useWatch([parentNamePath, "domainMatchPattern"], { form: formInst, preserve: true });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domainMatchPattern"]}
|
||||
initialValue={initialValues.domainMatchPattern}
|
||||
label={t("workflow_node.deploy.form.shared_domain_match_pattern.label")}
|
||||
extra={
|
||||
fieldDomainMatchPattern === DOMAIN_MATCH_PATTERN_EXACT ? (
|
||||
<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.shared_domain_match_pattern.help_wildcard") }}></span>
|
||||
) : (
|
||||
void 0
|
||||
)
|
||||
}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Radio.Group
|
||||
options={[DOMAIN_MATCH_PATTERN_EXACT].map((s) => ({
|
||||
key: s,
|
||||
label: t(`workflow_node.deploy.form.shared_domain_match_pattern.option.${s}.label`),
|
||||
value: s,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domains"]}
|
||||
initialValue={initialValues.domains}
|
||||
@@ -43,6 +70,7 @@ const BizDeployNodeConfigFieldsProviderWangsuCDN = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domains: "",
|
||||
};
|
||||
};
|
||||
@@ -50,14 +78,33 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
domains: z.string().refine((v) => {
|
||||
if (!v) return false;
|
||||
return String(v)
|
||||
.split(MULTIPLE_INPUT_SEPARATOR)
|
||||
.every((e) => validDomainName(e, { allowWildcard: true }));
|
||||
}, t("workflow_node.deploy.form.wangsu_cdn_domains.placeholder")),
|
||||
});
|
||||
return z
|
||||
.object({
|
||||
domainMatchPattern: z.string().nonempty(t("workflow_node.deploy.form.shared_domain_match_pattern.placeholder")).default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domains: z.string().nullish(),
|
||||
})
|
||||
.superRefine((values, ctx) => {
|
||||
if (values.domainMatchPattern) {
|
||||
switch (values.domainMatchPattern) {
|
||||
case DOMAIN_MATCH_PATTERN_EXACT:
|
||||
{
|
||||
const v =
|
||||
values.domains &&
|
||||
String(values.domains)
|
||||
.split(MULTIPLE_INPUT_SEPARATOR)
|
||||
.every((e) => validDomainName(e, { allowWildcard: true }));
|
||||
if (!v) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: t("common.errmsg.domain_invalid"),
|
||||
path: ["domains"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(BizDeployNodeConfigFieldsProviderWangsuCDN, {
|
||||
|
||||
+54
-7
@@ -1,5 +1,5 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input, Select } from "antd";
|
||||
import { Form, Input, Radio, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -10,6 +10,8 @@ import { useFormNestedFieldsContext } from "./_context";
|
||||
const ENVIRONMENT_PRODUCTION = "production" as const;
|
||||
const ENVIRONMENT_STAGING = "stating" as const;
|
||||
|
||||
const DOMAIN_MATCH_PATTERN_EXACT = "exact" as const;
|
||||
|
||||
const BizDeployNodeConfigFieldsProviderWangsuCDNPro = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
@@ -18,8 +20,11 @@ const BizDeployNodeConfigFieldsProviderWangsuCDNPro = () => {
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const formInst = Form.useFormInstance();
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
const fieldDomainMatchPattern = Form.useWatch([parentNamePath, "domainMatchPattern"], { form: formInst, preserve: true });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
@@ -38,6 +43,28 @@ const BizDeployNodeConfigFieldsProviderWangsuCDNPro = () => {
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domainMatchPattern"]}
|
||||
initialValue={initialValues.domainMatchPattern}
|
||||
label={t("workflow_node.deploy.form.shared_domain_match_pattern.label")}
|
||||
extra={
|
||||
fieldDomainMatchPattern === DOMAIN_MATCH_PATTERN_EXACT ? (
|
||||
<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.shared_domain_match_pattern.help_wildcard") }}></span>
|
||||
) : (
|
||||
void 0
|
||||
)
|
||||
}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Radio.Group
|
||||
options={[DOMAIN_MATCH_PATTERN_EXACT].map((s) => ({
|
||||
key: s,
|
||||
label: t(`workflow_node.deploy.form.shared_domain_match_pattern.option.${s}.label`),
|
||||
value: s,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
@@ -74,6 +101,7 @@ const BizDeployNodeConfigFieldsProviderWangsuCDNPro = () => {
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
environment: ENVIRONMENT_PRODUCTION,
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domain: "",
|
||||
};
|
||||
};
|
||||
@@ -81,12 +109,31 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
environment: z.literal([ENVIRONMENT_PRODUCTION, ENVIRONMENT_STAGING], t("workflow_node.deploy.form.wangsu_cdnpro_environment.placeholder")),
|
||||
domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
|
||||
certificateId: z.string().nullish(),
|
||||
webhookId: z.string().nullish(),
|
||||
});
|
||||
return z
|
||||
.object({
|
||||
environment: z.literal([ENVIRONMENT_PRODUCTION, ENVIRONMENT_STAGING], t("workflow_node.deploy.form.wangsu_cdnpro_environment.placeholder")),
|
||||
domainMatchPattern: z.string().nonempty(t("workflow_node.deploy.form.shared_domain_match_pattern.placeholder")).default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domain: z.string().nullish(),
|
||||
certificateId: z.string().nullish(),
|
||||
webhookId: z.string().nullish(),
|
||||
})
|
||||
.superRefine((values, ctx) => {
|
||||
if (values.domainMatchPattern) {
|
||||
switch (values.domainMatchPattern) {
|
||||
case DOMAIN_MATCH_PATTERN_EXACT:
|
||||
{
|
||||
if (!validDomainName(values.domain!, { allowWildcard: true })) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: t("common.errmsg.domain_invalid"),
|
||||
path: ["domain"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(BizDeployNodeConfigFieldsProviderWangsuCDNPro, {
|
||||
|
||||
Reference in New Issue
Block a user