From aaf48216af761d209eb204ab491d1cfd703d8188 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 5 Sep 2025 23:24:32 +0800 Subject: [PATCH] feat: upload certificate to cas first on deployment to aliyun cdn/dcdn --- .../certdeploy/deployers/sp_aliyun_cdn.go | 1 + .../{sp_aliyund_cdn.go => sp_aliyun_dcdn.go} | 1 + .../providers/aliyun-cdn/aliyun_cdn.go | 57 +++++++++++++++---- .../providers/aliyun-dcdn/aliyun_dcdn.go | 53 +++++++++++++---- .../providers/aliyun-ddos/aliyun_ddos.go | 2 +- .../providers/aliyun-vod/aliyun_vod.go | 52 +++++++++++++---- .../providers/rainyun-rcdn/rainyun_rcdn.go | 2 +- .../designer/forms/BizApplyNodeConfigForm.tsx | 2 +- ...eployNodeConfigFieldsProviderAliyunCDN.tsx | 18 +++++- ...ployNodeConfigFieldsProviderAliyunDCDN.tsx | 18 +++++- .../i18n/locales/en/nls.workflow.nodes.json | 6 ++ .../i18n/locales/zh/nls.workflow.nodes.json | 6 ++ 12 files changed, 177 insertions(+), 41 deletions(-) rename internal/certdeploy/deployers/{sp_aliyund_cdn.go => sp_aliyun_dcdn.go} (92%) diff --git a/internal/certdeploy/deployers/sp_aliyun_cdn.go b/internal/certdeploy/deployers/sp_aliyun_cdn.go index cd446f506..3301adaf9 100644 --- a/internal/certdeploy/deployers/sp_aliyun_cdn.go +++ b/internal/certdeploy/deployers/sp_aliyun_cdn.go @@ -20,6 +20,7 @@ func init() { AccessKeyId: credentials.AccessKeyId, AccessKeySecret: credentials.AccessKeySecret, ResourceGroupId: credentials.ResourceGroupId, + Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"), }) return provider, err diff --git a/internal/certdeploy/deployers/sp_aliyund_cdn.go b/internal/certdeploy/deployers/sp_aliyun_dcdn.go similarity index 92% rename from internal/certdeploy/deployers/sp_aliyund_cdn.go rename to internal/certdeploy/deployers/sp_aliyun_dcdn.go index 2a8279b74..8725d0ef6 100644 --- a/internal/certdeploy/deployers/sp_aliyund_cdn.go +++ b/internal/certdeploy/deployers/sp_aliyun_dcdn.go @@ -20,6 +20,7 @@ func init() { AccessKeyId: credentials.AccessKeyId, AccessKeySecret: credentials.AccessKeySecret, ResourceGroupId: credentials.ResourceGroupId, + Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"), }) return provider, err 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 a59924d73..00a541d7b 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go +++ b/pkg/core/ssl-deployer/providers/aliyun-cdn/aliyun_cdn.go @@ -5,13 +5,16 @@ import ( "errors" "fmt" "log/slog" + "strconv" "strings" - "time" alicdn "github.com/alibabacloud-go/cdn-20180510/v5/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" "github.com/alibabacloud-go/tea/tea" + "github.com/samber/lo" + "github.com/certimate-go/certimate/pkg/core" + sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" ) type SSLDeployerProviderConfig struct { @@ -21,14 +24,17 @@ type SSLDeployerProviderConfig struct { AccessKeySecret string `json:"accessKeySecret"` // 阿里云资源组 ID。 ResourceGroupId string `json:"resourceGroupId,omitempty"` + // 阿里云地域。 + Region string `json:"region"` // 加速域名(支持泛域名)。 Domain string `json:"domain"` } type SSLDeployerProvider struct { - config *SSLDeployerProviderConfig - logger *slog.Logger - sdkClient *alicdn.Client + config *SSLDeployerProviderConfig + logger *slog.Logger + sdkClient *alicdn.Client + sslManager core.SSLManager } var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) @@ -43,10 +49,23 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: lo. + If(config.Region == "" || strings.HasPrefix(config.Region, "cn-"), "cn-hangzhou"). + Else("ap-southeast-1"), + }) + if err != nil { + return nil, fmt.Errorf("could not create ssl manager: %w", err) + } + return &SSLDeployerProvider{ - config: config, - logger: slog.Default(), - sdkClient: client, + config: config, + logger: slog.Default(), + sdkClient: client, + sslManager: sslmgr, }, nil } @@ -59,18 +78,32 @@ 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 { + return nil, fmt.Errorf("failed to upload certificate file: %w", err) + } else { + d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) + } + // "*.example.com" → ".example.com",适配阿里云 CDN 要求的泛域名格式 domain := strings.TrimPrefix(d.config.Domain, "*") // 设置 CDN 域名域名证书 // REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-setcdndomainsslcertificate + certId, _ := strconv.ParseInt(upres.CertId, 10, 64) setCdnDomainSSLCertificateReq := &alicdn.SetCdnDomainSSLCertificateRequest{ - DomainName: tea.String(domain), - CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), - CertType: tea.String("upload"), + DomainName: tea.String(domain), + CertType: tea.String("cas"), + CertId: tea.Int64(int64(certId)), + CertRegion: lo. + If(d.config.Region == "" || strings.HasPrefix(d.config.Region, "cn-"), tea.String("cn-hangzhou")). + Else(tea.String("ap-southeast-1")), SSLProtocol: tea.String("on"), - SSLPub: tea.String(certPEM), - SSLPri: tea.String(privkeyPEM), } setCdnDomainSSLCertificateResp, err := d.sdkClient.SetCdnDomainSSLCertificate(setCdnDomainSSLCertificateReq) d.logger.Debug("sdk request 'cdn.SetCdnDomainSSLCertificate'", slog.Any("request", setCdnDomainSSLCertificateReq), slog.Any("response", setCdnDomainSSLCertificateResp)) 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 6118828f5..a599e3975 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go +++ b/pkg/core/ssl-deployer/providers/aliyun-dcdn/aliyun_dcdn.go @@ -5,13 +5,16 @@ import ( "errors" "fmt" "log/slog" + "strconv" "strings" - "time" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" alidcdn "github.com/alibabacloud-go/dcdn-20180115/v3/client" "github.com/alibabacloud-go/tea/tea" + "github.com/samber/lo" + "github.com/certimate-go/certimate/pkg/core" + sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" ) type SSLDeployerProviderConfig struct { @@ -21,14 +24,17 @@ type SSLDeployerProviderConfig struct { AccessKeySecret string `json:"accessKeySecret"` // 阿里云资源组 ID。 ResourceGroupId string `json:"resourceGroupId,omitempty"` + // 阿里云地域。 + Region string `json:"region"` // 加速域名(支持泛域名)。 Domain string `json:"domain"` } type SSLDeployerProvider struct { - config *SSLDeployerProviderConfig - logger *slog.Logger - sdkClient *alidcdn.Client + config *SSLDeployerProviderConfig + logger *slog.Logger + sdkClient *alidcdn.Client + sslManager core.SSLManager } var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) @@ -43,10 +49,23 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: lo. + If(config.Region == "" || strings.HasPrefix(config.Region, "cn-"), "cn-hangzhou"). + Else("ap-southeast-1"), + }) + if err != nil { + return nil, fmt.Errorf("could not create ssl manager: %w", err) + } + return &SSLDeployerProvider{ - config: config, - logger: slog.Default(), - sdkClient: client, + config: config, + logger: slog.Default(), + sdkClient: client, + sslManager: sslmgr, }, nil } @@ -63,18 +82,28 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return nil, errors.New("config `domain` is required") } + // 上传证书 + upres, err := d.sslManager.Upload(ctx, certPEM, privkeyPEM) + if err != nil { + return nil, fmt.Errorf("failed to upload certificate file: %w", err) + } else { + d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) + } + // "*.example.com" → ".example.com",适配阿里云 DCDN 要求的泛域名格式 domain := strings.TrimPrefix(d.config.Domain, "*") // 配置域名证书 // REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-setdcdndomainsslcertificate + certId, _ := strconv.ParseInt(upres.CertId, 10, 64) setDcdnDomainSSLCertificateReq := &alidcdn.SetDcdnDomainSSLCertificateRequest{ - DomainName: tea.String(domain), - CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), - CertType: tea.String("upload"), + DomainName: tea.String(domain), + CertType: tea.String("cas"), + CertId: tea.Int64(int64(certId)), + CertRegion: lo. + If(d.config.Region == "" || strings.HasPrefix(d.config.Region, "cn-"), tea.String("cn-hangzhou")). + Else(tea.String("ap-southeast-1")), SSLProtocol: tea.String("on"), - SSLPub: tea.String(certPEM), - SSLPri: tea.String(privkeyPEM), } setDcdnDomainSSLCertificateResp, err := d.sdkClient.SetDcdnDomainSSLCertificate(setDcdnDomainSSLCertificateReq) d.logger.Debug("sdk request 'dcdn.SetDcdnDomainSSLCertificate'", slog.Any("request", setDcdnDomainSSLCertificateReq), slog.Any("response", setDcdnDomainSSLCertificateResp)) diff --git a/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go b/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go index 12f8ceec6..dec81ee75 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go +++ b/pkg/core/ssl-deployer/providers/aliyun-ddos/aliyun_ddos.go @@ -94,7 +94,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke // 为网站业务转发规则关联 SSL 证书 // REF: https://help.aliyun.com/zh/anti-ddos/anti-ddos-pro-and-premium/developer-reference/api-ddoscoo-2020-01-01-associatewebcert - certId, _ := strconv.Atoi(upres.CertId) + certId, _ := strconv.ParseInt(upres.CertId, 10, 32) associateWebCertReq := &aliddos.AssociateWebCertRequest{ Domain: tea.String(d.config.Domain), CertId: tea.Int32(int32(certId)), diff --git a/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go b/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go index 081733689..07ea9c102 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go +++ b/pkg/core/ssl-deployer/providers/aliyun-vod/aliyun_vod.go @@ -5,12 +5,16 @@ import ( "errors" "fmt" "log/slog" - "time" + "strconv" + "strings" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" "github.com/alibabacloud-go/tea/tea" alivod "github.com/alibabacloud-go/vod-20170321/v4/client" + "github.com/samber/lo" + "github.com/certimate-go/certimate/pkg/core" + sslmgrsp "github.com/certimate-go/certimate/pkg/core/ssl-manager/providers/aliyun-cas" ) type SSLDeployerProviderConfig struct { @@ -27,9 +31,10 @@ type SSLDeployerProviderConfig struct { } type SSLDeployerProvider struct { - config *SSLDeployerProviderConfig - logger *slog.Logger - sdkClient *alivod.Client + config *SSLDeployerProviderConfig + logger *slog.Logger + sdkClient *alivod.Client + sslManager core.SSLManager } var _ core.SSLDeployer = (*SSLDeployerProvider)(nil) @@ -44,10 +49,23 @@ func NewSSLDeployerProvider(config *SSLDeployerProviderConfig) (*SSLDeployerProv return nil, fmt.Errorf("could not create sdk client: %w", err) } + sslmgr, err := sslmgrsp.NewSSLManagerProvider(&sslmgrsp.SSLManagerProviderConfig{ + AccessKeyId: config.AccessKeyId, + AccessKeySecret: config.AccessKeySecret, + ResourceGroupId: config.ResourceGroupId, + Region: lo. + If(config.Region == "" || strings.HasPrefix(config.Region, "cn-"), "cn-hangzhou"). + Else("ap-southeast-1"), + }) + if err != nil { + return nil, fmt.Errorf("could not create ssl manager: %w", err) + } + return &SSLDeployerProvider{ - config: config, - logger: slog.Default(), - sdkClient: client, + config: config, + logger: slog.Default(), + sdkClient: client, + sslManager: sslmgr, }, nil } @@ -64,15 +82,25 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke return nil, errors.New("config `domain` is required") } + // 上传证书 + upres, err := d.sslManager.Upload(ctx, certPEM, privkeyPEM) + if err != nil { + return nil, fmt.Errorf("failed to upload certificate file: %w", err) + } else { + d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) + } + // 设置域名证书 // REF: https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-setvoddomainsslcertificate + certId, _ := strconv.ParseInt(upres.CertId, 10, 64) setVodDomainSSLCertificateReq := &alivod.SetVodDomainSSLCertificateRequest{ - DomainName: tea.String(d.config.Domain), - CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), - CertType: tea.String("upload"), + DomainName: tea.String(d.config.Domain), + CertType: tea.String("cas"), + CertId: tea.Int64(int64(certId)), + CertRegion: lo. + If(d.config.Region == "" || strings.HasPrefix(d.config.Region, "cn-"), tea.String("cn-hangzhou")). + Else(tea.String("ap-southeast-1")), SSLProtocol: tea.String("on"), - SSLPub: tea.String(certPEM), - SSLPri: tea.String(privkeyPEM), } setVodDomainSSLCertificateResp, err := d.sdkClient.SetVodDomainSSLCertificate(setVodDomainSSLCertificateReq) d.logger.Debug("sdk request 'live.SetVodDomainSSLCertificate'", slog.Any("request", setVodDomainSSLCertificateReq), slog.Any("response", setVodDomainSSLCertificateResp)) diff --git a/pkg/core/ssl-deployer/providers/rainyun-rcdn/rainyun_rcdn.go b/pkg/core/ssl-deployer/providers/rainyun-rcdn/rainyun_rcdn.go index 8af0fa061..1accc617e 100644 --- a/pkg/core/ssl-deployer/providers/rainyun-rcdn/rainyun_rcdn.go +++ b/pkg/core/ssl-deployer/providers/rainyun-rcdn/rainyun_rcdn.go @@ -80,7 +80,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke // RCDN SSL 绑定域名 // REF: https://apifox.com/apidoc/shared/a4595cc8-44c5-4678-a2a3-eed7738dab03/api-184214120 - certId, _ := strconv.Atoi(upres.CertId) + certId, _ := strconv.ParseInt(upres.CertId, 10, 32) rcdnInstanceSslBindReq := &rainyunsdk.RcdnInstanceSslBindRequest{ CertId: int32(certId), Domains: []string{d.config.Domain}, diff --git a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx index 5ab9cb563..b5609cb9a 100644 --- a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigForm.tsx @@ -509,7 +509,7 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps) > ({ value }))} + options={["classic", "tlsserver", "shortlived"].map((s) => ({ value: s }))} placeholder={t("workflow_node.apply.form.acme_profile.placeholder")} filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} /> diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunCDN.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunCDN.tsx index bb8d68f1e..92105b64b 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunCDN.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunCDN.tsx @@ -1,5 +1,5 @@ import { getI18n, useTranslation } from "react-i18next"; -import { Form, Input } from "antd"; +import { AutoComplete, Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; @@ -19,6 +19,20 @@ const BizDeployNodeConfigFieldsProviderAliyunCDN = () => { return ( <> + } + > + ({ value: s }))} + placeholder={t("workflow_node.deploy.form.aliyun_cdn_region.placeholder")} + /> + + { const getInitialValues = (): Nullish>> => { return { + region: "", domain: "", }; }; @@ -42,6 +57,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) const { t } = i18n; return z.object({ + region: z.string().nullish(), domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); }; diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunDCDN.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunDCDN.tsx index 4a871f2b3..0ec8512e5 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunDCDN.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunDCDN.tsx @@ -1,5 +1,5 @@ import { getI18n, useTranslation } from "react-i18next"; -import { Form, Input } from "antd"; +import { AutoComplete, Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; @@ -19,6 +19,20 @@ const BizDeployNodeConfigFieldsProviderAliyunDCDN = () => { return ( <> + } + > + ({ value: s }))} + placeholder={t("workflow_node.deploy.form.aliyun_dcdn_region.placeholder")} + /> + + { const getInitialValues = (): Nullish>> => { return { + region: "", domain: "", }; }; @@ -42,6 +57,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) const { t } = i18n; return z.object({ + region: z.string().nullish(), domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")), }); }; diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 60ed9ca92..d62db857c 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -256,9 +256,15 @@ "workflow_node.deploy.form.aliyun_clb_snidomain.placeholder": "Please enter Alibaba Cloud CLB SNI domain name", "workflow_node.deploy.form.aliyun_clb_snidomain.help": "", "workflow_node.deploy.form.aliyun_clb_snidomain.tooltip": "For more information, see https://slb.console.aliyun.com/clb", + "workflow_node.deploy.form.aliyun_cdn_region.label": "Alibaba Cloud CDN region", + "workflow_node.deploy.form.aliyun_cdn_region.placeholder": "Please enter Alibaba Cloud CDN region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_cdn_region.tooltip": "
  • ap-southeast-1 for Alibaba Cloud International
  • cn-hangzhou for Alibaba Cloud in China
