mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
feat: upload certificate to cas first on deployment to aliyun cdn/dcdn
This commit is contained in:
@@ -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
|
||||
|
||||
+1
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -509,7 +509,7 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
>
|
||||
<AutoComplete
|
||||
allowClear
|
||||
options={["classic", "tlsserver", "shortlived"].map((value) => ({ 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())}
|
||||
/>
|
||||
|
||||
+17
-1
@@ -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 (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.aliyun_cdn_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cdn_region.tooltip") }}></span>}
|
||||
>
|
||||
<AutoComplete
|
||||
allowClear
|
||||
options={["cn-hangzhou", "ap-southeast-1"].map((s) => ({ value: s }))}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cdn_region.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
@@ -34,6 +48,7 @@ const BizDeployNodeConfigFieldsProviderAliyunCDN = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
domain: "",
|
||||
};
|
||||
};
|
||||
@@ -42,6 +57,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
region: z.string().nullish(),
|
||||
domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
|
||||
});
|
||||
};
|
||||
|
||||
+17
-1
@@ -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 (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.aliyun_dcdn_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_dcdn_region.tooltip") }}></span>}
|
||||
>
|
||||
<AutoComplete
|
||||
allowClear
|
||||
options={["cn-hangzhou", "ap-southeast-1"].map((s) => ({ value: s }))}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_dcdn_region.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
@@ -34,6 +48,7 @@ const BizDeployNodeConfigFieldsProviderAliyunDCDN = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
domain: "",
|
||||
};
|
||||
};
|
||||
@@ -42,6 +57,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
region: z.string().nullish(),
|
||||
domain: z.string().refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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 <a href=\"https://slb.console.aliyun.com/clb\" target=\"_blank\">https://slb.console.aliyun.com/clb</a>",
|
||||
"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": "<ul style=\"list-style: disc;\"><li><strong>ap-southeast-1</strong> for Alibaba Cloud International</li><li><strong>cn-hangzhou</strong> for Alibaba Cloud in China</li></ul>",
|
||||
"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 <a href=\"https://cdn.console.aliyun.com\" target=\"_blank\">https://cdn.console.aliyun.com</a>",
|
||||
"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": "<ul style=\"list-style: disc;\"><li><strong>ap-southeast-1</strong> for Alibaba Cloud International</li><li><strong>cn-hangzhou</strong> for Alibaba Cloud in China</li></ul>",
|
||||
"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 <a href=\"https://dcdn.console.aliyun.com\" target=\"_blank\">https://dcdn.console.aliyun.com</a>",
|
||||
|
||||
@@ -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": "这是什么?请参阅 <a href=\"https://slb.console.aliyun.com/clb\" target=\"_blank\">https://slb.console.aliyun.com/clb</a>",
|
||||
"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": "中国站请填写 <strong>cn-hangzhou</strong>;<br>国际站请填写 <strong>ap-southeast-1</strong>。",
|
||||
"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": "这是什么?请参阅 <a href=\"https://cdn.console.aliyun.com\" target=\"_blank\">https://cdn.console.aliyun.com</a>",
|
||||
"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": "中国站请填写 <strong>cn-hangzhou</strong>;<br>国际站请填写 <strong>ap-southeast-1</strong>。",
|
||||
"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": "这是什么?请参阅 <a href=\"https://dcdn.console.aliyun.com\" target=\"_blank\">https://dcdn.console.aliyun.com</a>",
|
||||
|
||||
Reference in New Issue
Block a user