diff --git a/README.md b/README.md
index d630efbb..3ab77300 100644
--- a/README.md
+++ b/README.md
@@ -125,7 +125,7 @@ make local.run
| [七牛云](https://www.qiniu.com/) | 可部署到七牛云 CDN |
| [多吉云](https://www.dogecloud.com/) | 可部署到多吉云 CDN |
| [BytePlus](https://www.byteplus.com/) | 可部署到 BytePlus CDN 等服务 |
-| [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 UCDN 等服务 |
+| [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 US3、UCDN 等服务 |
diff --git a/README_EN.md b/README_EN.md
index 65bcfac3..f0f8338e 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -124,7 +124,7 @@ The following hosting providers are supported:
| [Qiniu Cloud](https://www.qiniu.com/) | Supports deployment to Qiniu Cloud CDN |
| [Doge Cloud](https://www.dogecloud.com/) | Supports deployment to Doge Cloud CDN |
| [BytePlus](https://www.byteplus.com/) | Supports deployment to BytePlus CDN |
-| [UCloud](https://www.ucloud.cn/) | Supports deployment to UCloud UCDN |
+| [UCloud](https://www.ucloud-global.com/) | Supports deployment to UCloud US3, UCDN |
diff --git a/go.mod b/go.mod
index 6a4eed0e..1ff91571 100644
--- a/go.mod
+++ b/go.mod
@@ -34,6 +34,7 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1080
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1065
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1065
+ github.com/ucloud/ucloud-sdk-go v0.22.31
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.8
github.com/volcengine/volc-sdk-golang v1.0.189
github.com/volcengine/volcengine-go-sdk v1.0.177
@@ -82,7 +83,6 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
- github.com/ucloud/ucloud-sdk-go v0.22.31 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.mongodb.org/mongo-driver v1.12.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
diff --git a/internal/deployer/providers.go b/internal/deployer/providers.go
index 31d84baf..6cb192f9 100644
--- a/internal/deployer/providers.go
+++ b/internal/deployer/providers.go
@@ -28,6 +28,7 @@ import (
providerTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn"
providerTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo"
providerUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn"
+ providerUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3"
providerVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn"
providerVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb"
providerVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn"
@@ -353,7 +354,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
}
}
- case domain.DeployProviderTypeUCloudUCDN:
+ case domain.DeployProviderTypeUCloudUCDN, domain.DeployProviderTypeUCloudUS3:
{
access := domain.AccessConfigForUCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil {
@@ -365,11 +366,22 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
deployer, err := providerUCloudUCDN.NewWithLogger(&providerUCloudUCDN.UCloudUCDNDeployerConfig{
PrivateKey: access.PrivateKey,
PublicKey: access.PublicKey,
- ProjectId: maps.GetValueAsString(options.ProviderDeployConfig, "projectId"),
+ ProjectId: access.ProjectId,
DomainId: maps.GetValueAsString(options.ProviderDeployConfig, "domainId"),
}, logger)
return deployer, logger, err
+ case domain.DeployProviderTypeUCloudUS3:
+ deployer, err := providerUCloudUS3.NewWithLogger(&providerUCloudUS3.UCloudUS3DeployerConfig{
+ PrivateKey: access.PrivateKey,
+ PublicKey: access.PublicKey,
+ ProjectId: access.ProjectId,
+ Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
+ Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"),
+ Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
+ }, logger)
+ return deployer, logger, err
+
default:
break
}
diff --git a/internal/domain/access.go b/internal/domain/access.go
index e1979ea3..1893b4ab 100644
--- a/internal/domain/access.go
+++ b/internal/domain/access.go
@@ -25,9 +25,9 @@ func (a *Access) UnmarshalConfigToMap() (map[string]any, error) {
type AccessConfigForACMEHttpReq struct {
Endpoint string `json:"endpoint"`
- Mode string `json:"mode"`
- Username string `json:"username"`
- Password string `json:"password"`
+ Mode string `json:"mode,omitempty"`
+ Username string `json:"username,omitempty"`
+ Password string `json:"password,omitempty"`
}
type AccessConfigForAliyun struct {
@@ -79,7 +79,7 @@ type AccessConfigForHuaweiCloud struct {
type AccessConfigForLocal struct{}
type AccessConfigForKubernetes struct {
- KubeConfig string `json:"kubeConfig"`
+ KubeConfig string `json:"kubeConfig,omitempty"`
}
type AccessConfigForNameDotCom struct {
@@ -105,9 +105,9 @@ type AccessConfigForSSH struct {
Host string `json:"host"`
Port int32 `json:"port"`
Username string `json:"username"`
- Password string `json:"password"`
- Key string `json:"key"`
- KeyPassphrase string `json:"keyPassphrase"`
+ Password string `json:"password,omitempty"`
+ Key string `json:"key,omitempty"`
+ KeyPassphrase string `json:"keyPassphrase,omitempty"`
}
type AccessConfigForTencentCloud struct {
@@ -118,6 +118,7 @@ type AccessConfigForTencentCloud struct {
type AccessConfigForUCloud struct {
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
+ ProjectId string `json:"projectId,omitempty"`
}
type AccessConfigForVolcEngine struct {
diff --git a/internal/domain/provider.go b/internal/domain/provider.go
index d5b844a9..b90d9b38 100644
--- a/internal/domain/provider.go
+++ b/internal/domain/provider.go
@@ -94,6 +94,7 @@ const (
DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn")
DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo")
DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn")
+ DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3")
DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn")
DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb")
DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn")
diff --git a/internal/pkg/core/deployer/providers/ucloud-ucdn/ucloud_ucdn_test.go b/internal/pkg/core/deployer/providers/ucloud-ucdn/ucloud_ucdn_test.go
index ba285d71..d8b703b5 100644
--- a/internal/pkg/core/deployer/providers/ucloud-ucdn/ucloud_ucdn_test.go
+++ b/internal/pkg/core/deployer/providers/ucloud-ucdn/ucloud_ucdn_test.go
@@ -20,7 +20,7 @@ var (
)
func init() {
- argsPrefix := "CERTIMATE_DEPLOYER_UCLOUDCDN_"
+ argsPrefix := "CERTIMATE_DEPLOYER_UCLOUDUCDN_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
@@ -32,12 +32,12 @@ func init() {
/*
Shell command to run this test:
- go test -v ./ucloud_cdn_test.go -args \
- --CERTIMATE_DEPLOYER_UCLOUDCDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
- --CERTIMATE_DEPLOYER_UCLOUDCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
- --CERTIMATE_DEPLOYER_UCLOUDCDN_PRIVATEKEY="your-private-key" \
- --CERTIMATE_DEPLOYER_UCLOUDCDN_PUBLICKEY="your-public-key" \
- --CERTIMATE_DEPLOYER_UCLOUDCDN_DOMAINID="your-domain-id"
+ go test -v ./ucloud_ucdn_test.go -args \
+ --CERTIMATE_DEPLOYER_UCLOUDUCDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
+ --CERTIMATE_DEPLOYER_UCLOUDUCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
+ --CERTIMATE_DEPLOYER_UCLOUDUCDN_PRIVATEKEY="your-private-key" \
+ --CERTIMATE_DEPLOYER_UCLOUDUCDN_PUBLICKEY="your-public-key" \
+ --CERTIMATE_DEPLOYER_UCLOUDUCDN_DOMAINID="your-domain-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
@@ -53,9 +53,9 @@ func TestDeploy(t *testing.T) {
}, "\n"))
deployer, err := provider.New(&provider.UCloudUCDNDeployerConfig{
- AccessKeyId: fPrivateKey,
- AccessKeySecret: fPublicKey,
- DomainId: fDomainId,
+ PrivateKey: fPrivateKey,
+ PublicKey: fPublicKey,
+ DomainId: fDomainId,
})
if err != nil {
t.Errorf("err: %+v", err)
diff --git a/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3.go b/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3.go
new file mode 100644
index 00000000..b55d1acc
--- /dev/null
+++ b/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3.go
@@ -0,0 +1,116 @@
+package ucloudus3
+
+import (
+ "context"
+ "errors"
+
+ xerrors "github.com/pkg/errors"
+ usdk "github.com/ucloud/ucloud-sdk-go/ucloud"
+ uAuth "github.com/ucloud/ucloud-sdk-go/ucloud/auth"
+
+ "github.com/usual2970/certimate/internal/pkg/core/deployer"
+ "github.com/usual2970/certimate/internal/pkg/core/logger"
+ "github.com/usual2970/certimate/internal/pkg/core/uploader"
+ uploaderSsl "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/ucloud-ussl"
+ usdkFile "github.com/usual2970/certimate/internal/pkg/vendors/ucloud-sdk/ufile"
+)
+
+type UCloudUS3DeployerConfig struct {
+ // 优刻得 API 私钥。
+ PrivateKey string `json:"privateKey"`
+ // 优刻得 API 公钥。
+ PublicKey string `json:"publicKey"`
+ // 优刻得项目 ID。
+ ProjectId string `json:"projectId,omitempty"`
+ // 优刻得地域。
+ Region string `json:"region"`
+ // 存储桶名。
+ Bucket string `json:"bucket"`
+ // 自定义域名(不支持泛域名)。
+ Domain string `json:"domain"`
+}
+
+type UCloudUS3Deployer struct {
+ config *UCloudUS3DeployerConfig
+ logger logger.Logger
+ sdkClient *usdkFile.UFileClient
+ sslUploader uploader.Uploader
+}
+
+var _ deployer.Deployer = (*UCloudUS3Deployer)(nil)
+
+func New(config *UCloudUS3DeployerConfig) (*UCloudUS3Deployer, error) {
+ return NewWithLogger(config, logger.NewNilLogger())
+}
+
+func NewWithLogger(config *UCloudUS3DeployerConfig, logger logger.Logger) (*UCloudUS3Deployer, error) {
+ if config == nil {
+ return nil, errors.New("config is nil")
+ }
+
+ if logger == nil {
+ return nil, errors.New("logger is nil")
+ }
+
+ client, err := createSdkClient(config.PrivateKey, config.PublicKey, config.Region)
+ if err != nil {
+ return nil, xerrors.Wrap(err, "failed to create sdk client")
+ }
+
+ uploader, err := uploaderSsl.New(&uploaderSsl.UCloudUSSLUploaderConfig{
+ PrivateKey: config.PrivateKey,
+ PublicKey: config.PublicKey,
+ ProjectId: config.ProjectId,
+ })
+ if err != nil {
+ return nil, xerrors.Wrap(err, "failed to create ssl uploader")
+ }
+
+ return &UCloudUS3Deployer{
+ logger: logger,
+ config: config,
+ sdkClient: client,
+ sslUploader: uploader,
+ }, nil
+}
+
+func (d *UCloudUS3Deployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
+ // 上传证书到 USSL
+ upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
+ if err != nil {
+ return nil, xerrors.Wrap(err, "failed to upload certificate file")
+ }
+
+ d.logger.Logt("certificate file uploaded", upres)
+
+ // 添加 SSL 证书
+ // REF: https://docs.ucloud.cn/api/ufile-api/add_ufile_ssl_cert
+ addUFileSSLCertReq := d.sdkClient.NewAddUFileSSLCertRequest()
+ addUFileSSLCertReq.BucketName = usdk.String(d.config.Bucket)
+ addUFileSSLCertReq.Domain = usdk.String(d.config.Domain)
+ addUFileSSLCertReq.USSLId = usdk.String(upres.CertId)
+ addUFileSSLCertReq.CertificateName = usdk.String(upres.CertName)
+ if d.config.ProjectId != "" {
+ addUFileSSLCertReq.ProjectId = usdk.String(d.config.ProjectId)
+ }
+ addUFileSSLCertResp, err := d.sdkClient.AddUFileSSLCert(addUFileSSLCertReq)
+ if err != nil {
+ return nil, xerrors.Wrap(err, "failed to execute sdk request 'ucdn.AddUFileSSLCert'")
+ }
+
+ d.logger.Logt("添加 SSL 证书", addUFileSSLCertResp)
+
+ return &deployer.DeployResult{}, nil
+}
+
+func createSdkClient(privateKey, publicKey, region string) (*usdkFile.UFileClient, error) {
+ cfg := usdk.NewConfig()
+ cfg.Region = region
+
+ credential := uAuth.NewCredential()
+ credential.PrivateKey = privateKey
+ credential.PublicKey = publicKey
+
+ client := usdkFile.NewClient(&cfg, &credential)
+ return client, nil
+}
diff --git a/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3_test.go b/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3_test.go
new file mode 100644
index 00000000..e4175bfc
--- /dev/null
+++ b/internal/pkg/core/deployer/providers/ucloud-us3/ucloud_us3_test.go
@@ -0,0 +1,85 @@
+package ucloudus3_test
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+ "testing"
+
+ provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3"
+)
+
+var (
+ fInputCertPath string
+ fInputKeyPath string
+ fPrivateKey string
+ fPublicKey string
+ fRegion string
+ fBucket string
+ fDomain string
+)
+
+func init() {
+ argsPrefix := "CERTIMATE_DEPLOYER_UCLOUDUS3_"
+
+ flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
+ flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
+ flag.StringVar(&fPrivateKey, argsPrefix+"PRIVATEKEY", "", "")
+ flag.StringVar(&fPublicKey, argsPrefix+"PUBLICKEY", "", "")
+ flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
+ flag.StringVar(&fBucket, argsPrefix+"BUCKET", "", "")
+ flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
+}
+
+/*
+Shell command to run this test:
+
+ go test -v ./ucloud_us3_test.go -args \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_INPUTCERTPATH="/path/to/your-input-cert.pem" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_INPUTKEYPATH="/path/to/your-input-key.pem" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_PRIVATEKEY="your-private-key" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_PUBLICKEY="your-public-key" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_REGION="cn-bj2" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_BUCKET="your-us3-bucket" \
+ --CERTIMATE_DEPLOYER_UCLOUDUS3_DOMAIN="example.com"
+*/
+func TestDeploy(t *testing.T) {
+ flag.Parse()
+
+ t.Run("Deploy", func(t *testing.T) {
+ t.Log(strings.Join([]string{
+ "args:",
+ fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
+ fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
+ fmt.Sprintf("PRIVATEKEY: %v", fPrivateKey),
+ fmt.Sprintf("PUBLICKEY: %v", fPublicKey),
+ fmt.Sprintf("REGION: %v", fRegion),
+ fmt.Sprintf("BUCKET: %v", fBucket),
+ fmt.Sprintf("DOMAIN: %v", fDomain),
+ }, "\n"))
+
+ deployer, err := provider.New(&provider.UCloudUS3DeployerConfig{
+ PrivateKey: fPrivateKey,
+ PublicKey: fPublicKey,
+ Region: fRegion,
+ Bucket: fBucket,
+ Domain: fDomain,
+ })
+ 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/pkg/vendors/ucloud-sdk/ufile/apis.go b/internal/pkg/vendors/ucloud-sdk/ufile/apis.go
new file mode 100644
index 00000000..009405fa
--- /dev/null
+++ b/internal/pkg/vendors/ucloud-sdk/ufile/apis.go
@@ -0,0 +1,42 @@
+package ufile
+
+import (
+ "github.com/ucloud/ucloud-sdk-go/ucloud/request"
+ "github.com/ucloud/ucloud-sdk-go/ucloud/response"
+)
+
+type AddUFileSSLCertRequest struct {
+ request.CommonBase
+
+ BucketName *string `required:"true"`
+ Domain *string `required:"true"`
+ CertificateName *string `required:"true"`
+ USSLId *string `required:"false"`
+}
+
+type AddUFileSSLCertResponse struct {
+ response.CommonBase
+}
+
+func (c *UFileClient) NewAddUFileSSLCertRequest() *AddUFileSSLCertRequest {
+ req := &AddUFileSSLCertRequest{}
+
+ c.Client.SetupRequest(req)
+
+ req.SetRetryable(false)
+ return req
+}
+
+func (c *UFileClient) AddUFileSSLCert(req *AddUFileSSLCertRequest) (*AddUFileSSLCertResponse, error) {
+ var err error
+ var res AddUFileSSLCertResponse
+
+ reqCopier := *req
+
+ err = c.Client.InvokeAction("AddUFileSSLCert", &reqCopier, &res)
+ if err != nil {
+ return &res, err
+ }
+
+ return &res, nil
+}
diff --git a/internal/pkg/vendors/ucloud-sdk/ufile/client.go b/internal/pkg/vendors/ucloud-sdk/ufile/client.go
new file mode 100644
index 00000000..ab1f4d2e
--- /dev/null
+++ b/internal/pkg/vendors/ucloud-sdk/ufile/client.go
@@ -0,0 +1,18 @@
+package ufile
+
+import (
+ "github.com/ucloud/ucloud-sdk-go/ucloud"
+ "github.com/ucloud/ucloud-sdk-go/ucloud/auth"
+)
+
+type UFileClient struct {
+ *ucloud.Client
+}
+
+func NewClient(config *ucloud.Config, credential *auth.Credential) *UFileClient {
+ meta := ucloud.ClientMeta{Product: "UFile"}
+ client := ucloud.NewClientWithMeta(config, credential, meta)
+ return &UFileClient{
+ client,
+ }
+}
diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
index 99c427f5..cbeb6c7a 100644
--- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
+++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx
@@ -38,6 +38,7 @@ import DeployNodeConfigFormTencentCloudCSSConfig from "./DeployNodeConfigFormTen
import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTencentCloudECDNConfig.tsx";
import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx";
import DeployNodeConfigFormUCloudUCDNConfig from "./DeployNodeConfigFormUCloudUCDNConfig.tsx";
+import DeployNodeConfigFormUCloudUS3Config from "./DeployNodeConfigFormUCloudUS3Config.tsx";
import DeployNodeConfigFormVolcEngineCDNConfig from "./DeployNodeConfigFormVolcEngineCDNConfig.tsx";
import DeployNodeConfigFormVolcEngineCLBConfig from "./DeployNodeConfigFormVolcEngineCLBConfig.tsx";
import DeployNodeConfigFormVolcEngineDCDNConfig from "./DeployNodeConfigFormVolcEngineDCDNConfig.tsx";
@@ -159,6 +160,8 @@ const DeployNodeConfigForm = forwardRef;
case DEPLOY_PROVIDERS.UCLOUD_UCDN:
return ;
+ case DEPLOY_PROVIDERS.UCLOUD_US3:
+ return ;
case DEPLOY_PROVIDERS.VOLCENGINE_CDN:
return ;
case DEPLOY_PROVIDERS.VOLCENGINE_CLB:
diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx
new file mode 100644
index 00000000..0ac3a5d6
--- /dev/null
+++ b/ui/src/components/workflow/node/DeployNodeConfigFormUCloudUS3Config.tsx
@@ -0,0 +1,93 @@
+import { useTranslation } from "react-i18next";
+import { Form, type FormInstance, Input } from "antd";
+import { createSchemaFieldRule } from "antd-zod";
+import { z } from "zod";
+
+import { validDomainName } from "@/utils/validators";
+
+type DeployNodeConfigFormUCloudUS3ConfigFieldValues = Nullish<{
+ region: string;
+ bucket: string;
+ domain: string;
+}>;
+
+export type DeployNodeConfigFormUCloudUS3ConfigProps = {
+ form: FormInstance;
+ formName: string;
+ disabled?: boolean;
+ initialValues?: DeployNodeConfigFormUCloudUS3ConfigFieldValues;
+ onValuesChange?: (values: DeployNodeConfigFormUCloudUS3ConfigFieldValues) => void;
+};
+
+const initFormModel = (): DeployNodeConfigFormUCloudUS3ConfigFieldValues => {
+ return {};
+};
+
+const DeployNodeConfigFormUCloudUS3Config = ({
+ form: formInst,
+ formName,
+ disabled,
+ initialValues,
+ onValuesChange,
+}: DeployNodeConfigFormUCloudUS3ConfigProps) => {
+ const { t } = useTranslation();
+
+ const formSchema = z.object({
+ region: z
+ .string({ message: t("workflow_node.deploy.form.ucloud_us3_region.placeholder") })
+ .nonempty(t("workflow_node.deploy.form.ucloud_us3_region.placeholder"))
+ .trim(),
+ bucket: z
+ .string({ message: t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder") })
+ .nonempty(t("workflow_node.deploy.form.ucloud_us3_bucket.placeholder"))
+ .trim(),
+ domain: z
+ .string({ message: t("workflow_node.deploy.form.ucloud_us3_domain.placeholder") })
+ .refine((v) => validDomainName(v), t("common.errmsg.domain_invalid")),
+ });
+ const formRule = createSchemaFieldRule(formSchema);
+
+ const handleFormChange = (_: unknown, values: z.infer) => {
+ onValuesChange?.(values);
+ };
+
+ return (
+ }
+ >
+
+
+
+ }
+ >
+
+
+
+ }
+ >
+
+
+
+ );
+};
+
+export default DeployNodeConfigFormUCloudUS3Config;
diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts
index a9876aad..42250e9d 100644
--- a/ui/src/domain/provider.ts
+++ b/ui/src/domain/provider.ts
@@ -176,6 +176,7 @@ export const DEPLOY_PROVIDERS = Object.freeze({
TENCENTCLOUD_ECDN: `${ACCESS_PROVIDERS.TENCENTCLOUD}-ecdn`,
TENCENTCLOUD_EO: `${ACCESS_PROVIDERS.TENCENTCLOUD}-eo`,
UCLOUD_UCDN: `${ACCESS_PROVIDERS.UCLOUD}-ucdn`,
+ UCLOUD_US3: `${ACCESS_PROVIDERS.UCLOUD}-us3`,
VOLCENGINE_CDN: `${ACCESS_PROVIDERS.VOLCENGINE}-cdn`,
VOLCENGINE_CLB: `${ACCESS_PROVIDERS.VOLCENGINE}-clb`,
VOLCENGINE_DCDN: `${ACCESS_PROVIDERS.VOLCENGINE}-dcdn`,
@@ -227,6 +228,7 @@ export const deployProvidersMap: Map [
type,
diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json
index 7f9ead1d..66228013 100644
--- a/ui/src/i18n/locales/en/nls.access.json
+++ b/ui/src/i18n/locales/en/nls.access.json
@@ -123,13 +123,13 @@
"access.form.tencentcloud_secret_key.tooltip": "For more information, see https://cloud.tencent.com/document/product/598/40488?lang=en",
"access.form.ucloud_private_key.label": "UCloud API private key",
"access.form.ucloud_private_key.placeholder": "Please enter UCloud API private key",
- "access.form.ucloud_private_key.tooltip": "For more information, see https://console.ucloud.cn/uaccount/api_manage",
+ "access.form.ucloud_private_key.tooltip": "For more information, see https://console.ucloud-global.com/uaccount/api_manage",
"access.form.ucloud_public_key.label": "UCloud API public key",
"access.form.ucloud_public_key.placeholder": "Please enter UCloud API public key",
- "access.form.ucloud_public_key.tooltip": "For more information, see https://console.ucloud.cn/uaccount/api_manage",
+ "access.form.ucloud_public_key.tooltip": "For more information, see https://console.ucloud-global.com/uaccount/api_manage",
"access.form.ucloud_project_id.label": "UCloud project ID (Optional)",
"access.form.ucloud_project_id.placeholder": "Please enter UCloud project ID",
- "access.form.ucloud_project_id.tooltip": "For more information, see https://console.ucloud.cn/uaccount/iam/project_manage",
+ "access.form.ucloud_project_id.tooltip": "For more information, see https://console.ucloud-global.com/uaccount/iam/project_manage",
"access.form.volcengine_access_key_id.label": "VolcEngine AccessKeyId",
"access.form.volcengine_access_key_id.placeholder": "Please enter VolcEngine AccessKeyId",
"access.form.volcengine_access_key_id.tooltip": "For more information, see https://www.volcengine.com/docs/6291/216571",
diff --git a/ui/src/i18n/locales/en/nls.common.json b/ui/src/i18n/locales/en/nls.common.json
index 0b673e32..dc8ea864 100644
--- a/ui/src/i18n/locales/en/nls.common.json
+++ b/ui/src/i18n/locales/en/nls.common.json
@@ -80,6 +80,7 @@
"common.provider.tencentcloud.eo": "Tencent Cloud - EdgeOne",
"common.provider.ucloud": "UCloud",
"common.provider.ucloud.ucdn": "UCloud - UCloud Content Delivery Network (UCDN)",
+ "common.provider.ucloud.us3": "UCloud - UCloud Object-based Storage (US3)",
"common.provider.volcengine": "Volcengine",
"common.provider.volcengine.cdn": "Volcengine - Content Delivery Network (CDN)",
"common.provider.volcengine.clb": "Volcengine - Cloud Load Balancer (CLB)",
diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json
index bbebd5a7..7275d08b 100644
--- a/ui/src/i18n/locales/en/nls.workflow.nodes.json
+++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json
@@ -303,7 +303,16 @@
"workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "For more information, see https://console.tencentcloud.com/edgeone",
"workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "UCloud UCDN domain ID",
"workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "Please enter UCloud UCDN domain ID",
- "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "For more information, see https://console.ucloud.cn/ucdn",
+ "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "For more information, see https://console.ucloud-global.com/ucdn",
+ "workflow_node.deploy.form.ucloud_us3_region.label": "UCloud region",
+ "workflow_node.deploy.form.ucloud_us3_region.placeholder": "Please enter VolcEngine region (e.g. cn-bj2)",
+ "workflow_node.deploy.form.ucloud_us3_region.tooltip": "For more information, see https://www.ucloud-global.com/en/docs/api/summary/regionlist",
+ "workflow_node.deploy.form.ucloud_us3_bucket.label": "UCloud US3 bucket",
+ "workflow_node.deploy.form.ucloud_us3_bucket.placeholder": "Please enter UCloud US3 bucket name",
+ "workflow_node.deploy.form.ucloud_us3_bucket.tooltip": "For more information, see https://console.ucloud-global.com/ufile",
+ "workflow_node.deploy.form.ucloud_us3_domain.label": "UCloud US3 domain",
+ "workflow_node.deploy.form.ucloud_us3_domain.placeholder": "Please enter UCloud US3 domain name",
+ "workflow_node.deploy.form.ucloud_us3_domain.tooltip": "For more information, see https://console.ucloud-global.com/ufile",
"workflow_node.deploy.form.volcengine_cdn_domain.label": "VolcEngine CDN domain",
"workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "Please enter VolcEngine CDN domain name",
"workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "For more information, see https://console.volcengine.com/cdn/homepage",
diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json
index c35f19a6..80d6ccc9 100644
--- a/ui/src/i18n/locales/zh/nls.common.json
+++ b/ui/src/i18n/locales/zh/nls.common.json
@@ -80,6 +80,7 @@
"common.provider.tencentcloud.eo": "腾讯云 - 边缘安全加速平台 EdgeOne",
"common.provider.ucloud": "优刻得",
"common.provider.ucloud.ucdn": "优刻得 - 内容分发 UCDN",
+ "common.provider.ucloud.us3": "优刻得 - 对象存储 US3",
"common.provider.volcengine": "火山引擎",
"common.provider.volcengine.cdn": "火山引擎 - 内容分发网络 CDN",
"common.provider.volcengine.clb": "火山引擎 - 负载均衡 CLB",
diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json
index 41450494..00b24d75 100644
--- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json
+++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json
@@ -304,6 +304,15 @@
"workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "优刻得 UCDN 域名 ID",
"workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "请输入优刻得 UCDN 域名 ID",
"workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "这是什么?请参阅 https://console.ucloud.cn/ucdn",
+ "workflow_node.deploy.form.ucloud_us3_region.label": "优刻得地域",
+ "workflow_node.deploy.form.ucloud_us3_region.placeholder": "优刻得地域(例如:cn-bj2)",
+ "workflow_node.deploy.form.ucloud_us3_region.tooltip": "这是什么?请参阅 https://docs.ucloud.cn/api/summary/regionlist",
+ "workflow_node.deploy.form.ucloud_us3_bucket.label": "优刻得 US3 存储桶名",
+ "workflow_node.deploy.form.ucloud_us3_bucket.placeholder": "请输入优刻得 US3 存储桶名",
+ "workflow_node.deploy.form.ucloud_us3_bucket.tooltip": "这是什么?请参阅 https://console.ucloud.cn/ufile",
+ "workflow_node.deploy.form.ucloud_us3_domain.label": "优刻得 US3 自定义域名",
+ "workflow_node.deploy.form.ucloud_us3_domain.placeholder": "请输入优刻得 US3 自定义域名",
+ "workflow_node.deploy.form.ucloud_us3_domain.tooltip": "这是什么?请参阅 https://console.ucloud.cn/ufile",
"workflow_node.deploy.form.volcengine_cdn_domain.label": "火山引擎 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "请输入火山引擎 CDN 加速域名",
"workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "这是什么?请参阅 https://console.volcengine.com/cdn/homepage
泛域名表示形式为:*.example.com",