", "workflow_node.deploy.form.aliyun_cdn_domain.label": "Alibaba Cloud CDN domain", "workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "Please enter Alibaba Cloud CDN domain name", "workflow_node.deploy.form.aliyun_cdn_domain.tooltip": "For more information, see https://cdn.console.aliyun.com", + "workflow_node.deploy.form.aliyun_dcdn_region.label": "Alibaba Cloud DCDN region", + "workflow_node.deploy.form.aliyun_dcdn_region.placeholder": "Please enter Alibaba Cloud DCDN region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_dcdn_region.tooltip": "
  • ap-southeast-1 for Alibaba Cloud International
  • cn-hangzhou for Alibaba Cloud in China
", "workflow_node.deploy.form.aliyun_dcdn_domain.label": "Alibaba Cloud DCDN domain", "workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "Please enter Alibaba Cloud DCDN domain name", "workflow_node.deploy.form.aliyun_dcdn_domain.tooltip": "For more information, see https://dcdn.console.aliyun.com", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index e214f6e97..c9a30717b 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -255,9 +255,15 @@ "workflow_node.deploy.form.aliyun_clb_snidomain.placeholder": "请输入阿里云 CLB 扩展域名(支持泛域名)", "workflow_node.deploy.form.aliyun_clb_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", "workflow_node.deploy.form.aliyun_clb_snidomain.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/clb", + "workflow_node.deploy.form.aliyun_cdn_region.label": "阿里云 CDN 服务地域", + "workflow_node.deploy.form.aliyun_cdn_region.placeholder": "请输入阿里云 CDN 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_cdn_region.tooltip": "中国站请填写 cn-hangzhou;
国际站请填写 ap-southeast-1。", "workflow_node.deploy.form.aliyun_cdn_domain.label": "阿里云 CDN 加速域名", "workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "请输入阿里云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.aliyun_cdn_domain.tooltip": "这是什么?请参阅 https://cdn.console.aliyun.com", + "workflow_node.deploy.form.aliyun_dcdn_region.label": "阿里云 DCDN 服务地域", + "workflow_node.deploy.form.aliyun_dcdn_region.placeholder": "请输入阿里云 DCDN 服务地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_dcdn_region.tooltip": "中国站请填写 cn-hangzhou;
国际站请填写 ap-southeast-1。", "workflow_node.deploy.form.aliyun_dcdn_domain.label": "阿里云 DCDN 加速域名", "workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "请输入阿里云 DCDN 加速域名(支持泛域名)", "workflow_node.deploy.form.aliyun_dcdn_domain.tooltip": "这是什么?请参阅 https://dcdn.console.aliyun.com",