diff --git a/go.mod b/go.mod
index bca64be5..ee794b86 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 404e21e4..eb4dc407 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go
index 06239710..e4467a40 100644
--- a/internal/deployer/providers.go
+++ b/internal/deployer/providers.go
@@ -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,
diff --git a/internal/domain/provider.go b/internal/domain/provider.go
index 560b08da..e0ace3ac 100644
--- a/internal/domain/provider.go
+++ b/internal/domain/provider.go
@@ -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")
diff --git a/internal/pkg/core/deployer/providers/tencentcloud-gaap/consts.go b/internal/pkg/core/deployer/providers/tencentcloud-gaap/consts.go
new file mode 100644
index 00000000..37a8a94a
--- /dev/null
+++ b/internal/pkg/core/deployer/providers/tencentcloud-gaap/consts.go
@@ -0,0 +1,8 @@
+package tencentcloudgaap
+
+type ResourceType string
+
+const (
+ // 资源类型:部署到指定监听器。
+ RESOURCE_TYPE_LISTENER = ResourceType("listener")
+)
diff --git a/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go
new file mode 100644
index 00000000..2cc076f0
--- /dev/null
+++ b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap.go
@@ -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
+}
diff --git a/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go
new file mode 100644
index 00000000..32943362
--- /dev/null
+++ b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go
@@ -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)
+ })
+}
diff --git a/internal/workflow/node-processor/monitor_node.go b/internal/workflow/node-processor/monitor_node.go
index d13e4247..8e3d3f87 100644
--- a/internal/workflow/node-processor/monitor_node.go
+++ b/internal/workflow/node-processor/monitor_node.go
@@ -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")
+ }
}
}
}
diff --git a/ui/src/components/provider/DeploymentProviderPicker.tsx b/ui/src/components/provider/DeploymentProviderPicker.tsx
index bb569acd..9b441189 100644
--- a/ui/src/components/provider/DeploymentProviderPicker.tsx
+++ b/ui/src/components/provider/DeploymentProviderPicker.tsx
@@ -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,
diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
index 96e50911..d9a34629 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
@@ -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;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_EO:
return ;
+ case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_GAAP:
+ return ;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SCF:
return ;
case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY:
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx
index bbfca5e6..341bfe6a 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunALBConfig.tsx
@@ -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 = ({
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx
index e666800e..fcd59569 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunCLBConfig.tsx
@@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormAliyunCLBConfigFieldValues => {
return {
+ resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx
index 20dd1ae1..f90652f9 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunGAConfig.tsx
@@ -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) => {
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx
index c37b97db..abd95843 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormAliyunNLBConfig.tsx
@@ -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 = ({
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx
index 875d254b..aba8bf6b 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudAppBLBConfig.tsx
@@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormBaiduCloudAppBLBConfigFieldValues => {
return {
+ resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx
index 99c0b059..fd61053c 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormBaiduCloudBLBConfig.tsx
@@ -27,6 +27,7 @@ const RESOURCE_TYPE_LISTENER = "listener" as const;
const initFormModel = (): DeployNodeConfigFormBaiduCloudBLBConfigFieldValues => {
return {
+ resourceType: RESOURCE_TYPE_LISTENER,
listenerPort: 443,
};
};
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx
index 259e1f44..c3f17e2a 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormHuaweiCloudELBConfig.tsx
@@ -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 = ({
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx
index 22c5bf08..f9cfd937 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormJDCloudALBConfig.tsx
@@ -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 = ({
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx
index 760c6fac..cd06dbd7 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudCLBConfig.tsx
@@ -29,7 +29,7 @@ const RESOURCE_TYPE_RULEDOMAIN = "ruledomain" as const;
const initFormModel = (): DeployNodeConfigFormTencentCloudCLBConfigFieldValues => {
return {
- resourceType: RESOURCE_TYPE_VIA_SSLDEPLOY,
+ resourceType: RESOURCE_TYPE_LISTENER,
};
};
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx
new file mode 100644
index 00000000..1f443cdf
--- /dev/null
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormTencentCloudGAAPConfig.tsx
@@ -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) => {
+ onValuesChange?.(values);
+ };
+
+ return (
+
+
+
+
+ }
+ >
+
+
+
+
+ }
+ >
+
+
+
+
+ );
+};
+
+export default DeployNodeConfigFormTencentCloudGAAPConfig;
diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts
index c74a13ba..d57cc380 100644
--- a/ui/src/domain/provider.ts
+++ b/ui/src/domain/provider.ts
@@ -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: Maphttps://console.tencentcloud.com/edgeone",
+ "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 https://console.cloud.tencent.com/gaap",
+ "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 https://console.cloud.tencent.com/gaap",
"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 https://www.tencentcloud.com/document/product/583/17299",
diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json
index cbf0c7db..b4cc3846 100644
--- a/ui/src/i18n/locales/zh/nls.access.json
+++ b/ui/src/i18n/locales/zh/nls.access.json
@@ -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": "这是什么?请参阅 https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/",
- "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": "这是什么?请参阅 https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/",
"access.form.telegrambot_token.label": "Telegram 机器人 API Token",
"access.form.telegrambot_token.placeholder": "请输入 Telegram 机器人 API Token",
diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json
index 79af14fc..a5ff9e05 100644
--- a/ui/src/i18n/locales/zh/nls.provider.json
+++ b/ui/src/i18n/locales/zh/nls.provider.json
@@ -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": "网站托管",
diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json
index a27ec30a..df6b0a1b 100644
--- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json
+++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json
@@ -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": "这是什么?请参阅 https://console.cloud.tencent.com/edgeone",
+ "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": "这是什么?请参阅 https://console.cloud.tencent.com/gaap",
+ "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": "这是什么?请参阅 https://console.cloud.tencent.com/gaap",
"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": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17299",