diff --git a/internal/certdeploy/deployers/sp_ctcccloud_icdn.go b/internal/certdeploy/deployers/sp_ctcccloud_icdn.go index bce31b39d..44b160488 100644 --- a/internal/certdeploy/deployers/sp_ctcccloud_icdn.go +++ b/internal/certdeploy/deployers/sp_ctcccloud_icdn.go @@ -17,9 +17,10 @@ func init() { } provider, err := ctcccloudicdn.NewSSLDeployerProvider(&ctcccloudicdn.SSLDeployerProviderConfig{ - AccessKeyId: credentials.AccessKeyId, - SecretAccessKey: credentials.SecretAccessKey, - Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"), + AccessKeyId: credentials.AccessKeyId, + SecretAccessKey: credentials.SecretAccessKey, + DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"), + Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"), }) return provider, err }) diff --git a/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go b/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go index 65836437e..96619421f 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go +++ b/pkg/core/ssl-deployer/providers/aliyun-alb/aliyun_alb.go @@ -320,7 +320,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 // REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getusercertificatedetail certificateIsAlreadyAssociated := false diff --git a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go index 486596bf3..0d3a3c158 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go +++ b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw.go @@ -146,7 +146,7 @@ func (d *SSLDeployerProvider) deployToCloudNative(ctx context.Context, certPEM s return errors.New("config `domain` is required") } - // 遍历查询域名列表,获取域名 ID + // 查询域名列表,获取域名 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) diff --git a/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go b/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go index b8bbf1a51..d5bc06697 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go +++ b/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go @@ -185,7 +185,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-describeuserdomains describeUserDomainsPageNumber := int32(1) describeUserDomainsPageSize := int32(500) diff --git a/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go b/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go index a1c541736..f703619d5 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go +++ b/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go @@ -185,7 +185,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-describedcdnuserdomains describeUserDomainsPageNumber := int32(1) describeUserDomainsPageSize := int32(500) diff --git a/pkg/core/ssl-deployer/providers/baiducloud-cdn/baiducloud_cdn.go b/pkg/core/ssl-deployer/providers/baiducloud-cdn/baiducloud_cdn.go index f360e2e77..75100ecac 100644 --- a/pkg/core/ssl-deployer/providers/baiducloud-cdn/baiducloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/baiducloud-cdn/baiducloud_cdn.go @@ -151,7 +151,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://cloud.baidu.com/doc/CDN/s/sjwvyewt1 listDomainsMarker := "" for { diff --git a/pkg/core/ssl-deployer/providers/baotapanelgo-site/baotapanelgo_site.go b/pkg/core/ssl-deployer/providers/baotapanelgo-site/baotapanelgo_site.go index 59a543d76..9b925b0a6 100644 --- a/pkg/core/ssl-deployer/providers/baotapanelgo-site/baotapanelgo_site.go +++ b/pkg/core/ssl-deployer/providers/baotapanelgo-site/baotapanelgo_site.go @@ -74,7 +74,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return nil, fmt.Errorf("failed to execute sdk request 'bt.PanelGetConfig': %w", err) } - // 遍历查询网站列表,获取网站 ID + // 查询网站列表,获取网站 ID var siteId int32 datalistGetDataListPage := int32(1) datalistGetDataListLimit := int32(10) diff --git a/pkg/core/ssl-deployer/providers/baotawaf-site/baotawaf_site.go b/pkg/core/ssl-deployer/providers/baotawaf-site/baotawaf_site.go index d1408d9e1..1ea80534e 100644 --- a/pkg/core/ssl-deployer/providers/baotawaf-site/baotawaf_site.go +++ b/pkg/core/ssl-deployer/providers/baotawaf-site/baotawaf_site.go @@ -68,7 +68,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke d.config.SitePort = 443 } - // 遍历获取网站列表,获取网站 ID + // 查询网站列表,获取网站 ID // REF: https://support.huaweicloud.com/api-waf/ListHost.html siteId := "" getSitListPage := int32(1) diff --git a/pkg/core/ssl-deployer/providers/byteplus-cdn/byteplus_cdn.go b/pkg/core/ssl-deployer/providers/byteplus-cdn/byteplus_cdn.go index 8a7180a21..1ace82c0e 100644 --- a/pkg/core/ssl-deployer/providers/byteplus-cdn/byteplus_cdn.go +++ b/pkg/core/ssl-deployer/providers/byteplus-cdn/byteplus_cdn.go @@ -153,7 +153,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, wildcardDomain string) ([]string, error) { domains := make([]string, 0) - // 遍历获取加速域名列表,获取匹配的域名 + // 查询加速域名列表,获取匹配的域名 // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/ListCdnDomains_en-us listCdnDomainsPageNum := int64(1) listCdnDomainsPageSize := int64(100) diff --git a/pkg/core/ssl-deployer/providers/ctcccloud-ao/ctcccloud_ao.go b/pkg/core/ssl-deployer/providers/ctcccloud-ao/ctcccloud_ao.go index da7c71a28..591a63576 100644 --- a/pkg/core/ssl-deployer/providers/ctcccloud-ao/ctcccloud_ao.go +++ b/pkg/core/ssl-deployer/providers/ctcccloud-ao/ctcccloud_ao.go @@ -169,7 +169,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13816&data=174&isNormal=1&vid=167 queryDomainsPage := int32(1) queryDomainsPageSize := int32(100) diff --git a/pkg/core/ssl-deployer/providers/ctcccloud-cdn/ctcccloud_cdn.go b/pkg/core/ssl-deployer/providers/ctcccloud-cdn/ctcccloud_cdn.go index f8a20f630..b21777b15 100644 --- a/pkg/core/ssl-deployer/providers/ctcccloud-cdn/ctcccloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/ctcccloud-cdn/ctcccloud_cdn.go @@ -168,8 +168,8 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 - // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=113&api=13816&data=174&isNormal=1&vid=167 + // 查询域名列表 + // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=108&api=11307&data=161&isNormal=1&vid=154 queryDomainListPage := int32(1) queryDomainListPageSize := int32(100) for { diff --git a/pkg/core/ssl-deployer/providers/ctcccloud-icdn/consts.go b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/consts.go new file mode 100644 index 000000000..0ccc5ad71 --- /dev/null +++ b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/consts.go @@ -0,0 +1,10 @@ +package ctcccloudicdn + +const ( + // 匹配模式:精确匹配。 + DOMAIN_MATCH_PATTERN_EXACT = "exact" + // 匹配模式:通配符匹配。 + DOMAIN_MATCH_PATTERN_WILDCARD = "wildcard" + // 匹配模式:证书 SAN 匹配。 + DOMAIN_MATCH_PATTERN_CERTSAN = "certsan" +) diff --git a/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn.go b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn.go index ad589ce08..7a3a2c525 100644 --- a/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn.go +++ b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn.go @@ -5,12 +5,15 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/samber/lo" "github.com/certimate-go/certimate/pkg/core" sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/ctcccloud-icdn" ctyunicdn "github.com/certimate-go/certimate/pkg/sdk3rd/ctyun/icdn" + xcert "github.com/certimate-go/certimate/pkg/utils/cert" + xcerthostname "github.com/certimate-go/certimate/pkg/utils/cert/hostname" ) type SSLDeployerProviderConfig struct { @@ -18,6 +21,9 @@ type SSLDeployerProviderConfig struct { AccessKeyId string `json:"accessKeyId"` // 天翼云 SecretAccessKey。 SecretAccessKey string `json:"secretAccessKey"` + // 域名匹配模式。 + // 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。 + DomainMatchPattern string `json:"domainMatchPattern,omitempty"` // 加速域名(支持泛域名)。 Domain string `json:"domain"` } @@ -66,10 +72,6 @@ func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) { } func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) { - if d.config.Domain == "" { - return nil, errors.New("config `domain` is required") - } - // 上传证书 upres, err := d.sslManager.Upload(ctx, certPEM, privkeyPEM) if err != nil { @@ -78,33 +80,165 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) } - // 查询域名配置信息 - // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10849&data=173&isNormal=1&vid=166 - queryDomainDetailReq := &ctyunicdn.QueryDomainDetailRequest{ - Domain: lo.ToPtr(d.config.Domain), - } - queryDomainDetailResp, err := d.sdkClient.QueryDomainDetail(queryDomainDetailReq) - d.logger.Debug("sdk request 'icdn.QueryDomainDetail'", slog.Any("request", queryDomainDetailReq), slog.Any("response", queryDomainDetailResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'icdn.QueryDomainDetail': %w", err) + // 获取待部署的域名列表 + var domains []string + switch d.config.DomainMatchPattern { + case "", DOMAIN_MATCH_PATTERN_EXACT: + { + if d.config.Domain == "" { + return nil, errors.New("config `domain` is required") + } + + domains = []string{d.config.Domain} + } + + case DOMAIN_MATCH_PATTERN_WILDCARD: + { + if d.config.Domain == "" { + return nil, errors.New("config `domain` is required") + } + + if strings.HasPrefix(d.config.Domain, "*.") { + domainCandidates, err := d.getAllDomains(ctx) + if err != nil { + return nil, err + } + + domains = lo.Filter(domainCandidates, func(domain string, _ int) bool { + return xcerthostname.IsMatch(d.config.Domain, domain) + }) + if len(domains) == 0 { + return nil, errors.New("could not find any domains matched by wildcard") + } + } else { + domains = []string{d.config.Domain} + } + } + + case DOMAIN_MATCH_PATTERN_CERTSAN: + { + certX509, err := xcert.ParseCertificateFromPEM(certPEM) + if err != nil { + return nil, err + } + + domainCandidates, err := d.getAllDomains(ctx) + if err != nil { + return nil, err + } + + domains = lo.Filter(domainCandidates, func(domain string, _ int) bool { + return certX509.VerifyHostname(domain) == nil + }) + if len(domains) == 0 { + return nil, errors.New("could not find any domains matched by certificate") + } + } + + default: + return nil, fmt.Errorf("unsupported domain match pattern: '%s'", d.config.DomainMatchPattern) } - // 修改域名配置 - // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10853&data=173&isNormal=1&vid=166 - updateDomainReq := &ctyunicdn.UpdateDomainRequest{ - Domain: lo.ToPtr(d.config.Domain), - HttpsStatus: lo.ToPtr("on"), - CertName: lo.ToPtr(upres.CertName), - } - updateDomainResp, err := d.sdkClient.UpdateDomain(updateDomainReq) - d.logger.Debug("sdk request 'icdn.UpdateDomain'", slog.Any("request", updateDomainReq), slog.Any("response", updateDomainResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'icdn.UpdateDomain': %w", err) + // 遍历更新域名证书 + if len(domains) == 0 { + d.logger.Info("no icdn domains to deploy") + } else { + d.logger.Info("found icdn domains to deploy", slog.Any("domains", domains)) + var errs []error + + for _, domain := range domains { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + if err := d.updateDomainCertificate(ctx, domain, upres.CertId, upres.CertName); err != nil { + errs = append(errs, err) + } + } + } + + if len(errs) > 0 { + return nil, errors.Join(errs...) + } } return &core.SSLDeployResult{}, nil } +func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { + domains := make([]string, 0) + + // 查询域名列表 + // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10852&data=173&isNormal=1&vid=166 + queryDomainsPage := int32(1) + queryDomainsPageSize := int32(100) + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } + + queryDomainListReq := &ctyunicdn.QueryDomainListRequest{ + Page: lo.ToPtr(queryDomainsPage), + PageSize: lo.ToPtr(queryDomainsPageSize), + ProductCode: lo.ToPtr("006"), + } + queryDomainListResp, err := d.sdkClient.QueryDomainList(queryDomainListReq) + d.logger.Debug("sdk request 'cdn.QueryDomainList'", slog.Any("request", queryDomainListReq), slog.Any("response", queryDomainListResp)) + if err != nil { + 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) { + break + } else { + queryDomainsPage++ + } + } + + return domains, nil +} + +func (d *SSLDeployerProvider) updateDomainCertificate(ctx context.Context, domain string, cloudCertId, cloudCertName string) error { + // 查询域名配置信息 + // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10849&data=173&isNormal=1&vid=166 + queryDomainDetailReq := &ctyunicdn.QueryDomainDetailRequest{ + Domain: lo.ToPtr(domain), + } + queryDomainDetailResp, err := d.sdkClient.QueryDomainDetail(queryDomainDetailReq) + d.logger.Debug("sdk request 'icdn.QueryDomainDetail'", slog.Any("request", queryDomainDetailReq), slog.Any("response", queryDomainDetailResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'icdn.QueryDomainDetail': %w", err) + } + + // 修改域名配置 + // REF: https://eop.ctyun.cn/ebp/ctapiDocument/search?sid=112&api=10853&data=173&isNormal=1&vid=166 + updateDomainReq := &ctyunicdn.UpdateDomainRequest{ + Domain: lo.ToPtr(domain), + HttpsStatus: lo.ToPtr("on"), + CertName: lo.ToPtr(cloudCertName), + } + updateDomainResp, err := d.sdkClient.UpdateDomain(updateDomainReq) + d.logger.Debug("sdk request 'icdn.UpdateDomain'", slog.Any("request", updateDomainReq), slog.Any("response", updateDomainResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'icdn.UpdateDomain': %w", err) + } + + return nil +} + func createSDKClient(accessKeyId, secretAccessKey string) (*ctyunicdn.Client, error) { return ctyunicdn.NewClient(accessKeyId, secretAccessKey) } diff --git a/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn_test.go b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn_test.go index 8c7665dfa..b7544a85d 100644 --- a/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn_test.go +++ b/pkg/core/ssl-deployer/providers/ctcccloud-icdn/ctcccloud_icdn_test.go @@ -53,9 +53,10 @@ func TestDeploy(t *testing.T) { }, "\n")) deployer, err := provider.NewSSLDeployerProvider(&provider.SSLDeployerProviderConfig{ - AccessKeyId: fAccessKeyId, - SecretAccessKey: fSecretAccessKey, - Domain: fDomain, + AccessKeyId: fAccessKeyId, + SecretAccessKey: fSecretAccessKey, + DomainMatchPattern: provider.DOMAIN_MATCH_PATTERN_EXACT, + Domain: fDomain, }) if err != nil { t.Errorf("err: %+v", err) diff --git a/pkg/core/ssl-deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go b/pkg/core/ssl-deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go index 63e990fbb..4e481c544 100644 --- a/pkg/core/ssl-deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/huaweicloud-cdn/huaweicloud_cdn.go @@ -183,7 +183,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://support.huaweicloud.com/api-cdn/ListDomains.html listDomainsPageNumber := int32(1) listDomainsPageSize := int32(100) diff --git a/pkg/core/ssl-deployer/providers/huaweicloud-waf/huaweicloud_waf.go b/pkg/core/ssl-deployer/providers/huaweicloud-waf/huaweicloud_waf.go index d7e932fbb..dacce0bea 100644 --- a/pkg/core/ssl-deployer/providers/huaweicloud-waf/huaweicloud_waf.go +++ b/pkg/core/ssl-deployer/providers/huaweicloud-waf/huaweicloud_waf.go @@ -171,7 +171,7 @@ func (d *SSLDeployerProvider) deployToCloudServer(ctx context.Context, certPEM s d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) } - // 遍历查询云模式防护域名列表,获取防护域名 ID + // 查询云模式防护域名列表,获取防护域名 ID // REF: https://support.huaweicloud.com/api-waf/ListHost.html hostId := "" listHostPage := int32(1) @@ -246,7 +246,7 @@ func (d *SSLDeployerProvider) deployToPremiumHost(ctx context.Context, certPEM s d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) } - // 遍历查询独享模式域名列表,获取防护域名 ID + // 查询独享模式域名列表,获取防护域名 ID // REF: https://support.huaweicloud.com/api-waf/ListPremiumHost.html hostId := "" listPremiumHostPage := int32(1) diff --git a/pkg/core/ssl-deployer/providers/jdcloud-cdn/jdcloud_cdn.go b/pkg/core/ssl-deployer/providers/jdcloud-cdn/jdcloud_cdn.go index bb7a84014..976816ed3 100644 --- a/pkg/core/ssl-deployer/providers/jdcloud-cdn/jdcloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/jdcloud-cdn/jdcloud_cdn.go @@ -172,7 +172,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://docs.jdcloud.com/cn/cdn/api/getdomainlist getDomainListPageNumber := 1 getDomainListPageSize := 50 diff --git a/pkg/core/ssl-deployer/providers/ksyun-cdn/ksyun_cdn.go b/pkg/core/ssl-deployer/providers/ksyun-cdn/ksyun_cdn.go index 956bfa0d1..1f43d2018 100644 --- a/pkg/core/ssl-deployer/providers/ksyun-cdn/ksyun_cdn.go +++ b/pkg/core/ssl-deployer/providers/ksyun-cdn/ksyun_cdn.go @@ -83,7 +83,7 @@ func (d *SSLDeployerProvider) deployToDomain(ctx context.Context, certPEM string return errors.New("config `domain` is required") } - // 遍历查询域名列表,获取域名 ID + // 查询域名列表,获取域名 ID // https://docs.ksyun.com/documents/198 var domainId string getCdnDomainsPageNumber := int32(1) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go index bc92ca0dd..26974375f 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-cdn/tencentcloud_cdn.go @@ -162,7 +162,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, wildcardDomain string) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名基本信息,获取匹配的域名 + // 查询域名基本信息,获取匹配的域名 // REF: https://cloud.tencent.com/document/api/228/41118 describeDomainsOffset := int64(0) describeDomainsLimit := int64(100) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go index 2155132b2..0337c2669 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ecdn/tencentcloud_ecdn.go @@ -162,7 +162,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, wildcardDomain string) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名基本信息,获取匹配的域名 + // 查询域名基本信息,获取匹配的域名 // REF: https://cloud.tencent.com/document/api/228/41118 describeDomainsOffset := int64(0) describeDomainsLimit := int64(100) diff --git a/pkg/core/ssl-deployer/providers/volcengine-cdn/volcengine_cdn.go b/pkg/core/ssl-deployer/providers/volcengine-cdn/volcengine_cdn.go index 8e30e2857..9787e597f 100644 --- a/pkg/core/ssl-deployer/providers/volcengine-cdn/volcengine_cdn.go +++ b/pkg/core/ssl-deployer/providers/volcengine-cdn/volcengine_cdn.go @@ -156,7 +156,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getMatchedDomainsByWildcard(ctx context.Context, wildcardDomain string) ([]string, error) { domains := make([]string, 0) - // 遍历获取加速域名列表,获取匹配的域名 + // 查询加速域名列表,获取匹配的域名 // REF: https://www.volcengine.com/docs/6454/75269 listCdnDomainsPageNum := int64(1) listCdnDomainsPageSize := int64(100) diff --git a/pkg/core/ssl-deployer/providers/volcengine-live/volcengine_live.go b/pkg/core/ssl-deployer/providers/volcengine-live/volcengine_live.go index c1054793f..6427eb435 100644 --- a/pkg/core/ssl-deployer/providers/volcengine-live/volcengine_live.go +++ b/pkg/core/ssl-deployer/providers/volcengine-live/volcengine_live.go @@ -170,7 +170,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke func (d *SSLDeployerProvider) getAllDomains(ctx context.Context) ([]string, error) { domains := make([]string, 0) - // 遍历查询域名列表 + // 查询域名列表 // REF: https://www.volcengine.com/docs/6469/1126815 listDomainDetailPageNum := int32(1) listDomainDetailPageSize := int32(1000) diff --git a/pkg/core/ssl-manager/providers/1panel-ssl/1panel_ssl.go b/pkg/core/ssl-manager/providers/1panel-ssl/1panel_ssl.go index e656323ff..416ed65fb 100644 --- a/pkg/core/ssl-manager/providers/1panel-ssl/1panel_ssl.go +++ b/pkg/core/ssl-manager/providers/1panel-ssl/1panel_ssl.go @@ -59,7 +59,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 { return nil, err } else if res != nil { @@ -106,7 +106,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey panic("sdk client is not implemented") } - // 遍历证书列表,获取刚刚上传证书 ID + // 获取刚刚上传证书 ID if res, err := m.findCertIfExists(ctx, certPEM, privkeyPEM); err != nil { return nil, err } else if res == nil { diff --git a/pkg/core/ssl-manager/providers/baiducloud-cert/baiducloud_cert.go b/pkg/core/ssl-manager/providers/baiducloud-cert/baiducloud_cert.go index a99b1a8d5..e27e5d852 100644 --- a/pkg/core/ssl-manager/providers/baiducloud-cert/baiducloud_cert.go +++ b/pkg/core/ssl-manager/providers/baiducloud-cert/baiducloud_cert.go @@ -60,7 +60,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey return nil, err } - // 遍历证书列表,避免重复上传 + // 查看证书列表 // REF: https://cloud.baidu.com/doc/Reference/s/Gjwvz27xu#35-%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E5%88%97%E8%A1%A8%E8%AF%A6%E6%83%85 listCertDetail, err := m.sdkClient.ListCertDetail() m.logger.Debug("sdk request 'cert.ListCertDetail'", slog.Any("response", listCertDetail)) diff --git a/pkg/core/ssl-manager/providers/ctcccloud-cms/ctcccloud_cms.go b/pkg/core/ssl-manager/providers/ctcccloud-cms/ctcccloud_cms.go index 104ccce62..e179566c8 100644 --- a/pkg/core/ssl-manager/providers/ctcccloud-cms/ctcccloud_cms.go +++ b/pkg/core/ssl-manager/providers/ctcccloud-cms/ctcccloud_cms.go @@ -58,7 +58,7 @@ 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 { return res, nil } @@ -98,7 +98,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey return nil, fmt.Errorf("failed to execute sdk request 'cms.UploadCertificate': %w", err) } - // 遍历证书列表,获取刚刚上传证书 ID + // 获取刚刚上传证书 ID if res, err := m.findCertIfExists(ctx, certPEM); err != nil { return nil, err } else if res == nil { diff --git a/pkg/core/ssl-manager/providers/huaweicloud-elb/huaweicloud_elb.go b/pkg/core/ssl-manager/providers/huaweicloud-elb/huaweicloud_elb.go index 10c2a9f4a..de1d13fc4 100644 --- a/pkg/core/ssl-manager/providers/huaweicloud-elb/huaweicloud_elb.go +++ b/pkg/core/ssl-manager/providers/huaweicloud-elb/huaweicloud_elb.go @@ -67,7 +67,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 diff --git a/pkg/core/ssl-manager/providers/huaweicloud-scm/huaweicloud_scm.go b/pkg/core/ssl-manager/providers/huaweicloud-scm/huaweicloud_scm.go index 674ffbe11..9d815d336 100644 --- a/pkg/core/ssl-manager/providers/huaweicloud-scm/huaweicloud_scm.go +++ b/pkg/core/ssl-manager/providers/huaweicloud-scm/huaweicloud_scm.go @@ -70,7 +70,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey return nil, err } - // 遍历查询已有证书,避免重复上传 + // 查询已有证书,避免重复上传 // REF: https://support.huaweicloud.com/api-ccm/ListCertificates.html // REF: https://support.huaweicloud.com/api-ccm/ExportCertificate_0.html listCertificatesLimit := int32(50) diff --git a/pkg/core/ssl-manager/providers/huaweicloud-waf/huaweicloud_waf.go b/pkg/core/ssl-manager/providers/huaweicloud-waf/huaweicloud_waf.go index 7db54c57c..06522586b 100644 --- a/pkg/core/ssl-manager/providers/huaweicloud-waf/huaweicloud_waf.go +++ b/pkg/core/ssl-manager/providers/huaweicloud-waf/huaweicloud_waf.go @@ -67,7 +67,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-waf/ListCertificates.html // REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html listCertificatesPage := int32(1) diff --git a/pkg/core/ssl-manager/providers/jdcloud-ssl/jdcloud_ssl.go b/pkg/core/ssl-manager/providers/jdcloud-ssl/jdcloud_ssl.go index 7f3861f27..1a496bf98 100644 --- a/pkg/core/ssl-manager/providers/jdcloud-ssl/jdcloud_ssl.go +++ b/pkg/core/ssl-manager/providers/jdcloud-ssl/jdcloud_ssl.go @@ -71,7 +71,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey privkeyPEM = strings.ReplaceAll(privkeyPEM, "\n", "\r\n") privkeyPEM = privkeyPEM + "\r\n" - // 遍历查看证书列表,避免重复上传 + // 查看证书列表 // REF: https://docs.jdcloud.com/cn/ssl-certificate/api/describecerts describeCertsPageNumber := 1 describeCertsPageSize := 10 diff --git a/pkg/core/ssl-manager/providers/qiniu-sslcert/qiniu_sslcert.go b/pkg/core/ssl-manager/providers/qiniu-sslcert/qiniu_sslcert.go index dcbe26b03..dd0297ded 100644 --- a/pkg/core/ssl-manager/providers/qiniu-sslcert/qiniu_sslcert.go +++ b/pkg/core/ssl-manager/providers/qiniu-sslcert/qiniu_sslcert.go @@ -67,7 +67,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey // 生成新证书名(需符合七牛云命名规则) certName := fmt.Sprintf("certimate-%d", time.Now().UnixMilli()) - // 遍历查询已有证书,避免重复上传 + // 查询已有证书,避免重复上传 getSslCertListMarker := "" getSslCertListLimit := int32(200) for { diff --git a/pkg/core/ssl-manager/providers/rainyun-sslcenter/rainyun_sslcenter.go b/pkg/core/ssl-manager/providers/rainyun-sslcenter/rainyun_sslcenter.go index 9b56fcb24..8170befe2 100644 --- a/pkg/core/ssl-manager/providers/rainyun-sslcenter/rainyun_sslcenter.go +++ b/pkg/core/ssl-manager/providers/rainyun-sslcenter/rainyun_sslcenter.go @@ -51,7 +51,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 { return nil, err } else if res != nil { @@ -71,7 +71,7 @@ func (m *SSLManagerProvider) Upload(ctx context.Context, certPEM string, privkey return nil, fmt.Errorf("failed to execute sdk request 'sslcenter.Create': %w", err) } - // 遍历证书列表,获取刚刚上传证书 ID + // 获取刚刚上传证书 ID if res, err := m.findCertIfExists(ctx, certPEM); err != nil { return nil, err } else if res == nil { @@ -88,7 +88,7 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin return nil, err } - // 遍历 SSL 证书列表 + // 获取 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) diff --git a/pkg/core/ssl-manager/providers/ucloud-ussl/ucloud_ussl.go b/pkg/core/ssl-manager/providers/ucloud-ussl/ucloud_ussl.go index 83fe9deac..79a485326 100644 --- a/pkg/core/ssl-manager/providers/ucloud-ussl/ucloud_ussl.go +++ b/pkg/core/ssl-manager/providers/ucloud-ussl/ucloud_ussl.go @@ -115,7 +115,7 @@ func (m *SSLManagerProvider) findCertIfExists(ctx context.Context, certPEM strin return nil, err } - // 遍历获取用户证书列表 + // 查询用户证书列表 // REF: https://docs.ucloud.cn/api/usslcertificate-api/get_certificate_list // REF: https://docs.ucloud.cn/api/usslcertificate-api/download_certificate getCertificateListPage := int(1) diff --git a/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go b/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go index ace1bddb6..bf735c2ae 100644 --- a/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go +++ b/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go @@ -14,23 +14,7 @@ type QueryDomainDetailRequest struct { type QueryDomainDetailResponse struct { apiResponseBase - ReturnObj *struct { - Domain string `json:"domain"` - ProductCode string `json:"product_code"` - Status int32 `json:"status"` - AreaScope int32 `json:"area_scope"` - Cname string `json:"cname"` - HttpsStatus string `json:"https_status"` - HttpsBasic *struct { - HttpsForce string `json:"https_force"` - HttpForce string `json:"http_force"` - ForceStatus string `json:"force_status"` - OriginProtocol string `json:"origin_protocol"` - } `json:"https_basic,omitempty"` - CertName string `json:"cert_name"` - Ssl string `json:"ssl"` - SslStapling string `json:"ssl_stapling"` - } `json:"returnObj,omitempty"` + ReturnObj *DomainDetail `json:"returnObj,omitempty"` } func (c *Client) QueryDomainDetail(req *QueryDomainDetailRequest) (*QueryDomainDetailResponse, error) { diff --git a/pkg/sdk3rd/ctyun/icdn/api_query_domain_list.go b/pkg/sdk3rd/ctyun/icdn/api_query_domain_list.go new file mode 100644 index 000000000..318fea11b --- /dev/null +++ b/pkg/sdk3rd/ctyun/icdn/api_query_domain_list.go @@ -0,0 +1,67 @@ +package icdn + +import ( + "context" + "net/http" + "strconv" +) + +type QueryDomainListRequest struct { + Page *int32 `json:"page,omitempty"` + PageSize *int32 `json:"page_size,omitempty"` + Domain *string `json:"domain,omitempty"` + ProductCode *string `json:"product_code,omitempty"` + Status *int32 `json:"status,omitempty"` + AreaScope *int32 `json:"area_scope,omitempty"` +} + +type QueryDomainListResponse struct { + apiResponseBase + + ReturnObj *struct { + Results []*DomainRecord `json:"result,omitempty"` + Page int32 `json:"page,omitempty"` + PageSize int32 `json:"page_size,omitempty"` + PageCount int32 `json:"page_count,omitempty"` + Total int32 `json:"total,omitempty"` + } `json:"returnObj,omitempty"` +} + +func (c *Client) QueryDomainList(req *QueryDomainListRequest) (*QueryDomainListResponse, error) { + return c.QueryDomainListWithContext(context.Background(), req) +} + +func (c *Client) QueryDomainListWithContext(ctx context.Context, req *QueryDomainListRequest) (*QueryDomainListResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/v1/domain/query-domain-list") + if err != nil { + return nil, err + } else { + if req.Page != nil { + httpreq.SetQueryParam("page", strconv.Itoa(int(*req.Page))) + } + if req.PageSize != nil { + httpreq.SetQueryParam("page_size", strconv.Itoa(int(*req.PageSize))) + } + if req.Domain != nil { + httpreq.SetQueryParam("domain", *req.Domain) + } + if req.ProductCode != nil { + httpreq.SetQueryParam("product_code", *req.ProductCode) + } + if req.Status != nil { + httpreq.SetQueryParam("status", strconv.Itoa(int(*req.Status))) + } + if req.AreaScope != nil { + httpreq.SetQueryParam("area_scope", strconv.Itoa(int(*req.AreaScope))) + } + + httpreq.SetContext(ctx) + } + + result := &QueryDomainListResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/pkg/sdk3rd/ctyun/icdn/types.go b/pkg/sdk3rd/ctyun/icdn/types.go index 0d1e8fb64..a48ed4658 100644 --- a/pkg/sdk3rd/ctyun/icdn/types.go +++ b/pkg/sdk3rd/ctyun/icdn/types.go @@ -70,6 +70,32 @@ func (r *apiResponseBase) GetErrorMessage() string { var _ apiResponse = (*apiResponseBase)(nil) +type DomainRecord struct { + Domain string `json:"domain"` + Cname string `json:"cname"` + ProductCode string `json:"product_code"` + ProductName string `json:"product_name"` + AreaScope int32 `json:"area_scope"` + Status int32 `json:"status"` + CreatedTime int64 `json:"insert_date"` +} + +type DomainDetail struct { + DomainRecord + HttpsStatus string `json:"https_status"` + HttpsBasic *DomainHttpsBasicConfig `json:"https_basic,omitempty"` + CertName string `json:"cert_name"` + Ssl string `json:"ssl"` + SslStapling string `json:"ssl_stapling"` +} + +type DomainHttpsBasicConfig struct { + HttpsForce string `json:"https_force"` + HttpForce string `json:"http_force"` + ForceStatus string `json:"force_status"` + OriginProtocol string `json:"origin_protocol"` +} + type CertRecord struct { Id int64 `json:"id"` Name string `json:"name"` diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderCTCCCloudICDN.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderCTCCCloudICDN.tsx index 86bb72107..cc55ff314 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderCTCCCloudICDN.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderCTCCCloudICDN.tsx @@ -1,12 +1,17 @@ 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"; +import Show from "@/components/Show"; import { validDomainName } from "@/utils/validators"; import { useFormNestedFieldsContext } from "./_context"; +const DOMAIN_MATCH_PATTERN_EXACT = "exact" as const; +const DOMAIN_MATCH_PATTERN_WILDCARD = "wildcard" as const; +const DOMAIN_MATCH_PATTERN_CERTSAN = "certsan" as const; + const BizDeployNodeConfigFieldsProviderCTCCCloudICDN = () => { const { i18n, t } = useTranslation(); @@ -15,24 +20,52 @@ const BizDeployNodeConfigFieldsProviderCTCCCloudICDN = () => { [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 ( <>