mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-09 05:59:50 +00:00
feat: add aliyun clb deployer
This commit is contained in:
parent
e660e9cad1
commit
20d2c5699c
@ -73,7 +73,7 @@ make local.run
|
|||||||
|
|
||||||
| 服务商 | 支持申请证书 | 支持部署证书 | 备注 |
|
| 服务商 | 支持申请证书 | 支持部署证书 | 备注 |
|
||||||
| :--------: | :----------: | :----------: | ------------------------------------------------------------ |
|
| :--------: | :----------: | :----------: | ------------------------------------------------------------ |
|
||||||
| 阿里云 | √ | √ | 可签发在阿里云注册的域名;可部署到阿里云 OSS、CDN |
|
| 阿里云 | √ | √ | 可签发在阿里云注册的域名;可部署到阿里云 OSS、CDN、CLB(SLB) |
|
||||||
| 腾讯云 | √ | √ | 可签发在腾讯云注册的域名;可部署到腾讯云 COS、CDN、CLB |
|
| 腾讯云 | √ | √ | 可签发在腾讯云注册的域名;可部署到腾讯云 COS、CDN、CLB |
|
||||||
| 华为云 | √ | √ | 可签发在华为云注册的域名;可部署到华为云 CDN、ELB |
|
| 华为云 | √ | √ | 可签发在华为云注册的域名;可部署到华为云 CDN、ELB |
|
||||||
| 七牛云 | | √ | 可部署到七牛云 CDN |
|
| 七牛云 | | √ | 可部署到七牛云 CDN |
|
||||||
|
32
README_EN.md
32
README_EN.md
@ -70,22 +70,22 @@ password:1234567890
|
|||||||
|
|
||||||
## List of Supported Providers
|
## List of Supported Providers
|
||||||
|
|
||||||
| Provider | Registration | Deployment | Remarks |
|
| Provider | Registration | Deployment | Remarks |
|
||||||
| :-----------: | :----------: | :--------: | ------------------------------------------------------------------------------------------------ |
|
| :-----------: | :----------: | :--------: | ----------------------------------------------------------------------------------------------------- |
|
||||||
| Alibaba Cloud | √ | √ | Supports domains registered on Alibaba Cloud; supports deployment to Alibaba Cloud OSS, CDN |
|
| Alibaba Cloud | √ | √ | Supports domains registered on Alibaba Cloud; supports deployment to Alibaba Cloud OSS, CDN, CLB(SLB) |
|
||||||
| Tencent Cloud | √ | √ | Supports domains registered on Tencent Cloud; supports deployment to Tencent Cloud COS, CDN, CLB |
|
| Tencent Cloud | √ | √ | Supports domains registered on Tencent Cloud; supports deployment to Tencent Cloud COS, CDN, CLB |
|
||||||
| Huawei Cloud | √ | √ | Supports domains registered on Huawei Cloud; supports deployment to Huawei Cloud CDN, ELB |
|
| Huawei Cloud | √ | √ | Supports domains registered on Huawei Cloud; supports deployment to Huawei Cloud CDN, ELB |
|
||||||
| Qiniu Cloud | | √ | Supports deployment to Qiniu Cloud CDN |
|
| Qiniu Cloud | | √ | Supports deployment to Qiniu Cloud CDN |
|
||||||
| AWS | √ | | Supports domains managed on AWS Route53 |
|
| AWS | √ | | Supports domains managed on AWS Route53 |
|
||||||
| CloudFlare | √ | | Supports domains registered on CloudFlare; CloudFlare services come with SSL certificates |
|
| CloudFlare | √ | | Supports domains registered on CloudFlare; CloudFlare services come with SSL certificates |
|
||||||
| GoDaddy | √ | | Supports domains registered on GoDaddy |
|
| GoDaddy | √ | | Supports domains registered on GoDaddy |
|
||||||
| Namesilo | √ | | Supports domains registered on Namesilo |
|
| Namesilo | √ | | Supports domains registered on Namesilo |
|
||||||
| PowerDNS | √ | | Supports domains managed on PowerDNS |
|
| PowerDNS | √ | | Supports domains managed on PowerDNS |
|
||||||
| HTTP Request | √ | | Supports domains which allow managing DNS by HTTP request |
|
| HTTP Request | √ | | Supports domains which allow managing DNS by HTTP request |
|
||||||
| Local Deploy | | √ | Supports deployment to local servers |
|
| Local Deploy | | √ | Supports deployment to local servers |
|
||||||
| SSH | | √ | Supports deployment to SSH servers |
|
| SSH | | √ | Supports deployment to SSH servers |
|
||||||
| Webhook | | √ | Supports callback to Webhook |
|
| Webhook | | √ | Supports callback to Webhook |
|
||||||
| Kubernetes | | √ | Supports deployment to Kubernetes Secret |
|
| Kubernetes | | √ | Supports deployment to Kubernetes Secret |
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
281
internal/deployer/aliyun_clb.go
Normal file
281
internal/deployer/aliyun_clb.go
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
package deployer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||||
|
slb20140515 "github.com/alibabacloud-go/slb-20140515/v4/client"
|
||||||
|
"github.com/alibabacloud-go/tea/tea"
|
||||||
|
|
||||||
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AliyunCLBDeployer struct {
|
||||||
|
option *DeployerOption
|
||||||
|
infos []string
|
||||||
|
|
||||||
|
sdkClient *slb20140515.Client
|
||||||
|
sslUploader uploader.Uploader
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAliyunCLBDeployer(option *DeployerOption) (Deployer, error) {
|
||||||
|
access := &domain.AliyunAccess{}
|
||||||
|
json.Unmarshal([]byte(option.Access), access)
|
||||||
|
|
||||||
|
client, err := (&AliyunCLBDeployer{}).createSdkClient(
|
||||||
|
access.AccessKeyId,
|
||||||
|
access.AccessKeySecret,
|
||||||
|
option.DeployConfig.GetConfigAsString("region"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uploader, err := uploader.NewAliyunSLBUploader(&uploader.AliyunSLBUploaderConfig{
|
||||||
|
AccessKeyId: access.AccessKeyId,
|
||||||
|
AccessKeySecret: access.AccessKeySecret,
|
||||||
|
Region: option.DeployConfig.GetConfigAsString("region"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &AliyunCLBDeployer{
|
||||||
|
option: option,
|
||||||
|
infos: make([]string, 0),
|
||||||
|
sdkClient: client,
|
||||||
|
sslUploader: uploader,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) GetID() string {
|
||||||
|
return fmt.Sprintf("%s-%s", d.option.AccessRecord.GetString("name"), d.option.AccessRecord.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) GetInfo() []string {
|
||||||
|
return d.infos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) Deploy(ctx context.Context) error {
|
||||||
|
switch d.option.DeployConfig.GetConfigAsString("resourceType") {
|
||||||
|
case "loadbalancer":
|
||||||
|
if err := d.deployToLoadbalancer(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case "listener":
|
||||||
|
if err := d.deployToListener(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return errors.New("unsupported resource type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) createSdkClient(accessKeyId, accessKeySecret, region string) (*slb20140515.Client, error) {
|
||||||
|
if region == "" {
|
||||||
|
region = "cn-hangzhou" // CLB(SLB) 服务默认区域:华东一杭州
|
||||||
|
}
|
||||||
|
|
||||||
|
aConfig := &openapi.Config{
|
||||||
|
AccessKeyId: tea.String(accessKeyId),
|
||||||
|
AccessKeySecret: tea.String(accessKeySecret),
|
||||||
|
}
|
||||||
|
|
||||||
|
var endpoint string
|
||||||
|
switch region {
|
||||||
|
case "cn-hangzhou":
|
||||||
|
case "cn-hangzhou-finance":
|
||||||
|
case "cn-shanghai-finance-1":
|
||||||
|
case "cn-shenzhen-finance-1":
|
||||||
|
endpoint = "slb.aliyuncs.com"
|
||||||
|
default:
|
||||||
|
endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region)
|
||||||
|
}
|
||||||
|
aConfig.Endpoint = tea.String(endpoint)
|
||||||
|
|
||||||
|
client, err := slb20140515.NewClient(aConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) deployToLoadbalancer(ctx context.Context) error {
|
||||||
|
aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
|
||||||
|
if aliLoadbalancerId == "" {
|
||||||
|
return errors.New("`loadbalancerId` is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询负载均衡器实例的详细信息
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerattribute
|
||||||
|
describeLoadBalancerAttributeReq := &slb20140515.DescribeLoadBalancerAttributeRequest{
|
||||||
|
RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
|
||||||
|
LoadBalancerId: tea.String(aliLoadbalancerId),
|
||||||
|
}
|
||||||
|
describeLoadBalancerAttributeResp, err := d.sdkClient.DescribeLoadBalancerAttribute(describeLoadBalancerAttributeReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.DescribeLoadBalancerAttribute': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已查询到 CLB 负载均衡器实例", describeLoadBalancerAttributeResp))
|
||||||
|
|
||||||
|
// 查询监听列表
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerlisteners
|
||||||
|
aliListenerPorts := make([]int32, 0)
|
||||||
|
listListenersPage := 1
|
||||||
|
listListenersLimit := int32(100)
|
||||||
|
var listListenersToken *string = nil
|
||||||
|
for {
|
||||||
|
describeLoadBalancerListenersReq := &slb20140515.DescribeLoadBalancerListenersRequest{
|
||||||
|
RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
|
||||||
|
MaxResults: tea.Int32(listListenersLimit),
|
||||||
|
NextToken: listListenersToken,
|
||||||
|
LoadBalancerId: []*string{tea.String(aliLoadbalancerId)},
|
||||||
|
ListenerProtocol: tea.String("https"),
|
||||||
|
}
|
||||||
|
describeLoadBalancerListenersResp, err := d.sdkClient.DescribeLoadBalancerListeners(describeLoadBalancerListenersReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.DescribeLoadBalancerListeners': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if describeLoadBalancerListenersResp.Body.Listeners != nil {
|
||||||
|
for _, listener := range describeLoadBalancerListenersResp.Body.Listeners {
|
||||||
|
aliListenerPorts = append(aliListenerPorts, *listener.ListenerPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if describeLoadBalancerListenersResp.Body.NextToken == nil {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
listListenersToken = describeLoadBalancerListenersResp.Body.NextToken
|
||||||
|
listListenersPage += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已查询到 ELB 负载均衡器下的监听器", aliListenerPorts))
|
||||||
|
|
||||||
|
// 上传证书到 SLB
|
||||||
|
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已上传证书", uploadResult))
|
||||||
|
|
||||||
|
// 批量更新监听证书
|
||||||
|
var errs []error
|
||||||
|
for _, aliListenerPort := range aliListenerPorts {
|
||||||
|
if err := d.updateListenerCertificate(ctx, aliLoadbalancerId, aliListenerPort, uploadResult.CertId); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) deployToListener(ctx context.Context) error {
|
||||||
|
aliLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
|
||||||
|
if aliLoadbalancerId == "" {
|
||||||
|
return errors.New("`loadbalancerId` is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
aliListenerPort := d.option.DeployConfig.GetConfigAsInt32("listenerPort")
|
||||||
|
if aliListenerPort == 0 {
|
||||||
|
return errors.New("`listenerPort` is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传证书到 SLB
|
||||||
|
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已上传证书", uploadResult))
|
||||||
|
|
||||||
|
// 更新监听
|
||||||
|
if err := d.updateListenerCertificate(ctx, aliLoadbalancerId, aliListenerPort, uploadResult.CertId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *AliyunCLBDeployer) updateListenerCertificate(ctx context.Context, aliLoadbalancerId string, aliListenerPort int32, aliCertId string) error {
|
||||||
|
// 查询监听配置
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute
|
||||||
|
describeLoadBalancerHTTPSListenerAttributeReq := &slb20140515.DescribeLoadBalancerHTTPSListenerAttributeRequest{
|
||||||
|
LoadBalancerId: tea.String(aliLoadbalancerId),
|
||||||
|
ListenerPort: tea.Int32(aliListenerPort),
|
||||||
|
}
|
||||||
|
describeLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.DescribeLoadBalancerHTTPSListenerAttribute(describeLoadBalancerHTTPSListenerAttributeReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.DescribeLoadBalancerHTTPSListenerAttribute': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已查询到 CLB HTTPS 监听配置", describeLoadBalancerHTTPSListenerAttributeResp))
|
||||||
|
|
||||||
|
// 查询扩展域名
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions
|
||||||
|
describeDomainExtensionsReq := &slb20140515.DescribeDomainExtensionsRequest{
|
||||||
|
RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
|
||||||
|
LoadBalancerId: tea.String(aliLoadbalancerId),
|
||||||
|
ListenerPort: tea.Int32(aliListenerPort),
|
||||||
|
}
|
||||||
|
describeDomainExtensionsResp, err := d.sdkClient.DescribeDomainExtensions(describeDomainExtensionsReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.DescribeDomainExtensions': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已查询到 CLB 扩展域名", describeDomainExtensionsResp))
|
||||||
|
|
||||||
|
// 遍历修改扩展域名
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setdomainextensionattribute
|
||||||
|
//
|
||||||
|
// 这里仅修改跟被替换证书一致的扩展域名
|
||||||
|
if describeDomainExtensionsResp.Body.DomainExtensions == nil && describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension == nil {
|
||||||
|
for _, domainExtension := range describeDomainExtensionsResp.Body.DomainExtensions.DomainExtension {
|
||||||
|
if *domainExtension.ServerCertificateId == *describeLoadBalancerHTTPSListenerAttributeResp.Body.ServerCertificateId {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
setDomainExtensionAttributeReq := &slb20140515.SetDomainExtensionAttributeRequest{
|
||||||
|
RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
|
||||||
|
DomainExtensionId: tea.String(*domainExtension.DomainExtensionId),
|
||||||
|
ServerCertificateId: tea.String(aliCertId),
|
||||||
|
}
|
||||||
|
_, err := d.sdkClient.SetDomainExtensionAttribute(setDomainExtensionAttributeReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.SetDomainExtensionAttribute': %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改监听配置
|
||||||
|
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
|
||||||
|
//
|
||||||
|
// 注意修改监听配置要放在修改扩展域名之后
|
||||||
|
setLoadBalancerHTTPSListenerAttributeReq := &slb20140515.SetLoadBalancerHTTPSListenerAttributeRequest{
|
||||||
|
RegionId: tea.String(d.option.DeployConfig.GetConfigAsString("region")),
|
||||||
|
LoadBalancerId: tea.String(aliLoadbalancerId),
|
||||||
|
ListenerPort: tea.Int32(aliListenerPort),
|
||||||
|
ServerCertificateId: tea.String(aliCertId),
|
||||||
|
}
|
||||||
|
setLoadBalancerHTTPSListenerAttributeResp, err := d.sdkClient.SetLoadBalancerHTTPSListenerAttribute(setLoadBalancerHTTPSListenerAttributeReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'slb.SetLoadBalancerHTTPSListenerAttribute': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.infos = append(d.infos, toStr("已更新 CLB HTTPS 监听配置", setLoadBalancerHTTPSListenerAttributeResp))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -18,6 +18,7 @@ const (
|
|||||||
targetAliyunOSS = "aliyun-oss"
|
targetAliyunOSS = "aliyun-oss"
|
||||||
targetAliyunCDN = "aliyun-cdn"
|
targetAliyunCDN = "aliyun-cdn"
|
||||||
targetAliyunESA = "aliyun-dcdn"
|
targetAliyunESA = "aliyun-dcdn"
|
||||||
|
targetAliyunCLB = "aliyun-clb"
|
||||||
targetTencentCDN = "tencent-cdn"
|
targetTencentCDN = "tencent-cdn"
|
||||||
targetTencentCLB = "tencent-clb"
|
targetTencentCLB = "tencent-clb"
|
||||||
targetTencentCOS = "tencent-cos"
|
targetTencentCOS = "tencent-cos"
|
||||||
@ -106,6 +107,8 @@ func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, dep
|
|||||||
return NewAliyunCDNDeployer(option)
|
return NewAliyunCDNDeployer(option)
|
||||||
case targetAliyunESA:
|
case targetAliyunESA:
|
||||||
return NewAliyunESADeployer(option)
|
return NewAliyunESADeployer(option)
|
||||||
|
case targetAliyunCLB:
|
||||||
|
return NewAliyunCLBDeployer(option)
|
||||||
case targetTencentCDN:
|
case targetTencentCDN:
|
||||||
return NewTencentCDNDeployer(option)
|
return NewTencentCDNDeployer(option)
|
||||||
case targetTencentCLB:
|
case targetTencentCLB:
|
||||||
|
@ -41,9 +41,9 @@ func NewHuaweiCloudCDNDeployer(option *DeployerOption) (Deployer, error) {
|
|||||||
|
|
||||||
// TODO: SCM 服务与 DNS 服务所支持的区域可能不一致,这里暂时不传而是使用默认值,仅支持华为云国内版
|
// TODO: SCM 服务与 DNS 服务所支持的区域可能不一致,这里暂时不传而是使用默认值,仅支持华为云国内版
|
||||||
uploader, err := uploader.NewHuaweiCloudSCMUploader(&uploader.HuaweiCloudSCMUploaderConfig{
|
uploader, err := uploader.NewHuaweiCloudSCMUploader(&uploader.HuaweiCloudSCMUploaderConfig{
|
||||||
Region: "",
|
|
||||||
AccessKeyId: access.AccessKeyId,
|
AccessKeyId: access.AccessKeyId,
|
||||||
SecretAccessKey: access.SecretAccessKey,
|
SecretAccessKey: access.SecretAccessKey,
|
||||||
|
Region: "",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -46,9 +46,9 @@ func NewHuaweiCloudELBDeployer(option *DeployerOption) (Deployer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uploader, err := uploader.NewHuaweiCloudELBUploader(&uploader.HuaweiCloudELBUploaderConfig{
|
uploader, err := uploader.NewHuaweiCloudELBUploader(&uploader.HuaweiCloudELBUploaderConfig{
|
||||||
Region: option.DeployConfig.GetConfigAsString("region"),
|
|
||||||
AccessKeyId: access.AccessKeyId,
|
AccessKeyId: access.AccessKeyId,
|
||||||
SecretAccessKey: access.SecretAccessKey,
|
SecretAccessKey: access.SecretAccessKey,
|
||||||
|
Region: option.DeployConfig.GetConfigAsString("region"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -176,10 +176,15 @@ func (u *HuaweiCloudELBDeployer) getSdkProjectId(accessKeyId, secretAccessKey, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context) error {
|
func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context) error {
|
||||||
|
hcCertId := d.option.DeployConfig.GetConfigAsString("certificateId")
|
||||||
|
if hcCertId == "" {
|
||||||
|
return errors.New("`certificateId` is required")
|
||||||
|
}
|
||||||
|
|
||||||
// 更新证书
|
// 更新证书
|
||||||
// REF: https://support.huaweicloud.com/api-elb/UpdateCertificate.html
|
// REF: https://support.huaweicloud.com/api-elb/UpdateCertificate.html
|
||||||
updateCertificateReq := &hcElbModel.UpdateCertificateRequest{
|
updateCertificateReq := &hcElbModel.UpdateCertificateRequest{
|
||||||
CertificateId: d.option.DeployConfig.GetConfigAsString("certificateId"),
|
CertificateId: hcCertId,
|
||||||
Body: &hcElbModel.UpdateCertificateRequestBody{
|
Body: &hcElbModel.UpdateCertificateRequestBody{
|
||||||
Certificate: &hcElbModel.UpdateCertificateOption{
|
Certificate: &hcElbModel.UpdateCertificateOption{
|
||||||
Certificate: cast.StringPtr(d.option.Certificate.Certificate),
|
Certificate: cast.StringPtr(d.option.Certificate.Certificate),
|
||||||
@ -198,21 +203,26 @@ func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error {
|
func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error {
|
||||||
|
hcLoadbalancerId := d.option.DeployConfig.GetConfigAsString("loadbalancerId")
|
||||||
|
if hcLoadbalancerId == "" {
|
||||||
|
return errors.New("`loadbalancerId` is required")
|
||||||
|
}
|
||||||
|
|
||||||
// 查询负载均衡器详情
|
// 查询负载均衡器详情
|
||||||
// REF: https://support.huaweicloud.com/api-elb/ShowLoadBalancer.html
|
// REF: https://support.huaweicloud.com/api-elb/ShowLoadBalancer.html
|
||||||
showLoadBalancerReq := &hcElbModel.ShowLoadBalancerRequest{
|
showLoadBalancerReq := &hcElbModel.ShowLoadBalancerRequest{
|
||||||
LoadbalancerId: d.option.DeployConfig.GetConfigAsString("loadbalancerId"),
|
LoadbalancerId: hcLoadbalancerId,
|
||||||
}
|
}
|
||||||
showLoadBalancerResp, err := d.sdkClient.ShowLoadBalancer(showLoadBalancerReq)
|
showLoadBalancerResp, err := d.sdkClient.ShowLoadBalancer(showLoadBalancerReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to execute sdk request 'elb.ShowLoadBalancer': %w", err)
|
return fmt.Errorf("failed to execute sdk request 'elb.ShowLoadBalancer': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.infos = append(d.infos, toStr("已查询到到 ELB 负载均衡器", showLoadBalancerResp))
|
d.infos = append(d.infos, toStr("已查询到 ELB 负载均衡器", showLoadBalancerResp))
|
||||||
|
|
||||||
// 查询监听器列表
|
// 查询监听器列表
|
||||||
// REF: https://support.huaweicloud.com/api-elb/ListListeners.html
|
// REF: https://support.huaweicloud.com/api-elb/ListListeners.html
|
||||||
listenerIds := make([]string, 0)
|
hcListenerIds := make([]string, 0)
|
||||||
listListenersLimit := int32(2000)
|
listListenersLimit := int32(2000)
|
||||||
var listListenersMarker *string = nil
|
var listListenersMarker *string = nil
|
||||||
for {
|
for {
|
||||||
@ -229,7 +239,7 @@ func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error
|
|||||||
|
|
||||||
if listListenersResp.Listeners != nil {
|
if listListenersResp.Listeners != nil {
|
||||||
for _, listener := range *listListenersResp.Listeners {
|
for _, listener := range *listListenersResp.Listeners {
|
||||||
listenerIds = append(listenerIds, listener.Id)
|
hcListenerIds = append(hcListenerIds, listener.Id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +250,7 @@ func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.infos = append(d.infos, toStr("已查询到到 ELB 负载均衡器下的监听器", listenerIds))
|
d.infos = append(d.infos, toStr("已查询到 ELB 负载均衡器下的监听器", hcListenerIds))
|
||||||
|
|
||||||
// 上传证书到 SCM
|
// 上传证书到 SCM
|
||||||
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
||||||
@ -252,8 +262,8 @@ func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error
|
|||||||
|
|
||||||
// 批量更新监听器证书
|
// 批量更新监听器证书
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, listenerId := range listenerIds {
|
for _, hcListenerId := range hcListenerIds {
|
||||||
if err := d.updateListenerCertificate(ctx, listenerId, uploadResult.CertId); err != nil {
|
if err := d.updateListenerCertificate(ctx, hcListenerId, uploadResult.CertId); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +275,11 @@ func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context) error {
|
func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context) error {
|
||||||
|
hcListenerId := d.option.DeployConfig.GetConfigAsString("listenerId")
|
||||||
|
if hcListenerId == "" {
|
||||||
|
return errors.New("`listenerId` is required")
|
||||||
|
}
|
||||||
|
|
||||||
// 上传证书到 SCM
|
// 上传证书到 SCM
|
||||||
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
uploadResult, err := d.sslUploader.Upload(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -274,7 +289,7 @@ func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context) error {
|
|||||||
d.infos = append(d.infos, toStr("已上传证书", uploadResult))
|
d.infos = append(d.infos, toStr("已上传证书", uploadResult))
|
||||||
|
|
||||||
// 更新监听器证书
|
// 更新监听器证书
|
||||||
if err := d.updateListenerCertificate(ctx, d.option.DeployConfig.GetConfigAsString("listenerId"), uploadResult.CertId); err != nil {
|
if err := d.updateListenerCertificate(ctx, hcListenerId, uploadResult.CertId); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +307,7 @@ func (d *HuaweiCloudELBDeployer) updateListenerCertificate(ctx context.Context,
|
|||||||
return fmt.Errorf("failed to execute sdk request 'elb.ShowListener': %w", err)
|
return fmt.Errorf("failed to execute sdk request 'elb.ShowListener': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.infos = append(d.infos, toStr("已查询到到 ELB 监听器", showListenerResp))
|
d.infos = append(d.infos, toStr("已查询到 ELB 监听器", showListenerResp))
|
||||||
|
|
||||||
// 更新监听器
|
// 更新监听器
|
||||||
// REF: https://support.huaweicloud.com/api-elb/UpdateListener.html
|
// REF: https://support.huaweicloud.com/api-elb/UpdateListener.html
|
||||||
@ -359,7 +374,7 @@ func (d *HuaweiCloudELBDeployer) updateListenerCertificate(ctx context.Context,
|
|||||||
return fmt.Errorf("failed to execute sdk request 'elb.UpdateListener': %w", err)
|
return fmt.Errorf("failed to execute sdk request 'elb.UpdateListener': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.infos = append(d.infos, toStr("已更新监听器", updateListenerResp))
|
d.infos = append(d.infos, toStr("已更新 ELB 监听器", updateListenerResp))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ type DeployConfig struct {
|
|||||||
Config map[string]any `json:"config"`
|
Config map[string]any `json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 以字符串形式获取配置项。
|
// 以字符串形式获取配置项。
|
||||||
//
|
//
|
||||||
// 入参:
|
// 入参:
|
||||||
@ -52,6 +51,39 @@ func (dc *DeployConfig) GetConfigOrDefaultAsString(key string, defaultValue stri
|
|||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 以 32 位整数形式获取配置项。
|
||||||
|
//
|
||||||
|
// 入参:
|
||||||
|
// - key: 配置项的键。
|
||||||
|
//
|
||||||
|
// 出参:
|
||||||
|
// - 配置项的值。如果配置项不存在或者类型不是 32 位整数,则返回 0。
|
||||||
|
func (dc *DeployConfig) GetConfigAsInt32(key string) int32 {
|
||||||
|
return dc.GetConfigOrDefaultAsInt32(key, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以 32 位整数形式获取配置项。
|
||||||
|
//
|
||||||
|
// 入参:
|
||||||
|
// - key: 配置项的键。
|
||||||
|
// - defaultValue: 默认值。
|
||||||
|
//
|
||||||
|
// 出参:
|
||||||
|
// - 配置项的值。如果配置项不存在或者类型不是 32 位整数,则返回默认值。
|
||||||
|
func (dc *DeployConfig) GetConfigOrDefaultAsInt32(key string, defaultValue int32) int32 {
|
||||||
|
if dc.Config == nil {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if value, ok := dc.Config[key]; ok {
|
||||||
|
if result, ok := value.(int32); ok {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
// 以布尔形式获取配置项。
|
// 以布尔形式获取配置项。
|
||||||
//
|
//
|
||||||
// 入参:
|
// 入参:
|
||||||
|
@ -11,6 +11,7 @@ import AccessEditDialog from "./AccessEditDialog";
|
|||||||
import { Context as DeployEditContext } from "./DeployEdit";
|
import { Context as DeployEditContext } from "./DeployEdit";
|
||||||
import DeployToAliyunOSS from "./DeployToAliyunOSS";
|
import DeployToAliyunOSS from "./DeployToAliyunOSS";
|
||||||
import DeployToAliyunCDN from "./DeployToAliyunCDN";
|
import DeployToAliyunCDN from "./DeployToAliyunCDN";
|
||||||
|
import DeployToAliyunCLB from "./DeployToAliyunCLB";
|
||||||
import DeployToTencentCDN from "./DeployToTencentCDN";
|
import DeployToTencentCDN from "./DeployToTencentCDN";
|
||||||
import DeployToTencentCLB from "./DeployToTencentCLB";
|
import DeployToTencentCLB from "./DeployToTencentCLB";
|
||||||
import DeployToTencentCOS from "./DeployToTencentCOS";
|
import DeployToTencentCOS from "./DeployToTencentCOS";
|
||||||
@ -118,6 +119,9 @@ const DeployEditDialog = ({ trigger, deployConfig, onSave }: DeployEditDialogPro
|
|||||||
case "aliyun-dcdn":
|
case "aliyun-dcdn":
|
||||||
childComponent = <DeployToAliyunCDN />;
|
childComponent = <DeployToAliyunCDN />;
|
||||||
break;
|
break;
|
||||||
|
case "aliyun-clb":
|
||||||
|
childComponent = <DeployToAliyunCLB />;
|
||||||
|
break;
|
||||||
case "tencent-cdn":
|
case "tencent-cdn":
|
||||||
childComponent = <DeployToTencentCDN />;
|
childComponent = <DeployToTencentCDN />;
|
||||||
break;
|
break;
|
||||||
|
156
ui/src/components/certimate/DeployToAliyunCLB.tsx
Normal file
156
ui/src/components/certimate/DeployToAliyunCLB.tsx
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { produce } from "immer";
|
||||||
|
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
|
import { useDeployEditContext } from "./DeployEdit";
|
||||||
|
|
||||||
|
const DeployToAliyunCLB = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { deploy: data, setDeploy, error, setError } = useDeployEditContext();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!data.id) {
|
||||||
|
setDeploy({
|
||||||
|
...data,
|
||||||
|
config: {
|
||||||
|
region: "cn-hangzhou",
|
||||||
|
resourceType: "",
|
||||||
|
loadbalancerId: "",
|
||||||
|
listenerPort: "443",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setError({});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const formSchema = z
|
||||||
|
.object({
|
||||||
|
region: z.string().min(1, t("domain.deployment.form.aliyun_clb_region.placeholder")),
|
||||||
|
resourceType: z.string().min(1, t("domain.deployment.form.aliyun_clb_resource_type.placeholder")),
|
||||||
|
loadbalancerId: z.string().optional(),
|
||||||
|
listenerPort: z.string().optional(),
|
||||||
|
})
|
||||||
|
.refine((data) => (data.resourceType === "loadbalancer" || data.resourceType === "listener" ? !!data.loadbalancerId?.trim() : true), {
|
||||||
|
message: t("domain.deployment.form.aliyun_clb_loadbalancer_id.placeholder"),
|
||||||
|
path: ["loadbalancerId"],
|
||||||
|
})
|
||||||
|
.refine((data) => (data.resourceType === "listener" ? +data.listenerPort! > 0 && +data.listenerPort! < 65535 : true), {
|
||||||
|
message: t("domain.deployment.form.aliyun_clb_listener_port.placeholder"),
|
||||||
|
path: ["listenerPort"],
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const res = formSchema.safeParse(data.config);
|
||||||
|
if (!res.success) {
|
||||||
|
setError({
|
||||||
|
...error,
|
||||||
|
region: res.error.errors.find((e) => e.path[0] === "region")?.message,
|
||||||
|
resourceType: res.error.errors.find((e) => e.path[0] === "resourceType")?.message,
|
||||||
|
loadbalancerId: res.error.errors.find((e) => e.path[0] === "loadbalancerId")?.message,
|
||||||
|
listenerPort: res.error.errors.find((e) => e.path[0] === "listenerPort")?.message,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setError({
|
||||||
|
...error,
|
||||||
|
region: undefined,
|
||||||
|
resourceType: undefined,
|
||||||
|
loadbalancerId: undefined,
|
||||||
|
listenerPort: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col space-y-8">
|
||||||
|
<div>
|
||||||
|
<Label>{t("domain.deployment.form.aliyun_clb_region.label")}</Label>
|
||||||
|
<Input
|
||||||
|
placeholder={t("domain.deployment.form.aliyun_clb_region.placeholder")}
|
||||||
|
className="w-full mt-1"
|
||||||
|
value={data?.config?.region}
|
||||||
|
onChange={(e) => {
|
||||||
|
const newData = produce(data, (draft) => {
|
||||||
|
draft.config ??= {};
|
||||||
|
draft.config.region = e.target.value?.trim();
|
||||||
|
});
|
||||||
|
setDeploy(newData);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="text-red-600 text-sm mt-1">{error?.region}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>{t("domain.deployment.form.aliyun_clb_resource_type.label")}</Label>
|
||||||
|
<Select
|
||||||
|
value={data?.config?.resourceType}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const newData = produce(data, (draft) => {
|
||||||
|
draft.config ??= {};
|
||||||
|
draft.config.resourceType = value?.trim();
|
||||||
|
});
|
||||||
|
setDeploy(newData);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder={t("domain.deployment.form.aliyun_clb_resource_type.placeholder")} />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectItem value="loadbalancer">{t("domain.deployment.form.aliyun_clb_resource_type.option.loadbalancer.label")}</SelectItem>
|
||||||
|
<SelectItem value="listener">{t("domain.deployment.form.aliyun_clb_resource_type.option.listener.label")}</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<div className="text-red-600 text-sm mt-1">{error?.resourceType}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>{t("domain.deployment.form.aliyun_clb_loadbalancer_id.label")}</Label>
|
||||||
|
<Input
|
||||||
|
placeholder={t("domain.deployment.form.aliyun_clb_loadbalancer_id.placeholder")}
|
||||||
|
className="w-full mt-1"
|
||||||
|
value={data?.config?.loadbalancerId}
|
||||||
|
onChange={(e) => {
|
||||||
|
const newData = produce(data, (draft) => {
|
||||||
|
draft.config ??= {};
|
||||||
|
draft.config.loadbalancerId = e.target.value?.trim();
|
||||||
|
});
|
||||||
|
setDeploy(newData);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="text-red-600 text-sm mt-1">{error?.loadbalancerId}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{data?.config?.resourceType === "listener" ? (
|
||||||
|
<div>
|
||||||
|
<Label>{t("domain.deployment.form.aliyun_clb_listener_port.label")}</Label>
|
||||||
|
<Input
|
||||||
|
placeholder={t("domain.deployment.form.aliyun_clb_listener_port.placeholder")}
|
||||||
|
className="w-full mt-1"
|
||||||
|
value={data?.config?.listenerPort}
|
||||||
|
onChange={(e) => {
|
||||||
|
const newData = produce(data, (draft) => {
|
||||||
|
draft.config ??= {};
|
||||||
|
draft.config.listenerPort = e.target.value?.trim();
|
||||||
|
});
|
||||||
|
setDeploy(newData);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="text-red-600 text-sm mt-1">{error?.listenerPort}</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DeployToAliyunCLB;
|
@ -44,7 +44,7 @@ const DeployToHuaweiCloudCDN = () => {
|
|||||||
message: t("domain.deployment.form.huaweicloud_elb_certificate_id.placeholder"),
|
message: t("domain.deployment.form.huaweicloud_elb_certificate_id.placeholder"),
|
||||||
path: ["certificateId"],
|
path: ["certificateId"],
|
||||||
})
|
})
|
||||||
.refine((data) => (data.resourceType === "loadbalancer" ? !!data.certificateId?.trim() : true), {
|
.refine((data) => (data.resourceType === "loadbalancer" ? !!data.loadbalancerId?.trim() : true), {
|
||||||
message: t("domain.deployment.form.huaweicloud_elb_loadbalancer_id.placeholder"),
|
message: t("domain.deployment.form.huaweicloud_elb_loadbalancer_id.placeholder"),
|
||||||
path: ["loadbalancerId"],
|
path: ["loadbalancerId"],
|
||||||
})
|
})
|
||||||
|
@ -75,6 +75,7 @@ export const deployTargetsMap: Map<DeployTarget["type"], DeployTarget> = new Map
|
|||||||
["aliyun-oss", "common.provider.aliyun.oss", "/imgs/providers/aliyun.svg"],
|
["aliyun-oss", "common.provider.aliyun.oss", "/imgs/providers/aliyun.svg"],
|
||||||
["aliyun-cdn", "common.provider.aliyun.cdn", "/imgs/providers/aliyun.svg"],
|
["aliyun-cdn", "common.provider.aliyun.cdn", "/imgs/providers/aliyun.svg"],
|
||||||
["aliyun-dcdn", "common.provider.aliyun.dcdn", "/imgs/providers/aliyun.svg"],
|
["aliyun-dcdn", "common.provider.aliyun.dcdn", "/imgs/providers/aliyun.svg"],
|
||||||
|
["aliyun-clb", "common.provider.aliyun.clb", "/imgs/providers/aliyun.svg"],
|
||||||
["tencent-cdn", "common.provider.tencent.cdn", "/imgs/providers/tencent.svg"],
|
["tencent-cdn", "common.provider.tencent.cdn", "/imgs/providers/tencent.svg"],
|
||||||
["tencent-clb", "common.provider.tencent.clb", "/imgs/providers/tencent.svg"],
|
["tencent-clb", "common.provider.tencent.clb", "/imgs/providers/tencent.svg"],
|
||||||
["tencent-cos", "common.provider.tencent.cos", "/imgs/providers/tencent.svg"],
|
["tencent-cos", "common.provider.tencent.cos", "/imgs/providers/tencent.svg"],
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
"common.provider.aliyun.oss": "Alibaba Cloud - OSS",
|
"common.provider.aliyun.oss": "Alibaba Cloud - OSS",
|
||||||
"common.provider.aliyun.cdn": "Alibaba Cloud - CDN",
|
"common.provider.aliyun.cdn": "Alibaba Cloud - CDN",
|
||||||
"common.provider.aliyun.dcdn": "Alibaba Cloud - DCDN",
|
"common.provider.aliyun.dcdn": "Alibaba Cloud - DCDN",
|
||||||
|
"common.provider.aliyun.clb": "Alibaba Cloud - CLB(SLB)",
|
||||||
"common.provider.tencent": "Tencent Cloud",
|
"common.provider.tencent": "Tencent Cloud",
|
||||||
"common.provider.tencent.cdn": "Tencent Cloud - CDN",
|
"common.provider.tencent.cdn": "Tencent Cloud - CDN",
|
||||||
"common.provider.tencent.clb": "Tencent Cloud - CLB",
|
"common.provider.tencent.clb": "Tencent Cloud - CLB",
|
||||||
|
@ -61,6 +61,16 @@
|
|||||||
"domain.deployment.form.aliyun_oss_endpoint.placeholder": "Please enter endpoint",
|
"domain.deployment.form.aliyun_oss_endpoint.placeholder": "Please enter endpoint",
|
||||||
"domain.deployment.form.aliyun_oss_bucket.label": "Bucket",
|
"domain.deployment.form.aliyun_oss_bucket.label": "Bucket",
|
||||||
"domain.deployment.form.aliyun_oss_bucket.placeholder": "Please enter bucket",
|
"domain.deployment.form.aliyun_oss_bucket.placeholder": "Please enter bucket",
|
||||||
|
"domain.deployment.form.aliyun_clb_region.label": "Region",
|
||||||
|
"domain.deployment.form.aliyun_clb_region.placeholder": "Please enter region (e.g. cn-hangzhou)",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.label": "Resource Type",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.placeholder": "Please select CLB resource type",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.option.loadbalancer.label": "CLB LoadBalancer",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.option.listener.label": "CLB Listener",
|
||||||
|
"domain.deployment.form.aliyun_clb_loadbalancer_id.label": "LoadBalancer ID",
|
||||||
|
"domain.deployment.form.aliyun_clb_loadbalancer_id.placeholder": "Please enter CLB loadbalancer ID",
|
||||||
|
"domain.deployment.form.aliyun_clb_listener_port.label": "Listener Port",
|
||||||
|
"domain.deployment.form.aliyun_clb_listener_port.placeholder": "Please enter CLB listener port",
|
||||||
"domain.deployment.form.tencent_cos_region.label": "Region",
|
"domain.deployment.form.tencent_cos_region.label": "Region",
|
||||||
"domain.deployment.form.tencent_cos_region.placeholder": "Please enter region (e.g. ap-guangzhou)",
|
"domain.deployment.form.tencent_cos_region.placeholder": "Please enter region (e.g. ap-guangzhou)",
|
||||||
"domain.deployment.form.tencent_cos_bucket.label": "Bucket",
|
"domain.deployment.form.tencent_cos_bucket.label": "Bucket",
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
"common.provider.aliyun.oss": "阿里云 - OSS",
|
"common.provider.aliyun.oss": "阿里云 - OSS",
|
||||||
"common.provider.aliyun.cdn": "阿里云 - CDN",
|
"common.provider.aliyun.cdn": "阿里云 - CDN",
|
||||||
"common.provider.aliyun.dcdn": "阿里云 - DCDN",
|
"common.provider.aliyun.dcdn": "阿里云 - DCDN",
|
||||||
|
"common.provider.aliyun.clb": "阿里云 - CLB(原 SLB)",
|
||||||
"common.provider.tencent": "腾讯云",
|
"common.provider.tencent": "腾讯云",
|
||||||
"common.provider.tencent.cos": "腾讯云 - COS",
|
"common.provider.tencent.cos": "腾讯云 - COS",
|
||||||
"common.provider.tencent.cdn": "腾讯云 - CDN",
|
"common.provider.tencent.cdn": "腾讯云 - CDN",
|
||||||
|
@ -61,6 +61,16 @@
|
|||||||
"domain.deployment.form.aliyun_oss_endpoint.placeholder": "请输入 Endpoint",
|
"domain.deployment.form.aliyun_oss_endpoint.placeholder": "请输入 Endpoint",
|
||||||
"domain.deployment.form.aliyun_oss_bucket.label": "存储桶",
|
"domain.deployment.form.aliyun_oss_bucket.label": "存储桶",
|
||||||
"domain.deployment.form.aliyun_oss_bucket.placeholder": "请输入存储桶名",
|
"domain.deployment.form.aliyun_oss_bucket.placeholder": "请输入存储桶名",
|
||||||
|
"domain.deployment.form.aliyun_clb_region.label": "地域",
|
||||||
|
"domain.deployment.form.aliyun_clb_region.placeholder": "请输入地域(如 cn-hangzhou)",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.label": "替换方式",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.placeholder": "请选择替换方式",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.option.loadbalancer.label": "替换指定负载均衡器的全部监听的证书",
|
||||||
|
"domain.deployment.form.aliyun_clb_resource_type.option.listener.label": "替换指定负载均衡器监听的证书",
|
||||||
|
"domain.deployment.form.aliyun_clb_loadbalancer_id.label": "负载均衡器 ID",
|
||||||
|
"domain.deployment.form.aliyun_clb_loadbalancer_id.placeholder": "请输入负载均衡器 ID",
|
||||||
|
"domain.deployment.form.aliyun_clb_listener_port.label": "监听端口",
|
||||||
|
"domain.deployment.form.aliyun_clb_listener_port.placeholder": "请输入监听端口",
|
||||||
"domain.deployment.form.tencent_cos_region.label": "地域",
|
"domain.deployment.form.tencent_cos_region.label": "地域",
|
||||||
"domain.deployment.form.tencent_cos_region.placeholder": "请输入地域(如 ap-guangzhou)",
|
"domain.deployment.form.tencent_cos_region.placeholder": "请输入地域(如 ap-guangzhou)",
|
||||||
"domain.deployment.form.tencent_cos_bucket.label": "存储桶",
|
"domain.deployment.form.tencent_cos_bucket.label": "存储桶",
|
||||||
@ -75,17 +85,17 @@
|
|||||||
"domain.deployment.form.tencent_clb_domain.placeholder": "请输入部署到的域名, 如未开启 SNI, 可置空忽略此项",
|
"domain.deployment.form.tencent_clb_domain.placeholder": "请输入部署到的域名, 如未开启 SNI, 可置空忽略此项",
|
||||||
"domain.deployment.form.huaweicloud_elb_region.label": "地域",
|
"domain.deployment.form.huaweicloud_elb_region.label": "地域",
|
||||||
"domain.deployment.form.huaweicloud_elb_region.placeholder": "请输入地域(如 cn-north-1)",
|
"domain.deployment.form.huaweicloud_elb_region.placeholder": "请输入地域(如 cn-north-1)",
|
||||||
"domain.deployment.form.huaweicloud_elb_resource_type.label": "资源类型替换方式",
|
"domain.deployment.form.huaweicloud_elb_resource_type.label": "替换方式",
|
||||||
"domain.deployment.form.huaweicloud_elb_resource_type.placeholder": "请选择资源类型替换方式",
|
"domain.deployment.form.huaweicloud_elb_resource_type.placeholder": "请选择替换方式",
|
||||||
"domain.deployment.form.huaweicloud_elb_resource_type.option.certificate.label": "按证书替换",
|
"domain.deployment.form.huaweicloud_elb_resource_type.option.certificate.label": "替换指定证书",
|
||||||
"domain.deployment.form.huaweicloud_elb_resource_type.option.loadbalancer.label": "按负载均衡器替换",
|
"domain.deployment.form.huaweicloud_elb_resource_type.option.loadbalancer.label": "替换指定负载均衡器的全部监听器的证书",
|
||||||
"domain.deployment.form.huaweicloud_elb_resource_type.option.listener.label": "按监听器替换",
|
"domain.deployment.form.huaweicloud_elb_resource_type.option.listener.label": "替换指定监听器",
|
||||||
"domain.deployment.form.huaweicloud_elb_certificate_id.label": "证书 ID",
|
"domain.deployment.form.huaweicloud_elb_certificate_id.label": "证书 ID",
|
||||||
"domain.deployment.form.huaweicloud_elb_certificate_id.placeholder": "请输入证书 ID(可从华为云控制面板获取)",
|
"domain.deployment.form.huaweicloud_elb_certificate_id.placeholder": "请输入证书 ID",
|
||||||
"domain.deployment.form.huaweicloud_elb_loadbalancer_id.label": "负载均衡器 ID",
|
"domain.deployment.form.huaweicloud_elb_loadbalancer_id.label": "负载均衡器 ID",
|
||||||
"domain.deployment.form.huaweicloud_elb_loadbalancer_id.placeholder": "请输入负载均衡器 ID(可从华为云控制面板获取)",
|
"domain.deployment.form.huaweicloud_elb_loadbalancer_id.placeholder": "请输入负载均衡器 ID",
|
||||||
"domain.deployment.form.huaweicloud_elb_listener_id.label": "监听器 ID",
|
"domain.deployment.form.huaweicloud_elb_listener_id.label": "监听器 ID",
|
||||||
"domain.deployment.form.huaweicloud_elb_listener_id.placeholder": "请输入监听器 ID(可从华为云控制面板获取)",
|
"domain.deployment.form.huaweicloud_elb_listener_id.placeholder": "请输入监听器 ID",
|
||||||
"domain.deployment.form.ssh_key_path.label": "私钥保存路径",
|
"domain.deployment.form.ssh_key_path.label": "私钥保存路径",
|
||||||
"domain.deployment.form.ssh_key_path.placeholder": "请输入私钥保存路径",
|
"domain.deployment.form.ssh_key_path.placeholder": "请输入私钥保存路径",
|
||||||
"domain.deployment.form.ssh_cert_path.label": "证书保存路径",
|
"domain.deployment.form.ssh_cert_path.label": "证书保存路径",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user