feat: new deployment provider: tencentcloud gaap

This commit is contained in:
Fu Diwei 2025-06-11 19:55:21 +08:00
parent 57eb66b889
commit b833d09466
26 changed files with 424 additions and 12 deletions

3
go.mod
View File

@ -30,6 +30,7 @@ require (
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go-v2/service/acm v1.32.0
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0
github.com/baidubce/bce-sdk-go v0.9.228
github.com/blinkbean/dingtalk v1.1.3
github.com/byteplus-sdk/byteplus-sdk-golang v1.0.46
@ -51,6 +52,7 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169
@ -85,7 +87,6 @@ require (
github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.50.0 // indirect
github.com/buger/goterm v1.0.4 // indirect
github.com/diskfs/go-diskfs v1.5.0 // indirect

3
go.sum
View File

@ -836,6 +836,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166/go.mod h1
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1150/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1155/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1163/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1164/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1166/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1169/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
@ -845,6 +846,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173 h1:W5b
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163 h1:putqrH5n1SVRqFWHOylVqYI5yLQUjRTkHqZPLT2yeVY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.0.1163/go.mod h1:aEWRXlAvovPUUoS3kVB/LVWEQ19WqzTj2lXGvR1YArY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150 h1:RQQYfZOFYlkxKR2+xp8el3+8xs9DhxBy+ajlHtapqtQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150/go.mod h1:zpfr6EBWy7ClASTGUgIy01Gn4R79UXf+2QGQeyR124A=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk=

View File

@ -73,6 +73,7 @@ import (
pTencentCloudCSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-css"
pTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn"
pTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo"
pTencentCloudGAAP "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-gaap"
pTencentCloudSCF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-scf"
pTencentCloudSSL "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl"
pTencentCloudSSLDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy"
@ -1030,7 +1031,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
return deployer, err
}
case domain.DeploymentProviderTypeTencentCloudCDN, domain.DeploymentProviderTypeTencentCloudCLB, domain.DeploymentProviderTypeTencentCloudCOS, domain.DeploymentProviderTypeTencentCloudCSS, domain.DeploymentProviderTypeTencentCloudECDN, domain.DeploymentProviderTypeTencentCloudEO, domain.DeploymentProviderTypeTencentCloudSCF, domain.DeploymentProviderTypeTencentCloudSSL, domain.DeploymentProviderTypeTencentCloudSSLDeploy, domain.DeploymentProviderTypeTencentCloudVOD, domain.DeploymentProviderTypeTencentCloudWAF:
case domain.DeploymentProviderTypeTencentCloudCDN, domain.DeploymentProviderTypeTencentCloudCLB, domain.DeploymentProviderTypeTencentCloudCOS, domain.DeploymentProviderTypeTencentCloudCSS, domain.DeploymentProviderTypeTencentCloudECDN, domain.DeploymentProviderTypeTencentCloudEO, domain.DeploymentProviderTypeTencentCloudGAAP, domain.DeploymentProviderTypeTencentCloudSCF, domain.DeploymentProviderTypeTencentCloudSSL, domain.DeploymentProviderTypeTencentCloudSSLDeploy, domain.DeploymentProviderTypeTencentCloudVOD, domain.DeploymentProviderTypeTencentCloudWAF:
{
access := domain.AccessConfigForTencentCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
@ -1093,6 +1094,16 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
})
return deployer, err
case domain.DeploymentProviderTypeTencentCloudGAAP:
deployer, err := pTencentCloudGAAP.NewDeployer(&pTencentCloudGAAP.DeployerConfig{
SecretId: access.SecretId,
SecretKey: access.SecretKey,
ResourceType: pTencentCloudGAAP.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
ProxyId: maputil.GetString(options.ProviderServiceConfig, "proxyId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"),
})
return deployer, err
case domain.DeploymentProviderTypeTencentCloudSCF:
deployer, err := pTencentCloudSCF.NewDeployer(&pTencentCloudSCF.DeployerConfig{
SecretId: access.SecretId,

View File

@ -242,6 +242,7 @@ const (
DeploymentProviderTypeTencentCloudCSS = DeploymentProviderType(AccessProviderTypeTencentCloud + "-css")
DeploymentProviderTypeTencentCloudECDN = DeploymentProviderType(AccessProviderTypeTencentCloud + "-ecdn")
DeploymentProviderTypeTencentCloudEO = DeploymentProviderType(AccessProviderTypeTencentCloud + "-eo")
DeploymentProviderTypeTencentCloudGAAP = DeploymentProviderType(AccessProviderTypeTencentCloud + "-gaap")
DeploymentProviderTypeTencentCloudSCF = DeploymentProviderType(AccessProviderTypeTencentCloud + "-scf")
DeploymentProviderTypeTencentCloudSSL = DeploymentProviderType(AccessProviderTypeTencentCloud + "-ssl")
DeploymentProviderTypeTencentCloudSSLDeploy = DeploymentProviderType(AccessProviderTypeTencentCloud + "-ssldeploy")

View File

@ -0,0 +1,8 @@
package tencentcloudgaap
type ResourceType string
const (
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -0,0 +1,154 @@
package tencentcloudgaap
import (
"context"
"errors"
"fmt"
"log/slog"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcgaap "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap/v20180529"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/tencentcloud-ssl"
typeutil "github.com/usual2970/certimate/internal/pkg/utils/type"
)
type DeployerConfig struct {
// 腾讯云 SecretId。
SecretId string `json:"secretId"`
// 腾讯云 SecretKey。
SecretKey string `json:"secretKey"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 通道 ID。
// 选填。
ProxyId string `json:"proxyId,omitempty"`
// 负载均衡监听 ID。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *tcgaap.Client
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClients(config.SecretId, config.SecretKey)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
SecretId: config.SecretId,
SecretKey: config.SecretKey,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
return &DeployerProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
d.sslUploader.WithLogger(logger)
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
// 上传证书到 SSL
upres, err := d.sslUploader.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.ResourceType {
case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type '%s'", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required")
}
// 更新监听器证书
if err := d.modifyHttpsListenerCertificate(ctx, d.config.ListenerId, cloudCertId); err != nil {
return err
}
return nil
}
func (d *DeployerProvider) modifyHttpsListenerCertificate(ctx context.Context, cloudListenerId, cloudCertId string) error {
// 查询 HTTPS 监听器信息
// REF: https://cloud.tencent.com/document/product/608/37001
describeHTTPSListenersReq := tcgaap.NewDescribeHTTPSListenersRequest()
describeHTTPSListenersReq.ListenerId = common.StringPtr(cloudListenerId)
describeHTTPSListenersReq.Offset = common.Uint64Ptr(0)
describeHTTPSListenersReq.Limit = common.Uint64Ptr(1)
describeHTTPSListenersResp, err := d.sdkClient.DescribeHTTPSListeners(describeHTTPSListenersReq)
d.logger.Debug("sdk request 'gaap.DescribeHTTPSListeners'", slog.Any("request", describeHTTPSListenersReq), slog.Any("response", describeHTTPSListenersResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'gaap.DescribeHTTPSListeners': %w", err)
} else if len(describeHTTPSListenersResp.Response.ListenerSet) == 0 {
return errors.New("listener not found")
}
// 修改 HTTPS 监听器配置
// REF: https://cloud.tencent.com/document/product/608/36996
modifyHTTPSListenerAttributeReq := tcgaap.NewModifyHTTPSListenerAttributeRequest()
modifyHTTPSListenerAttributeReq.ProxyId = typeutil.ToPtrOrZeroNil(d.config.ProxyId)
modifyHTTPSListenerAttributeReq.ListenerId = common.StringPtr(cloudListenerId)
modifyHTTPSListenerAttributeReq.CertificateId = common.StringPtr(cloudCertId)
modifyHTTPSListenerAttributeResp, err := d.sdkClient.ModifyHTTPSListenerAttribute(modifyHTTPSListenerAttributeReq)
d.logger.Debug("sdk request 'gaap.ModifyHTTPSListenerAttribute'", slog.Any("request", modifyHTTPSListenerAttributeReq), slog.Any("response", modifyHTTPSListenerAttributeResp))
if err != nil {
return fmt.Errorf("failed to execute sdk request 'gaap.ModifyHTTPSListenerAttribute': %w", err)
}
return nil
}
func createSdkClients(secretId, secretKey string) (*tcgaap.Client, error) {
credential := common.NewCredential(secretId, secretKey)
client, err := tcgaap.NewClient(credential, "", profile.NewClientProfile())
if err != nil {
return nil, err
}
return client, nil
}

View File

@ -0,0 +1,86 @@
package tencentcloudgaap_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-gaap"
)
var (
fInputCertPath string
fInputKeyPath string
fSecretId string
fSecretKey string
fProxyGroupId string
fProxyId string
fListenerId string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_TENCENTCLOUDCDN_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fSecretId, argsPrefix+"SECRETID", "", "")
flag.StringVar(&fSecretKey, argsPrefix+"SECRETKEY", "", "")
flag.StringVar(&fProxyGroupId, argsPrefix+"PROXYGROUPID", "", "")
flag.StringVar(&fProxyId, argsPrefix+"PROXYID", "", "")
flag.StringVar(&fListenerId, argsPrefix+"LISTENERID", "", "")
}
/*
Shell command to run this test:
go test -v ./tencentcloud_gaap_test.go -args \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_SECRETID="your-secret-id" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_SECRETKEY="your-secret-key" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_PROXYGROUPID="your-gaap-group-id" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_PROXYID="your-gaap-group-id" \
--CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_LISTENERID="your-clb-listener-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy_ToListener", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("SECRETID: %v", fSecretId),
fmt.Sprintf("SECRETKEY: %v", fSecretKey),
fmt.Sprintf("PROXYGROUPID: %v", fProxyGroupId),
fmt.Sprintf("PROXYID: %v", fProxyId),
fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
SecretId: fSecretId,
SecretKey: fSecretKey,
ResourceType: provider.RESOURCE_TYPE_LISTENER,
ProxyGroupId: fProxyGroupId,
ProxyId: fProxyId,
ListenerId: fListenerId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -100,7 +100,13 @@ func (n *monitorNode) Process(ctx context.Context) error {
if validated {
n.logger.Info(fmt.Sprintf("the certificate is valid, and will expire in %d day(s)", daysLeft))
} else {
n.logger.Warn(fmt.Sprintf("the certificate is invalid", validated))
if !isCertHostMatched {
n.logger.Warn("the certificate is invalid, because it is not matched the host")
} else if !isCertPeriodValid {
n.logger.Warn("the certificate is invalid, because it is either expired or not yet valid")
} else {
n.logger.Warn("the certificate is invalid")
}
}
}
}

View File

@ -72,6 +72,7 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, filter, placeho
DEPLOYMENT_CATEGORIES.LOADBALANCE,
DEPLOYMENT_CATEGORIES.FIREWALL,
DEPLOYMENT_CATEGORIES.AV,
DEPLOYMENT_CATEGORIES.ACCELERATOR,
DEPLOYMENT_CATEGORIES.APIGATEWAY,
DEPLOYMENT_CATEGORIES.SERVERLESS,
DEPLOYMENT_CATEGORIES.WEBSITE,

View File

@ -77,6 +77,7 @@ import DeployNodeConfigFormTencentCloudCOSConfig from "./DeployNodeConfigFormTen
import DeployNodeConfigFormTencentCloudCSSConfig from "./DeployNodeConfigFormTencentCloudCSSConfig.tsx";
import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTencentCloudECDNConfig.tsx";
import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx";
import DeployNodeConfigFormTencentCloudGAAPConfig from "./DeployNodeConfigFormTencentCloudGAAPConfig.tsx";
import DeployNodeConfigFormTencentCloudSCFConfig from "./DeployNodeConfigFormTencentCloudSCFConfig";
import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig";
import DeployNodeConfigFormTencentCloudVODConfig from "./DeployNodeConfigFormTencentCloudVODConfig";
@ -321,6 +322,8 @@ const DeployNodeConfigForm = forwardRef<DeployNodeConfigFormInstance, DeployNode
return <DeployNodeConfigFormTencentCloudECDNConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_EO:
return <DeployNodeConfigFormTencentCloudEOConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_GAAP:
return <DeployNodeConfigFormTencentCloudGAAPConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SCF:
return <DeployNodeConfigFormTencentCloudSCFConfig {...nestedFormProps} />;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY:

View File

@ -26,7 +26,9 @@ const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const;
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormAliyunALBConfigFieldValues => {
return {};
return {
resourceType: RESOURCE_TYPE_LISTENER,
};
};
const DeployNodeConfigFormAliyunALBConfig = ({

View File

@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormAliyunCLBConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};

View File

@ -25,7 +25,9 @@ const RESOURCE_TYPE_ACCELERATOR = "accelerator" as const;
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormAliyunGAConfigFieldValues => {
return {};
return {
resourceType: RESOURCE_TYPE_LISTENER,
};
};
const DeployNodeConfigFormAliyunGAConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormAliyunGAConfigProps) => {

View File

@ -24,7 +24,9 @@ const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const;
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormAliyunNLBConfigFieldValues => {
return {};
return {
resourceType: RESOURCE_TYPE_LISTENER,
};
};
const DeployNodeConfigFormAliyunNLBConfig = ({

View File

@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormBaiduCloudAppBLBConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};

View File

@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormBaiduCloudBLBConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};

View File

@ -26,7 +26,9 @@ const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const;
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormHuaweiCloudELBConfigFieldValues => {
return {};
return {
resourceType: RESOURCE_TYPE_LISTENER,
};
};
const DeployNodeConfigFormHuaweiCloudELBConfig = ({

View File

@ -26,7 +26,9 @@ const RESOURCE_TYPE_LOADBALANCER = "loadbalancer" as const;
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormJDCloudALBConfigFieldValues => {
return {};
return {
resourceType: RESOURCE_TYPE_LISTENER,
};
};
const DeployNodeConfigFormJDCloudALBConfig = ({

View File

@ -29,7 +29,7 @@ const RESOURCE_TYPE_RULEDOMAIN = "ruledomain" as const;
const initFormModel = (): DeployNodeConfigFormTencentCloudCLBConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_VIA_SSLDEPLOY,
resourceType: RESOURCE_TYPE_LISTENER,
};
};

View File

@ -0,0 +1,100 @@
import { useTranslation } from "react-i18next";
import { Form, type FormInstance, Input, Select } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import Show from "@/components/Show";
type DeployNodeConfigFormTencentCloudGAAPConfigFieldValues = Nullish<{
resourceType: string;
proxyId?: string;
listenerId?: string;
}>;
export type DeployNodeConfigFormTencentCloudGAAPConfigProps = {
form: FormInstance;
formName: string;
disabled?: boolean;
initialValues?: DeployNodeConfigFormTencentCloudGAAPConfigFieldValues;
onValuesChange?: (values: DeployNodeConfigFormTencentCloudGAAPConfigFieldValues) => void;
};
const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormTencentCloudGAAPConfigFieldValues => {
return {
resourceType: RESOURCE_TYPE_LISTENER,
listenerId: "",
};
};
const DeployNodeConfigFormTencentCloudGAAPConfig = ({
form: formInst,
formName,
disabled,
initialValues,
onValuesChange,
}: DeployNodeConfigFormTencentCloudGAAPConfigProps) => {
const { t } = useTranslation();
const formSchema = z.object({
resourceType: z.literal(RESOURCE_TYPE_LISTENER, { message: t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder") }),
proxyId: z.string().trim().nullish(),
listenerId: z
.string()
.trim()
.nullish()
.refine(
(v) => ![RESOURCE_TYPE_LISTENER].includes(fieldResourceType) || !!v?.trim(),
t("workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder")
),
});
const formRule = createSchemaFieldRule(formSchema);
const fieldResourceType = Form.useWatch("resourceType", formInst);
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
onValuesChange?.(values);
};
return (
<Form
form={formInst}
disabled={disabled}
initialValues={initialValues ?? initFormModel()}
layout="vertical"
name={formName}
onValuesChange={handleFormChange}
>
<Form.Item name="resourceType" label={t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.label")} rules={[formRule]}>
<Select placeholder={t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder")}>
<Select.Option key={RESOURCE_TYPE_LISTENER} value={RESOURCE_TYPE_LISTENER}>
{t("workflow_node.deploy.form.tencentcloud_gaap_resource_type.option.listener.label")}
</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="proxyId"
label={t("workflow_node.deploy.form.tencentcloud_gaap_proxy_id.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_gaap_proxy_id.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.tencentcloud_gaap_proxy_id.placeholder")} />
</Form.Item>
<Show when={fieldResourceType === RESOURCE_TYPE_LISTENER}>
<Form.Item
name="listenerId"
label={t("workflow_node.deploy.form.tencentcloud_gaap_listener_id.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder")} />
</Form.Item>
</Show>
</Form>
);
};
export default DeployNodeConfigFormTencentCloudGAAPConfig;

View File

@ -436,6 +436,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
TENCENTCLOUD_CSS: `${ACCESS_PROVIDERS.TENCENTCLOUD}-css`,
TENCENTCLOUD_ECDN: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ecdn`,
TENCENTCLOUD_EO: `${ACCESS_PROVIDERS.TENCENTCLOUD}-eo`,
TENCENTCLOUD_GAAP: `${ACCESS_PROVIDERS.TENCENTCLOUD}-gaap`,
TENCENTCLOUD_SCF: `${ACCESS_PROVIDERS.TENCENTCLOUD}-scf`,
TENCENTCLOUD_SSL: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ssl`,
TENCENTCLOUD_SSL_DEPLOY: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ssldeploy`,
@ -469,6 +470,7 @@ export const DEPLOYMENT_CATEGORIES = Object.freeze({
LOADBALANCE: "loadbalance",
FIREWALL: "firewall",
AV: "av",
ACCELERATOR: "accelerator",
APIGATEWAY: "apigw",
SERVERLESS: "serverless",
WEBSITE: "website",
@ -511,7 +513,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.ALIYUN_VOD, "provider.aliyun.vod", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.ALIYUN_FC, "provider.aliyun.fc", DEPLOYMENT_CATEGORIES.SERVERLESS],
[DEPLOYMENT_PROVIDERS.ALIYUN_APIGW, "provider.aliyun.apigw", DEPLOYMENT_CATEGORIES.APIGATEWAY],
[DEPLOYMENT_PROVIDERS.ALIYUN_GA, "provider.aliyun.ga", DEPLOYMENT_CATEGORIES.OTHER],
[DEPLOYMENT_PROVIDERS.ALIYUN_GA, "provider.aliyun.ga", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.ALIYUN_CAS, "provider.aliyun.cas_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.ALIYUN_CAS_DEPLOY, "provider.aliyun.cas_deploy", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_COS, "provider.tencentcloud.cos", DEPLOYMENT_CATEGORIES.STORAGE],
@ -523,6 +525,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_CSS, "provider.tencentcloud.css", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_VOD, "provider.tencentcloud.vod", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SCF, "provider.tencentcloud.scf", DEPLOYMENT_CATEGORIES.SERVERLESS],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_GAAP, "provider.tencentcloud.gaap", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL, "provider.tencentcloud.ssl_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY, "provider.tencentcloud.ssl_deploy", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CDN, "provider.baiducloud.cdn", DEPLOYMENT_CATEGORIES.CDN],

View File

@ -132,6 +132,7 @@
"provider.tencentcloud.dns": "Tencent Cloud - DNS (Domain Name Service)",
"provider.tencentcloud.ecdn": "Tencent Cloud - ECDN (Enterprise Content Delivery Network)",
"provider.tencentcloud.eo": "Tencent Cloud - EdgeOne",
"provider.tencentcloud.gaap": "Tencent Cloud - GAAP (Global Application Acceleration Platform)",
"provider.tencentcloud.scf": "Tencent Cloud - SCF (Serverless Cloud Function)",
"provider.tencentcloud.ssl_upload": "Tencent Cloud - Upload to SSL Certificate Service",
"provider.tencentcloud.ssl_deploy": "Tencent Cloud - Deploy via SSL Certificate Service",
@ -172,6 +173,7 @@
"provider.category.loadbalance": "Loadbalance",
"provider.category.firewall": "Firewall",
"provider.category.av": "Audio/Video",
"provider.category.accelerator": "Accelerator",
"provider.category.apigw": "API Gateway",
"provider.category.serverless": "Serverless",
"provider.category.website": "Website",

View File

@ -670,6 +670,15 @@
"workflow_node.deploy.form.tencentcloud_eo_domain.label": "Tencent Cloud EdgeOne domain",
"workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "Please enter Tencent Cloud EdgeOne domain name",
"workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "For more information, see <a href=\"https://console.tencentcloud.com/edgeone\" target=\"_blank\">https://console.tencentcloud.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "Resource type",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder": "Please select resource type",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.option.listener.label": "GAAP listener",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.label": "Tencent Cloud GAAP proxy ID (Optional)",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.placeholder": "Please enter Tencent Cloud GAAP proxy ID",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.tooltip": "For more information, see <a href=\"https://console.cloud.tencent.com/gaap\" target=\"_blank\">https://console.cloud.tencent.com/gaap</a>",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "Tencent Cloud GAAP listener ID",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "Please enter Tencent Cloud GAAP listener ID",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "For more information, see <a href=\"https://console.cloud.tencent.com/gaap\" target=\"_blank\">https://console.cloud.tencent.com/gaap</a>",
"workflow_node.deploy.form.tencentcloud_scf_region.label": "Tencent Cloud SCF region",
"workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "Please enter Tencent Cloud SCF region (e.g. ap-guangzhou)",
"workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "For more information, see <a href=\"https://www.tencentcloud.com/document/product/583/17299\" target=\"_blank\">https://www.tencentcloud.com/document/product/583/17299</a>",

View File

@ -398,8 +398,8 @@
"access.form.sslcom_eab_kid.label": "ACME EAB KID",
"access.form.sslcom_eab_kid.placeholder": "请输入 ACME EAB KID",
"access.form.sslcom_eab_kid.tooltip": "这是什么?请参阅 <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
"access.form.sslcom_eab_hmac_key.label": "ACME EAB HMAC key",
"access.form.sslcom_eab_hmac_key.placeholder": "请输入 ACME EAB HMAC key",
"access.form.sslcom_eab_hmac_key.label": "ACME EAB HMAC Key",
"access.form.sslcom_eab_hmac_key.placeholder": "请输入 ACME EAB HMAC Key",
"access.form.sslcom_eab_hmac_key.tooltip": "这是什么?请参阅 <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
"access.form.telegrambot_token.label": "Telegram 机器人 API Token",
"access.form.telegrambot_token.placeholder": "请输入 Telegram 机器人 API Token",

View File

@ -132,6 +132,7 @@
"provider.tencentcloud.dns": "腾讯云 - 云解析 DNS",
"provider.tencentcloud.ecdn": "腾讯云 - 全站加速网络 ECDN",
"provider.tencentcloud.eo": "腾讯云 - 边缘安全加速平台 EdgeOne",
"provider.tencentcloud.gaap": "腾讯云 - 全球应用加速 GAAP",
"provider.tencentcloud.scf": "腾讯云 - 云函数 SCF",
"provider.tencentcloud.ssl_upload": "腾讯云 - 上传到 SSL 证书服务",
"provider.tencentcloud.ssl_deploy": "腾讯云 - 通过 SSL 证书服务创建部署任务",
@ -172,6 +173,7 @@
"provider.category.loadbalance": "负载均衡",
"provider.category.firewall": "防火墙",
"provider.category.av": "音视频",
"provider.category.accelerator": "加速器",
"provider.category.apigw": "API 网关",
"provider.category.serverless": "Serverless",
"provider.category.website": "网站托管",

View File

@ -669,6 +669,15 @@
"workflow_node.deploy.form.tencentcloud_eo_domain.label": "腾讯云 EdgeOne 加速域名",
"workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "请输入腾讯云 EdgeOne 加速域名",
"workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "证书部署方式",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.placeholder": "请选择证书部署方式",
"workflow_node.deploy.form.tencentcloud_gaap_resource_type.option.listener.label": "替换指定监听器的证书",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.label": "腾讯云 GAAP 通道 ID可选",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.placeholder": "请输入腾讯云 GAAP 通道 ID",
"workflow_node.deploy.form.tencentcloud_gaap_proxy_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/gaap\" target=\"_blank\">https://console.cloud.tencent.com/gaap</a>",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "腾讯云 GAAP 监听器 ID",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "请输入腾讯云 GAAP 监听器 ID",
"workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/gaap\" target=\"_blank\">https://console.cloud.tencent.com/gaap</a>",
"workflow_node.deploy.form.tencentcloud_scf_region.label": "腾讯云 SCF 产品地域",
"workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "输入腾讯云 SCF 产品地域例如ap-guangzhou",
"workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "这是什么?请参阅 <a href=\"https://cloud.tencent.com/document/product/583/17299\" target=\"_blank\">https://cloud.tencent.com/document/product/583/17299</a>",