mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
feat(provider): new deployment provider: byteplus alb
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package deployers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/domain"
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
dplyimpl "github.com/certimate-go/certimate/pkg/core/deployer/providers/byteplus-alb"
|
||||
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Registries.MustRegister(domain.DeploymentProviderTypeBytePlusALB, func(options *ProviderFactoryOptions) (core.Deployer, error) {
|
||||
credentials := domain.AccessConfigForBytePlus{}
|
||||
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
|
||||
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
||||
}
|
||||
|
||||
provider, err := dplyimpl.NewDeployer(&dplyimpl.DeployerConfig{
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
SecretAccessKey: credentials.SecretAccessKey,
|
||||
ProjectName: credentials.ProjectName,
|
||||
Region: xmaps.GetString(options.ProviderExtendedConfig, "region"),
|
||||
DeployTarget: xmaps.GetString(options.ProviderExtendedConfig, "deployTarget"),
|
||||
LoadbalancerId: xmaps.GetString(options.ProviderExtendedConfig, "loadbalancerId"),
|
||||
ListenerId: xmaps.GetString(options.ProviderExtendedConfig, "listenerId"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
})
|
||||
return provider, err
|
||||
})
|
||||
}
|
||||
@@ -338,6 +338,7 @@ const (
|
||||
DeploymentProviderTypeBaotaWAF = DeploymentProviderType(AccessProviderTypeBaotaWAF)
|
||||
DeploymentProviderTypeBaotaWAFConsole = DeploymentProviderType(AccessProviderTypeBaotaWAF + "-console")
|
||||
DeploymentProviderTypeBunnyCDN = DeploymentProviderType(AccessProviderTypeBunny + "-cdn")
|
||||
DeploymentProviderTypeBytePlusALB = DeploymentProviderType(AccessProviderTypeBytePlus + "-alb")
|
||||
DeploymentProviderTypeBytePlusCDN = DeploymentProviderType(AccessProviderTypeBytePlus + "-cdn")
|
||||
DeploymentProviderTypeBytePlusCertCenter = DeploymentProviderType(AccessProviderTypeBytePlus + "-certcenter")
|
||||
DeploymentProviderTypeBytePlusMediaLive = DeploymentProviderType(AccessProviderTypeBytePlus + "-medialive")
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
package byteplusalb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
bp "github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
bpsession "github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/session"
|
||||
"github.com/samber/lo"
|
||||
|
||||
bpalb "github.com/certimate-go/certimate/pkg/sdk3rd-trimmed/github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
cmgrimpl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/byteplus-certcenter"
|
||||
)
|
||||
|
||||
type (
|
||||
Provider = core.Deployer
|
||||
DeployResult = core.DeployerDeployResult
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
// BytePlus AccessKeyId。
|
||||
AccessKeyId string `json:"accessKeyId"`
|
||||
// BytePlus SecretAccessKey。
|
||||
SecretAccessKey string `json:"secretAccessKey"`
|
||||
// BytePlus 项目名称。
|
||||
ProjectName string `json:"projectName,omitempty"`
|
||||
// BytePlus 地域。
|
||||
Region string `json:"region"`
|
||||
// 部署目标。
|
||||
DeployTarget string `json:"deployTarget"`
|
||||
// 负载均衡实例 ID。
|
||||
// 部署目标为 [DEPLOY_TARGET_LOADBALANCER] 时必填。
|
||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||
// 负载均衡监听器 ID。
|
||||
// 部署目标为 [DEPLOY_TARGET_LISTENER] 时必填。
|
||||
ListenerId string `json:"listenerId,omitempty"`
|
||||
// SNI 域名(支持泛域名)。
|
||||
// 部署目标为 [DEPLOY_TARGET_LOADBALANCER]、[DEPLOY_TARGET_LISTENER] 时选填。
|
||||
Domain string `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
type Deployer struct {
|
||||
config *DeployerConfig
|
||||
logger *slog.Logger
|
||||
sdkClient *bpalb.ALB
|
||||
sdkCertmgr core.Certmgr
|
||||
}
|
||||
|
||||
var _ Provider = (*Deployer)(nil)
|
||||
|
||||
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
|
||||
}
|
||||
|
||||
client, err := createSDKClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create client: %w", err)
|
||||
}
|
||||
|
||||
pcertmgr, err := cmgrimpl.NewCertmgr(&cmgrimpl.CertmgrConfig{
|
||||
AccessKeyId: config.AccessKeyId,
|
||||
SecretAccessKey: config.SecretAccessKey,
|
||||
ProjectName: config.ProjectName,
|
||||
Region: "ap-singapore-1",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create certmgr: %w", err)
|
||||
}
|
||||
|
||||
return &Deployer{
|
||||
config: config,
|
||||
logger: slog.Default(),
|
||||
sdkClient: client,
|
||||
sdkCertmgr: pcertmgr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Deployer) SetLogger(logger *slog.Logger) {
|
||||
if logger == nil {
|
||||
d.logger = slog.New(slog.DiscardHandler)
|
||||
} else {
|
||||
d.logger = logger
|
||||
}
|
||||
|
||||
d.sdkCertmgr.SetLogger(logger)
|
||||
}
|
||||
|
||||
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*DeployResult, error) {
|
||||
// 上传证书
|
||||
upres, err := d.sdkCertmgr.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))
|
||||
}
|
||||
|
||||
// 根据部署目标决定业务流程
|
||||
switch d.config.DeployTarget {
|
||||
case DEPLOY_TARGET_LOADBALANCER:
|
||||
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case DEPLOY_TARGET_LISTENER:
|
||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported deploy target '%s'", d.config.DeployTarget)
|
||||
}
|
||||
|
||||
return &DeployResult{}, nil
|
||||
}
|
||||
|
||||
func (d *Deployer) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
|
||||
if d.config.LoadbalancerId == "" {
|
||||
return fmt.Errorf("config `loadbalancerId` is required")
|
||||
}
|
||||
|
||||
// 查询 ALB 实例的详细信息
|
||||
describeLoadBalancerAttributesReq := &bpalb.DescribeLoadBalancerAttributesInput{
|
||||
LoadBalancerId: bp.String(d.config.LoadbalancerId),
|
||||
}
|
||||
describeLoadBalancerAttributesResp, err := d.sdkClient.DescribeLoadBalancerAttributes(describeLoadBalancerAttributesReq)
|
||||
d.logger.Debug("sdk request 'alb.DescribeLoadBalancerAttributes'", slog.Any("request", describeLoadBalancerAttributesReq), slog.Any("response", describeLoadBalancerAttributesResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.DescribeLoadBalancerAttributes': %w", err)
|
||||
}
|
||||
|
||||
// 查询 HTTPS 监听器列表
|
||||
listenerIds := make([]string, 0)
|
||||
describeListenersPageSize := 100
|
||||
describeListenersPageNumber := 1
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
describeListenersReq := &bpalb.DescribeListenersInput{
|
||||
ProjectName: lo.EmptyableToPtr(d.config.ProjectName),
|
||||
LoadBalancerId: bp.String(d.config.LoadbalancerId),
|
||||
Protocol: bp.String("HTTPS"),
|
||||
PageNumber: bp.Int64(int64(describeListenersPageNumber)),
|
||||
PageSize: bp.Int64(int64(describeListenersPageSize)),
|
||||
}
|
||||
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
|
||||
d.logger.Debug("sdk request 'alb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.DescribeListeners': %w", err)
|
||||
}
|
||||
|
||||
for _, listener := range describeListenersResp.Listeners {
|
||||
listenerIds = append(listenerIds, *listener.ListenerId)
|
||||
}
|
||||
|
||||
if len(describeListenersResp.Listeners) < describeListenersPageSize {
|
||||
break
|
||||
}
|
||||
|
||||
describeListenersPageNumber++
|
||||
}
|
||||
|
||||
// 遍历更新监听证书
|
||||
if len(listenerIds) == 0 {
|
||||
d.logger.Info("no alb listeners to deploy")
|
||||
} else {
|
||||
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
|
||||
var errs []error
|
||||
|
||||
for _, listenerId := range listenerIds {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
if err := d.updateListenerCertificate(ctx, listenerId, cloudCertId); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Deployer) deployToListener(ctx context.Context, cloudCertId string) error {
|
||||
if d.config.ListenerId == "" {
|
||||
return fmt.Errorf("config `listenerId` is required")
|
||||
}
|
||||
|
||||
if err := d.updateListenerCertificate(ctx, d.config.ListenerId, cloudCertId); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Deployer) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
|
||||
// 查询指定监听器的详细信息
|
||||
describeListenerAttributesReq := &bpalb.DescribeListenerAttributesInput{
|
||||
ListenerId: bp.String(cloudListenerId),
|
||||
}
|
||||
describeListenerAttributesResp, err := d.sdkClient.DescribeListenerAttributesWithContext(ctx, describeListenerAttributesReq)
|
||||
d.logger.Debug("sdk request 'alb.DescribeListenerAttributes'", slog.Any("request", describeListenerAttributesReq), slog.Any("response", describeListenerAttributesResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.DescribeListenerAttributes': %w", err)
|
||||
}
|
||||
|
||||
if d.config.Domain == "" {
|
||||
// 未指定 SNI,只需部署到监听器
|
||||
|
||||
// 修改指定监听器
|
||||
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
|
||||
ListenerId: bp.String(cloudListenerId),
|
||||
CertificateSource: bp.String("cert_center"),
|
||||
CertCenterCertificateId: bp.String(cloudCertId),
|
||||
}
|
||||
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
|
||||
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
|
||||
}
|
||||
} else {
|
||||
// 指定 SNI,需部署到扩展域名
|
||||
|
||||
// 修改指定监听器
|
||||
modifyListenerAttributesReq := &bpalb.ModifyListenerAttributesInput{
|
||||
ListenerId: bp.String(cloudListenerId),
|
||||
DomainExtensions: lo.Map(
|
||||
lo.Filter(
|
||||
describeListenerAttributesResp.DomainExtensions,
|
||||
func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) bool {
|
||||
return *domain.Domain == d.config.Domain
|
||||
},
|
||||
),
|
||||
func(domain *bpalb.DomainExtensionForDescribeListenerAttributesOutput, _ int) *bpalb.DomainExtensionForModifyListenerAttributesInput {
|
||||
return &bpalb.DomainExtensionForModifyListenerAttributesInput{
|
||||
DomainExtensionId: domain.DomainExtensionId,
|
||||
Domain: domain.Domain,
|
||||
CertificateSource: bp.String("cert_center"),
|
||||
CertCenterCertificateId: bp.String(cloudCertId),
|
||||
Action: bp.String("modify"),
|
||||
}
|
||||
}),
|
||||
}
|
||||
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributesWithContext(ctx, modifyListenerAttributesReq)
|
||||
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'alb.ModifyListenerAttributes': %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createSDKClient(accessKeyId, secretAccessKey, region string) (*bpalb.ALB, error) {
|
||||
config := bp.NewConfig().
|
||||
WithAkSk(accessKeyId, secretAccessKey).
|
||||
WithRegion(region)
|
||||
|
||||
session, err := bpsession.NewSession(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := bpalb.New(session)
|
||||
return client, nil
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package byteplusalb_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/internal/tester"
|
||||
impl "github.com/certimate-go/certimate/pkg/core/deployer/providers/byteplus-alb"
|
||||
)
|
||||
|
||||
var (
|
||||
fp = tester.Args("BYTEPLUSALB_")
|
||||
fTestCertPath string
|
||||
fTestKeyPath string
|
||||
fAccessKeyId string
|
||||
fSecretAccessKey string
|
||||
fRegion string
|
||||
fListenerId string
|
||||
)
|
||||
|
||||
func init() {
|
||||
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
|
||||
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
|
||||
fp.DefineString(&fAccessKeyId, "ACCESSKEYID")
|
||||
fp.DefineString(&fSecretAccessKey, "SECRETACCESSKEY")
|
||||
fp.DefineString(&fRegion, "REGION")
|
||||
fp.DefineString(&fListenerId, "LISTENERID")
|
||||
}
|
||||
|
||||
/*
|
||||
Shell command to run this test:
|
||||
|
||||
go test -v ./byteplus_alb_test.go -args \
|
||||
--BYTEPLUSALB_TESTCERTPATH="/path/to/your-test-cert.pem" \
|
||||
--BYTEPLUSALB_TESTKEYPATH="/path/to/your-test-key.pem" \
|
||||
--BYTEPLUSALB_ACCESSKEYID="your-access-key-id" \
|
||||
--BYTEPLUSALB_SECRETACCESSKEY="your-secret-access-key" \
|
||||
--BYTEPLUSALB_REGION="ap-southeast-1" \
|
||||
--BYTEPLUSALB_LISTENERID="your-listener-id"
|
||||
*/
|
||||
func TestProvider(t *testing.T) {
|
||||
fp.Parse()
|
||||
|
||||
t.Run("Deploy_ToListener", func(t *testing.T) {
|
||||
provider, err := impl.NewDeployer(&impl.DeployerConfig{
|
||||
AccessKeyId: fAccessKeyId,
|
||||
SecretAccessKey: fSecretAccessKey,
|
||||
Region: fRegion,
|
||||
DeployTarget: impl.DEPLOY_TARGET_LISTENER,
|
||||
ListenerId: fListenerId,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("err: %+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
tester.TestDeploy(t, provider, tester.TestDeployArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package byteplusalb
|
||||
|
||||
const (
|
||||
// 部署目标:部署到指定负载均衡器。
|
||||
DEPLOY_TARGET_LOADBALANCER = "loadbalancer"
|
||||
// 部署目标:部署到指定监听器。
|
||||
DEPLOY_TARGET_LISTENER = "listener"
|
||||
)
|
||||
@@ -54,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*Deployer, error) {
|
||||
AccessKeyId: config.AccessKeyId,
|
||||
SecretAccessKey: config.SecretAccessKey,
|
||||
ProjectName: config.ProjectName,
|
||||
Region: config.Region,
|
||||
Region: "ap-singapore-1",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create certmgr: %w", err)
|
||||
|
||||
@@ -36,7 +36,7 @@ Shell command to run this test:
|
||||
--BYTEPLUSTOS_TESTKEYPATH="/path/to/your-test-key.pem" \
|
||||
--BYTEPLUSTOS_ACCESSKEYID="your-access-key-id" \
|
||||
--BYTEPLUSTOS_SECRETACCESSKEY="your-secret-access-key" \
|
||||
--BYTEPLUSTOS_REGION="cn-beijing" \
|
||||
--BYTEPLUSTOS_REGION="ap-southeast-1" \
|
||||
--BYTEPLUSTOS_BUCKET="your-tos-bucket" \
|
||||
--BYTEPLUSTOS_DOMAIN="example.com"
|
||||
*/
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package alb
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
)
|
||||
|
||||
const opDescribeListenerAttributes = "DescribeListenerAttributes"
|
||||
|
||||
func (c *ALB) DescribeListenerAttributesRequest(input *DescribeListenerAttributesInput) (req *request.Request, output *DescribeListenerAttributesOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opDescribeListenerAttributes,
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DescribeListenerAttributesInput{}
|
||||
}
|
||||
|
||||
output = &DescribeListenerAttributesOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ALB) DescribeListenerAttributesWithContext(ctx byteplus.Context, input *DescribeListenerAttributesInput, opts ...request.Option) (*DescribeListenerAttributesOutput, error) {
|
||||
req, out := c.DescribeListenerAttributesRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type DescribeListenerAttributesInput = alb.DescribeListenerAttributesInput
|
||||
|
||||
type DescribeListenerAttributesOutput = alb.DescribeListenerAttributesOutput
|
||||
|
||||
type DomainExtensionForDescribeListenerAttributesOutput = alb.DomainExtensionForDescribeListenerAttributesOutput
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package alb
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
)
|
||||
|
||||
const opDescribeListeners = "DescribeListeners"
|
||||
|
||||
func (c *ALB) DescribeListenersRequest(input *DescribeListenersInput) (req *request.Request, output *DescribeListenersOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opDescribeListeners,
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DescribeListenersInput{}
|
||||
}
|
||||
|
||||
output = &DescribeListenersOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ALB) DescribeListeners(input *DescribeListenersInput) (*DescribeListenersOutput, error) {
|
||||
req, out := c.DescribeListenersRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
func (c *ALB) DescribeListenersWithContext(ctx byteplus.Context, input *DescribeListenersInput, opts ...request.Option) (*DescribeListenersOutput, error) {
|
||||
req, out := c.DescribeListenersRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type DescribeListenersInput = alb.DescribeListenersInput
|
||||
|
||||
type DescribeListenersOutput = alb.DescribeListenersOutput
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package alb
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
)
|
||||
|
||||
const opDescribeLoadBalancerAttributes = "DescribeLoadBalancerAttributes"
|
||||
|
||||
func (c *ALB) DescribeLoadBalancerAttributesRequest(input *DescribeLoadBalancerAttributesInput) (req *request.Request, output *DescribeLoadBalancerAttributesOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opDescribeLoadBalancerAttributes,
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DescribeLoadBalancerAttributesInput{}
|
||||
}
|
||||
|
||||
output = &DescribeLoadBalancerAttributesOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ALB) DescribeLoadBalancerAttributes(input *DescribeLoadBalancerAttributesInput) (*DescribeLoadBalancerAttributesOutput, error) {
|
||||
req, out := c.DescribeLoadBalancerAttributesRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
func (c *ALB) DescribeLoadBalancerAttributesWithContext(ctx byteplus.Context, input *DescribeLoadBalancerAttributesInput, opts ...request.Option) (*DescribeLoadBalancerAttributesOutput, error) {
|
||||
req, out := c.DescribeLoadBalancerAttributesRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type DescribeLoadBalancerAttributesInput = alb.DescribeLoadBalancerAttributesInput
|
||||
|
||||
type DescribeLoadBalancerAttributesOutput = alb.DescribeLoadBalancerAttributesOutput
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package alb
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
)
|
||||
|
||||
const opModifyListenerAttributes = "ModifyListenerAttributes"
|
||||
|
||||
func (c *ALB) ModifyListenerAttributesRequest(input *ModifyListenerAttributesInput) (req *request.Request, output *ModifyListenerAttributesOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opModifyListenerAttributes,
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &ModifyListenerAttributesInput{}
|
||||
}
|
||||
|
||||
output = &ModifyListenerAttributesOutput{}
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *ALB) ModifyListenerAttributes(input *ModifyListenerAttributesInput) (*ModifyListenerAttributesOutput, error) {
|
||||
req, out := c.ModifyListenerAttributesRequest(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
func (c *ALB) ModifyListenerAttributesWithContext(ctx byteplus.Context, input *ModifyListenerAttributesInput, opts ...request.Option) (*ModifyListenerAttributesOutput, error) {
|
||||
req, out := c.ModifyListenerAttributesRequest(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type ModifyListenerAttributesInput = alb.ModifyListenerAttributesInput
|
||||
|
||||
type ModifyListenerAttributesOutput = alb.ModifyListenerAttributesOutput
|
||||
|
||||
type DomainExtensionForModifyListenerAttributesInput = alb.DomainExtensionForModifyListenerAttributesInput
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package alb
|
||||
|
||||
import (
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/byteplusquery"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/client"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/client/metadata"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/corehandlers"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/request"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/byteplus/signer/byteplussign"
|
||||
"github.com/byteplus-sdk/byteplus-go-sdk-v2/service/alb"
|
||||
)
|
||||
|
||||
type ALB struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
const (
|
||||
ServiceName = alb.ServiceName
|
||||
EndpointsID = alb.EndpointsID
|
||||
ServiceID = alb.ServiceID
|
||||
)
|
||||
|
||||
func New(p client.ConfigProvider, cfgs ...*byteplus.Config) *ALB {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
func newClient(cfg byteplus.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *ALB {
|
||||
svc := &ALB{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2020-04-01",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
svc.Handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
svc.Handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHandler)
|
||||
svc.Handlers.Sign.PushBackNamed(byteplussign.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(byteplusquery.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(byteplusquery.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(byteplusquery.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(byteplusquery.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *ALB) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import BizDeployNodeConfigFieldsProviderBaotaPanelGoConsole from "./BizDeployNod
|
||||
import BizDeployNodeConfigFieldsProviderBaotaWAF from "./BizDeployNodeConfigFieldsProviderBaotaWAF";
|
||||
import BizDeployNodeConfigFieldsProviderBaotaWAFConsole from "./BizDeployNodeConfigFieldsProviderBaotaWAFConsole";
|
||||
import BizDeployNodeConfigFieldsProviderBunnyCDN from "./BizDeployNodeConfigFieldsProviderBunnyCDN";
|
||||
import BizDeployNodeConfigFieldsProviderBytePlusALB from "./BizDeployNodeConfigFieldsProviderBytePlusALB";
|
||||
import BizDeployNodeConfigFieldsProviderBytePlusCDN from "./BizDeployNodeConfigFieldsProviderBytePlusCDN";
|
||||
import BizDeployNodeConfigFieldsProviderBytePlusCertCenter from "./BizDeployNodeConfigFieldsProviderBytePlusCertCenter";
|
||||
import BizDeployNodeConfigFieldsProviderBytePlusMediaLive from "./BizDeployNodeConfigFieldsProviderBytePlusMediaLive";
|
||||
@@ -167,6 +168,7 @@ const providerComponentMap: Partial<Record<DeploymentProviderType, React.Compone
|
||||
[DEPLOYMENT_PROVIDERS.BAOTAWAF]: BizDeployNodeConfigFieldsProviderBaotaWAF,
|
||||
[DEPLOYMENT_PROVIDERS.BAOTAWAF_CONSOLE]: BizDeployNodeConfigFieldsProviderBaotaWAFConsole,
|
||||
[DEPLOYMENT_PROVIDERS.BUNNY_CDN]: BizDeployNodeConfigFieldsProviderBunnyCDN,
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_ALB]: BizDeployNodeConfigFieldsProviderBytePlusALB,
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_CDN]: BizDeployNodeConfigFieldsProviderBytePlusCDN,
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_CERTCENTER]: BizDeployNodeConfigFieldsProviderBytePlusCertCenter,
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_MEDIALIVE]: BizDeployNodeConfigFieldsProviderBytePlusMediaLive,
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import { isDomain } from "@/utils/validator";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const DEPLOY_TARGET_LOADBALANCER = "loadbalancer" as const;
|
||||
const DEPLOY_TARGET_LISTENER = "listener" as const;
|
||||
|
||||
const BizDeployNodeConfigFieldsProviderBytePlusALB = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const { parentNamePath } = useFormNestedFieldsContext();
|
||||
const formSchema = z.object({
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const formInst = Form.useFormInstance();
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
const fieldResourceType = Form.useWatch([parentNamePath, "deployTarget"], formInst);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.byteplus_alb_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.byteplus_alb_region.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.byteplus_alb_region.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "deployTarget"]}
|
||||
initialValue={initialValues.deployTarget}
|
||||
label={t("workflow_node.deploy.form.shared_deploy_target.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Select
|
||||
options={[DEPLOY_TARGET_LOADBALANCER, DEPLOY_TARGET_LISTENER].map((s) => ({
|
||||
value: s,
|
||||
label: t(`workflow_node.deploy.form.byteplus_alb_deploy_target.option.${s}.label`),
|
||||
}))}
|
||||
placeholder={t("workflow_node.deploy.form.shared_deploy_target.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Show when={fieldResourceType === DEPLOY_TARGET_LOADBALANCER}>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "loadbalancerId"]}
|
||||
initialValue={initialValues.loadbalancerId}
|
||||
label={t("workflow_node.deploy.form.byteplus_alb_loadbalancer_id.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.byteplus_alb_loadbalancer_id.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.byteplus_alb_loadbalancer_id.placeholder")} />
|
||||
</Form.Item>
|
||||
</Show>
|
||||
|
||||
<Show when={fieldResourceType === DEPLOY_TARGET_LISTENER}>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "listenerId"]}
|
||||
initialValue={initialValues.listenerId}
|
||||
label={t("workflow_node.deploy.form.byteplus_alb_listener_id.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.byteplus_alb_listener_id.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.byteplus_alb_listener_id.placeholder")} />
|
||||
</Form.Item>
|
||||
</Show>
|
||||
|
||||
<Show when={fieldResourceType === DEPLOY_TARGET_LOADBALANCER || fieldResourceType === DEPLOY_TARGET_LISTENER}>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.byteplus_alb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.byteplus_alb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Input allowClear placeholder={t("workflow_node.deploy.form.byteplus_alb_snidomain.placeholder")} />
|
||||
</Form.Item>
|
||||
</Show>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
deployTarget: DEPLOY_TARGET_LISTENER,
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
.object({
|
||||
region: z.string().nonempty(),
|
||||
deployTarget: z.enum([DEPLOY_TARGET_LOADBALANCER, DEPLOY_TARGET_LISTENER]),
|
||||
loadbalancerId: z.string().nullish(),
|
||||
listenerId: z.string().nullish(),
|
||||
domain: z
|
||||
.string()
|
||||
.nullish()
|
||||
.refine((v) => {
|
||||
if (!v) return true;
|
||||
return isDomain(v, { allowWildcard: true });
|
||||
}, t("common.errmsg.domain_invalid")),
|
||||
})
|
||||
.superRefine((values, ctx) => {
|
||||
switch (values.deployTarget) {
|
||||
case DEPLOY_TARGET_LOADBALANCER:
|
||||
{
|
||||
const scLoadbalancerId = z.string().nonempty();
|
||||
const spLoadbalancerId = scLoadbalancerId.safeParse(values.loadbalancerId);
|
||||
if (!spLoadbalancerId.success) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: z.treeifyError(spLoadbalancerId.error).errors.join(),
|
||||
path: ["loadbalancerId"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DEPLOY_TARGET_LISTENER:
|
||||
{
|
||||
const scListenerId = z.string().nonempty();
|
||||
const spListenerId = scListenerId.safeParse(values.listenerId);
|
||||
if (!spListenerId.success) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: z.treeifyError(spListenerId.error).errors.join(),
|
||||
path: ["listenerId"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(BizDeployNodeConfigFieldsProviderBytePlusALB, {
|
||||
getInitialValues,
|
||||
getSchema,
|
||||
});
|
||||
|
||||
export default _default;
|
||||
@@ -621,6 +621,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
|
||||
BAOTAWAF: `${ACCESS_PROVIDERS.BAOTAWAF}`,
|
||||
BAOTAWAF_CONSOLE: `${ACCESS_PROVIDERS.BAOTAWAF}-console`,
|
||||
BUNNY_CDN: `${ACCESS_PROVIDERS.BUNNY}-cdn`,
|
||||
BYTEPLUS_ALB: `${ACCESS_PROVIDERS.BYTEPLUS}-alb`,
|
||||
BYTEPLUS_CDN: `${ACCESS_PROVIDERS.BYTEPLUS}-cdn`,
|
||||
BYTEPLUS_CERTCENTER: `${ACCESS_PROVIDERS.BYTEPLUS}-certcenter`,
|
||||
BYTEPLUS_MEDIALIVE: `${ACCESS_PROVIDERS.BYTEPLUS}-medialive`,
|
||||
@@ -829,6 +830,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
|
||||
[DEPLOYMENT_PROVIDERS.KSYUN_SLB, "provider.ksyun_slb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_TOS, "provider.byteplus_tos", DEPLOYMENT_CATEGORIES.STORAGE],
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_CDN, "provider.byteplus_cdn", DEPLOYMENT_CATEGORIES.CDN],
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_ALB, "provider.byteplus_alb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_MEDIALIVE, "provider.byteplus_medialive", DEPLOYMENT_CATEGORIES.AV],
|
||||
[DEPLOYMENT_PROVIDERS.BYTEPLUS_CERTCENTER, "provider.byteplus_certcenter_upload", DEPLOYMENT_CATEGORIES.SSL],
|
||||
[DEPLOYMENT_PROVIDERS.UCLOUD_US3, "provider.ucloud_us3", DEPLOYMENT_CATEGORIES.STORAGE],
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"bunny": "Bunny",
|
||||
"bunny_cdn": "Bunny - CDN (Content Delivery Network)",
|
||||
"byteplus": "BytePlus",
|
||||
"byteplus_alb": "BytePlus - ALB (Application Load Balancer)",
|
||||
"byteplus_cdn": "BytePlus - CDN (Content Delivery Network)",
|
||||
"byteplus_certcenter_upload": "BytePlus - Upload to Certificate Center",
|
||||
"byteplus_dns": "BytePlus - DNS Suite",
|
||||
|
||||
@@ -1209,6 +1209,36 @@
|
||||
"placeholder": "Please enter Bunny CDN hostname",
|
||||
"tooltip": "What is this? See <a href=\"https://dash.bunny.net/cdn\" target=\"_blank\">https://dash.bunny.net/cdn</a>"
|
||||
},
|
||||
"byteplus_alb_region": {
|
||||
"label": "BytePlus region",
|
||||
"placeholder": "Please enter BytePlus ALB region (e.g. ap-southeast-1)",
|
||||
"tooltip": "For more information, see <a href=\"https://docs.byteplus.com/en/docs/clb/Regions-and-Availability-Zones\" target=\"_blank\">https://docs.byteplus.com/en/docs/clb/Regions-and-Availability-Zones</a>"
|
||||
},
|
||||
"byteplus_alb_deploy_target": {
|
||||
"option": {
|
||||
"loadbalancer": {
|
||||
"label": "ALB load balancer"
|
||||
},
|
||||
"listener": {
|
||||
"label": "ALB listener"
|
||||
}
|
||||
}
|
||||
},
|
||||
"byteplus_alb_loadbalancer_id": {
|
||||
"label": "BytePlus ALB load balancer ID",
|
||||
"placeholder": "Please enter BytePlus ALB load balancer ID",
|
||||
"tooltip": "For more information, see <a href=\"https://console.byteplus.com/alb\" target=\"_blank\">https://console.byteplus.com/alb</a>"
|
||||
},
|
||||
"byteplus_alb_listener_id": {
|
||||
"label": "BytePlus ALB listener ID",
|
||||
"placeholder": "Please enter BytePlus ALB listener ID",
|
||||
"tooltip": "For more information, see <a href=\"https://console.byteplus.com/alb\" target=\"_blank\">https://console.byteplus.com/alb</a>"
|
||||
},
|
||||
"byteplus_alb_snidomain": {
|
||||
"label": "BytePlus ALB SNI domain (Optional)",
|
||||
"placeholder": "Please enter BytePlus ALB SNI domain name",
|
||||
"help": "Notes: Leave it blank to set the default certificate; otherwise, to set the extension one for SNI."
|
||||
},
|
||||
"byteplus_cdn_domain": {
|
||||
"label": "BytePlus CDN domain",
|
||||
"placeholder": "Please enter BytePlus CDN domain name"
|
||||
@@ -1223,8 +1253,8 @@
|
||||
},
|
||||
"byteplus_tos_region": {
|
||||
"label": "BytePlus region",
|
||||
"placeholder": "Please enter BytePlus TOS region (e.g. ap-singapore-1)",
|
||||
"tooltip": "For more information, see <a href=\"https://www.volcengine.com/docs/6349/107356\" target=\"_blank\">https://www.volcengine.com/docs/6349/107356</a>"
|
||||
"placeholder": "Please enter BytePlus TOS region (e.g. ap-southeast-1)",
|
||||
"tooltip": "For more information, see <a href=\"https://docs.byteplus.com/en/docs/tos/docs-region-and-endpoint\" target=\"_blank\">https://docs.byteplus.com/en/docs/tos/docs-region-and-endpoint</a>"
|
||||
},
|
||||
"byteplus_tos_bucket": {
|
||||
"label": "BytePlus TOS bucket",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"bunny": "Bunny",
|
||||
"bunny_cdn": "Bunny - 内容分发网络 CDN",
|
||||
"byteplus": "BytePlus",
|
||||
"byteplus_alb": "BytePlus - 应用型负载均衡 ALB",
|
||||
"byteplus_cdn": "BytePlus - 内容分发网络 CDN",
|
||||
"byteplus_certcenter_upload": "BytePlus - 上传到证书中心",
|
||||
"byteplus_dns": "BytePlus - DNS Suite",
|
||||
|
||||
@@ -1208,6 +1208,36 @@
|
||||
"placeholder": "请输入 Bunny CDN 主机名",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://dash.bunny.net/cdn\" target=\"_blank\">https://dash.bunny.net/cdn</a>"
|
||||
},
|
||||
"byteplus_alb_deploy_target": {
|
||||
"option": {
|
||||
"loadbalancer": {
|
||||
"label": "部署到指定负载均衡器下的全部 HTTPS 监听"
|
||||
},
|
||||
"listener": {
|
||||
"label": "部署到指定 HTTPS 监听器"
|
||||
}
|
||||
}
|
||||
},
|
||||
"byteplus_alb_region": {
|
||||
"label": "BytePlus 服务地域",
|
||||
"placeholder": "请输入 BytePlus ALB 服务地域(例如:cn-beijing)",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://docs.byteplus.com/en/docs/clb/Regions-and-Availability-Zones\" target=\"_blank\">https://docs.byteplus.com/en/docs/clb/Regions-and-Availability-Zones</a>"
|
||||
},
|
||||
"byteplus_alb_loadbalancer_id": {
|
||||
"label": "BytePlus ALB 负载均衡器 ID",
|
||||
"placeholder": "请输入 BytePlus ALB 负载均衡器 ID",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://console.byteplus.com/alb\" target=\"_blank\">https://console.byteplus.com/alb</a>"
|
||||
},
|
||||
"byteplus_alb_listener_id": {
|
||||
"label": "BytePlus ALB 监听器 ID",
|
||||
"placeholder": "请输入 BytePlus ALB 监听器 ID",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://console.byteplus.com/alb\" target=\"_blank\">https://console.byteplus.com/alb</a>"
|
||||
},
|
||||
"byteplus_alb_snidomain": {
|
||||
"label": "BytePlus ALB 扩展域名(可选)",
|
||||
"placeholder": "请输入 BytePlus ALB 扩展域名",
|
||||
"help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。"
|
||||
},
|
||||
"byteplus_cdn_domain": {
|
||||
"label": "BytePlus CDN 域名",
|
||||
"placeholder": "请输入 BytePlus CDN 域名"
|
||||
@@ -1222,8 +1252,8 @@
|
||||
},
|
||||
"byteplus_tos_region": {
|
||||
"label": "BytePlus 服务地域",
|
||||
"placeholder": "请输入 BytePlus TOS 服务地域(例如:ap-singapore-1)",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://www.volcengine.com/docs/6349/107356\" target=\"_blank\">https://www.volcengine.com/docs/6349/107356</a>"
|
||||
"placeholder": "请输入 BytePlus TOS 服务地域(例如:ap-southeast-1)",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://docs.byteplus.com/en/docs/tos/docs-region-and-endpoint\" target=\"_blank\">https://docs.byteplus.com/en/docs/tos/docs-region-and-endpoint</a>"
|
||||
},
|
||||
"byteplus_tos_bucket": {
|
||||
"label": "BytePlus TOS 存储桶名",
|
||||
|
||||
Reference in New Issue
Block a user