feat: add baishan cdn deployer

This commit is contained in:
Fu Diwei 2025-02-17 20:19:31 +08:00
parent c72dc0d2c4
commit b2eb5d2754
34 changed files with 866 additions and 285 deletions

View File

@ -128,6 +128,7 @@ make local.run
| [华为云](https://www.huaweicloud.com/) | 可部署到华为云 CDN、ELB、WAF 等服务 | | [华为云](https://www.huaweicloud.com/) | 可部署到华为云 CDN、ELB、WAF 等服务 |
| [火山引擎](https://www.volcengine.com/) | 可部署到火山引擎 TOS、CDN、DCDN、CLB、ImageX、Live 等服务 | | [火山引擎](https://www.volcengine.com/) | 可部署到火山引擎 TOS、CDN、DCDN、CLB、ImageX、Live 等服务 |
| [七牛云](https://www.qiniu.com/) | 可部署到七牛云 CDN、直播云等服务 | | [七牛云](https://www.qiniu.com/) | 可部署到七牛云 CDN、直播云等服务 |
| [白山云](https://www.baishan.com/) | 可部署到白山云 CDN |
| [多吉云](https://www.dogecloud.com/) | 可部署到多吉云 CDN | | [多吉云](https://www.dogecloud.com/) | 可部署到多吉云 CDN |
| [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 US3、UCDN 等服务 | | [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 US3、UCDN 等服务 |
| [雷池](https://waf-ce.chaitin.cn/) | 可部署到雷池 WAF | | [雷池](https://waf-ce.chaitin.cn/) | 可部署到雷池 WAF |

View File

@ -127,6 +127,7 @@ The following hosting providers are supported:
| [Huawei Cloud](https://www.huaweicloud.com/) | Supports deployment to Huawei Cloud CDN, ELB, WAF | | [Huawei Cloud](https://www.huaweicloud.com/) | Supports deployment to Huawei Cloud CDN, ELB, WAF |
| [Volcengine](https://www.volcengine.com/) | Supports deployment to Volcengine TOS, CDN, DCDN, CLB, ImageX, Live | | [Volcengine](https://www.volcengine.com/) | Supports deployment to Volcengine TOS, CDN, DCDN, CLB, ImageX, Live |
| [Qiniu Cloud](https://www.qiniu.com/) | Supports deployment to Qiniu Cloud CDN, Pili | | [Qiniu Cloud](https://www.qiniu.com/) | Supports deployment to Qiniu Cloud CDN, Pili |
| [Baishan Cloud](https://intl.baishancloud.com/) | Supports deployment to Baishan Cloud CDN |
| [Doge Cloud](https://www.dogecloud.com/) | Supports deployment to Doge Cloud CDN | | [Doge Cloud](https://www.dogecloud.com/) | Supports deployment to Doge Cloud CDN |
| [UCloud](https://www.ucloud-global.com/) | Supports deployment to UCloud US3, UCDN | | [UCloud](https://www.ucloud-global.com/) | Supports deployment to UCloud US3, UCDN |
| [SafeLine](https://waf.chaitin.com/) | Supports deployment to SafeLine WAF | | [SafeLine](https://waf.chaitin.com/) | Supports deployment to SafeLine WAF |

View File

@ -18,6 +18,7 @@ import (
pAliyunWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-waf" pAliyunWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-waf"
pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront" pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront"
pBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn" pBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn"
pBaishanCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn"
pBaotaPanelConsole "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console" pBaotaPanelConsole "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console"
pBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site" pBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site"
pBytePlusCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/byteplus-cdn" pBytePlusCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/byteplus-cdn"
@ -216,6 +217,26 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
} }
} }
case domain.DeployProviderTypeBaishanCDN:
{
access := domain.AccessConfigForBaishan{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
switch options.Provider {
case domain.DeployProviderTypeBaishanCDN:
deployer, err := pBaishanCDN.NewWithLogger(&pBaishanCDN.BaishanCDNDeployerConfig{
ApiToken: access.ApiToken,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger)
return deployer, logger, err
default:
break
}
}
case domain.DeployProviderTypeBaotaPanelConsole, domain.DeployProviderTypeBaotaPanelSite: case domain.DeployProviderTypeBaotaPanelConsole, domain.DeployProviderTypeBaotaPanelSite:
{ {
access := domain.AccessConfigForBaotaPanel{} access := domain.AccessConfigForBaotaPanel{}

View File

@ -53,6 +53,10 @@ type AccessConfigForBaiduCloud struct {
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
} }
type AccessConfigForBaishan struct {
ApiToken string `json:"apiToken"`
}
type AccessConfigForBaotaPanel struct { type AccessConfigForBaotaPanel struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`

View File

@ -16,7 +16,7 @@ const (
AccessProviderTypeAWS = AccessProviderType("aws") AccessProviderTypeAWS = AccessProviderType("aws")
AccessProviderTypeAzure = AccessProviderType("azure") AccessProviderTypeAzure = AccessProviderType("azure")
AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud") AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud")
AccessProviderTypeBaishan = AccessProviderType("baishan") // 白山云(预留) AccessProviderTypeBaishan = AccessProviderType("baishan")
AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel") AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel")
AccessProviderTypeBytePlus = AccessProviderType("byteplus") AccessProviderTypeBytePlus = AccessProviderType("byteplus")
AccessProviderTypeCacheFly = AccessProviderType("cachefly") // CacheFly预留 AccessProviderTypeCacheFly = AccessProviderType("cachefly") // CacheFly预留
@ -107,6 +107,7 @@ const (
DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf") DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf")
DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront") DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront")
DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn")
DeployProviderTypeBaishanCDN = DeployProviderType("baishan-cdn")
DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console") DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console")
DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site") DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site")
DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn")

View File

@ -37,7 +37,7 @@ type Config struct {
} }
type DNSProvider struct { type DNSProvider struct {
client *gnamesdk.GnameClient client *gnamesdk.Client
config *Config config *Config
} }
@ -68,7 +68,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("gname: the configuration of the DNS provider is nil") return nil, errors.New("gname: the configuration of the DNS provider is nil")
} }
client := gnamesdk.NewGnameClient(config.AppID, config.AppKey). client := gnamesdk.NewClient(config.AppID, config.AppKey).
WithTimeout(config.HTTPTimeout) WithTimeout(config.HTTPTimeout)
return &DNSProvider{ return &DNSProvider{

View File

@ -0,0 +1,116 @@
package baishancdn
import (
"context"
"errors"
"fmt"
"time"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
bssdk "github.com/usual2970/certimate/internal/pkg/vendors/baishan-sdk"
)
type BaishanCDNDeployerConfig struct {
// 白山云 API Token。
ApiToken string `json:"apiToken"`
// 加速域名(支持泛域名)。
Domain string `json:"domain"`
}
type BaishanCDNDeployer struct {
config *BaishanCDNDeployerConfig
logger logger.Logger
sdkClient *bssdk.Client
}
var _ deployer.Deployer = (*BaishanCDNDeployer)(nil)
func New(config *BaishanCDNDeployerConfig) (*BaishanCDNDeployer, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *BaishanCDNDeployerConfig, logger logger.Logger) (*BaishanCDNDeployer, 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.ApiToken)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &BaishanCDNDeployer{
logger: logger,
config: config,
sdkClient: client,
}, nil
}
func (d *BaishanCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.Domain == "" {
return nil, errors.New("config `domain` is required")
}
// 查询域名配置
// REF: https://portal.baishancloud.com/track/document/api/1/1065
getDomainConfigReq := &bssdk.GetDomainConfigRequest{
Domains: d.config.Domain,
Config: "https",
}
getDomainConfigResp, err := d.sdkClient.GetDomainConfig(getDomainConfigReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.GetDomainConfig'")
} else if len(getDomainConfigResp.Data) == 0 {
return nil, errors.New("domain config not found")
} else {
d.logger.Logt("已查询到域名配置", getDomainConfigResp)
}
// 新增证书
// REF: https://portal.baishancloud.com/track/document/downloadPdf/1441
createCertificateReq := &bssdk.CreateCertificateRequest{
Certificate: certPem,
Key: privkeyPem,
Name: fmt.Sprintf("certimate_%d", time.Now().UnixMilli()),
}
createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.CreateCertificate'")
} else {
d.logger.Logt("已新增证书", createCertificateResp)
}
// 设置域名配置
// REF: https://portal.baishancloud.com/track/document/api/1/1045
setDomainConfigReq := &bssdk.SetDomainConfigRequest{
Domains: d.config.Domain,
Config: &bssdk.DomainConfig{
Https: &bssdk.DomainConfigHttps{
CertId: createCertificateResp.Data.CertId,
ForceHttps: getDomainConfigResp.Data[0].Config.Https.ForceHttps,
EnableHttp2: getDomainConfigResp.Data[0].Config.Https.EnableHttp2,
EnableOcsp: getDomainConfigResp.Data[0].Config.Https.EnableOcsp,
},
},
}
setDomainConfigResp, err := d.sdkClient.SetDomainConfig(setDomainConfigReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.SetDomainConfig'")
} else {
d.logger.Logt("已设置域名配置", setDomainConfigResp)
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiToken string) (*bssdk.Client, error) {
client := bssdk.NewClient(apiToken)
return client, nil
}

View File

@ -0,0 +1,70 @@
package baishancdn_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn"
)
var (
fInputCertPath string
fInputKeyPath string
fApiToken string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_BAISHANCDN_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./baishan_cdn_test.go -args \
--CERTIMATE_DEPLOYER_BAISHANCDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAISHANCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAISHANCDN_APITOKEN="your-api-token" \
--CERTIMATE_DEPLOYER_BAISHANCDN_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("APITOKEN: %v", fApiToken),
fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n"))
deployer, err := provider.New(&provider.BaishanCDNDeployerConfig{
ApiToken: fApiToken,
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)
})
}

View File

@ -23,7 +23,7 @@ type BaotaPanelConsoleDeployerConfig struct {
type BaotaPanelConsoleDeployer struct { type BaotaPanelConsoleDeployer struct {
config *BaotaPanelConsoleDeployerConfig config *BaotaPanelConsoleDeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *btsdk.BaoTaPanelClient sdkClient *btsdk.Client
} }
var _ deployer.Deployer = (*BaotaPanelConsoleDeployer)(nil) var _ deployer.Deployer = (*BaotaPanelConsoleDeployer)(nil)
@ -81,7 +81,7 @@ func (d *BaotaPanelConsoleDeployer) Deploy(ctx context.Context, certPem string,
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(apiUrl, apiKey string) (*btsdk.BaoTaPanelClient, error) { func createSdkClient(apiUrl, apiKey string) (*btsdk.Client, error) {
client := btsdk.NewBaoTaPanelClient(apiUrl, apiKey) client := btsdk.NewClient(apiUrl, apiKey)
return client, nil return client, nil
} }

View File

@ -16,14 +16,14 @@ type BaotaPanelSiteDeployerConfig struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
// 宝塔面板接口密钥。 // 宝塔面板接口密钥。
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
// 站点名称 // 站点名称
SiteName string `json:"siteName"` SiteName string `json:"siteName"`
} }
type BaotaPanelSiteDeployer struct { type BaotaPanelSiteDeployer struct {
config *BaotaPanelSiteDeployerConfig config *BaotaPanelSiteDeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *btsdk.BaoTaPanelClient sdkClient *btsdk.Client
} }
var _ deployer.Deployer = (*BaotaPanelSiteDeployer)(nil) var _ deployer.Deployer = (*BaotaPanelSiteDeployer)(nil)
@ -75,7 +75,7 @@ func (d *BaotaPanelSiteDeployer) Deploy(ctx context.Context, certPem string, pri
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(apiUrl, apiKey string) (*btsdk.BaoTaPanelClient, error) { func createSdkClient(apiUrl, apiKey string) (*btsdk.Client, error) {
client := btsdk.NewBaoTaPanelClient(apiUrl, apiKey) client := btsdk.NewClient(apiUrl, apiKey)
return client, nil return client, nil
} }

View File

@ -27,7 +27,7 @@ type SafeLineDeployerConfig struct {
type SafeLineDeployer struct { type SafeLineDeployer struct {
config *SafeLineDeployerConfig config *SafeLineDeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *safelinesdk.SafeLineClient sdkClient *safelinesdk.Client
} }
var _ deployer.Deployer = (*SafeLineDeployer)(nil) var _ deployer.Deployer = (*SafeLineDeployer)(nil)
@ -96,7 +96,7 @@ func (d *SafeLineDeployer) deployToCertificate(ctx context.Context, certPem stri
return nil return nil
} }
func createSdkClient(apiUrl, apiToken string) (*safelinesdk.SafeLineClient, error) { func createSdkClient(apiUrl, apiToken string) (*safelinesdk.Client, error) {
client := safelinesdk.NewSafeLineClient(apiUrl, apiToken) client := safelinesdk.NewClient(apiUrl, apiToken)
return client, nil return client, nil
} }

45
internal/pkg/vendors/baishan-sdk/api.go vendored Normal file
View File

@ -0,0 +1,45 @@
package baishansdk
import (
"encoding/json"
"net/http"
)
func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := CreateCertificateResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/certificate", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *Client) GetDomainConfig(req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := GetDomainConfigResponse{}
err := c.sendRequestWithResult(http.MethodGet, "/v2/domain/config", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *Client) SetDomainConfig(req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := SetDomainConfigResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/config", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}

View File

@ -0,0 +1,84 @@
package baishansdk
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/go-resty/resty/v2"
)
type Client struct {
apiToken string
client *resty.Client
}
func NewClient(apiToken string) *Client {
client := resty.New()
return &Client{
apiToken: apiToken,
client: client,
}
}
func (c *Client) WithTimeout(timeout time.Duration) *Client {
c.client.SetTimeout(timeout)
return c
}
func (c *Client) sendRequest(method string, path string, params map[string]any) (*resty.Response, error) {
url := "https://cdn.api.baishan.com" + path
req := c.client.R()
if method == http.MethodGet {
data := make(map[string]string)
for k, v := range params {
data[k] = fmt.Sprintf("%v", v)
}
req = req.
SetQueryParams(data).
SetQueryParam("token", c.apiToken)
} else if method == http.MethodPost {
req = req.
SetHeader("Content-Type", "application/json").
SetQueryParam("token", c.apiToken).
SetBody(params)
}
var resp *resty.Response
var err error
if method == http.MethodGet {
resp, err = req.Get(url)
} else if method == http.MethodPost {
resp, err = req.Post(url)
} else {
return nil, fmt.Errorf("baishan: unsupported method: %s", method)
}
if err != nil {
return nil, fmt.Errorf("baishan: failed to send request: %w", err)
} else if resp.IsError() {
return nil, fmt.Errorf("baishan: unexpected status code: %d, %s", resp.StatusCode(), resp.Body())
}
return resp, nil
}
func (c *Client) sendRequestWithResult(method string, path string, params map[string]any, result BaseResponse) error {
resp, err := c.sendRequest(method, path, params)
if err != nil {
return err
}
if err := json.Unmarshal(resp.Body(), &result); err != nil {
return fmt.Errorf("baishan: failed to parse response: %w", err)
}
if result.GetCode() != 0 {
return fmt.Errorf("baishan api error: %d, %s", result.GetCode(), result.GetMessage())
}
return nil
}

View File

@ -0,0 +1,77 @@
package baishansdk
type BaseResponse interface {
GetCode() int
GetMessage() string
}
type baseResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (r *baseResponse) GetCode() int {
return r.Code
}
func (r *baseResponse) GetMessage() string {
return r.Message
}
type CreateCertificateRequest struct {
Certificate string `json:"certificate"`
Key string `json:"key"`
Name string `json:"name"`
}
type CreateCertificateResponse struct {
baseResponse
Data *DomainCertificate `json:"data"`
}
type GetDomainConfigRequest struct {
Domains string `json:"domains"`
Config string `json:"config"`
}
type GetDomainConfigResponse struct {
baseResponse
Data []*GetDomainConfigResponseData `json:"data"`
}
type GetDomainConfigResponseData struct {
Domain string `json:"domain"`
Config *DomainConfig `json:"config"`
}
type SetDomainConfigRequest struct {
Domains string `json:"domains"`
Config *DomainConfig `json:"config"`
}
type SetDomainConfigResponse struct {
baseResponse
Data *SetDomainConfigResponseData `json:"data"`
}
type SetDomainConfigResponseData struct {
Config *DomainConfig `json:"config"`
}
type DomainCertificate struct {
CertId int64 `json:"cert_id"`
Name string `json:"name"`
CertStartTime string `json:"cert_start_time"`
CertExpireTime string `json:"cert_expire_time"`
}
type DomainConfig struct {
Https *DomainConfigHttps `json:"https"`
}
type DomainConfigHttps struct {
CertId int64 `json:"cert_id"`
ForceHttps *string `json:"force_https,omitempty"`
EnableHttp2 *string `json:"http2,omitempty"`
EnableOcsp *string `json:"ocsp,omitempty"`
}

View File

@ -1,48 +1,44 @@
package btpanelsdk package btpanelsdk
type BaseResponse interface { import (
GetStatus() *bool "encoding/json"
GetMsg() *string )
func (c *Client) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := ConfigSavePanelSSLResponse{}
err := c.sendRequestWithResult("/config?action=SavePanelSSL", params, &result)
if err != nil {
return nil, err
}
return &result, nil
} }
type baseResponse struct { func (c *Client) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) {
Status *bool `json:"status,omitempty"` params := make(map[string]any)
Msg *string `json:"msg,omitempty"` jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := SiteSetSSLResponse{}
err := c.sendRequestWithResult("/site?action=SetSSL", params, &result)
if err != nil {
return nil, err
}
return &result, nil
} }
func (r *baseResponse) GetStatus() *bool { func (c *Client) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) {
return r.Status params := make(map[string]any)
} jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
func (r *baseResponse) GetMsg() *string { result := SystemServiceAdminResponse{}
return r.Msg err := c.sendRequestWithResult("/system?action=ServiceAdmin", params, &result)
} if err != nil {
return nil, err
type ConfigSavePanelSSLRequest struct { }
PrivateKey string `json:"privateKey"` return &result, nil
Certificate string `json:"certPem"`
}
type ConfigSavePanelSSLResponse struct {
baseResponse
}
type SiteSetSSLRequest struct {
Type string `json:"type"`
SiteName string `json:"siteName"`
PrivateKey string `json:"key"`
Certificate string `json:"csr"`
}
type SiteSetSSLResponse struct {
baseResponse
}
type SystemServiceAdminRequest struct {
Name string `json:"name"`
Type string `json:"type"`
}
type SystemServiceAdminResponse struct {
baseResponse
} }

View File

@ -11,67 +11,28 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
) )
type BaoTaPanelClient struct { type Client struct {
apiHost string apiHost string
apiKey string apiKey string
client *resty.Client client *resty.Client
} }
func NewBaoTaPanelClient(apiHost, apiKey string) *BaoTaPanelClient { func NewClient(apiHost, apiKey string) *Client {
client := resty.New() client := resty.New()
return &BaoTaPanelClient{ return &Client{
apiHost: apiHost, apiHost: apiHost,
apiKey: apiKey, apiKey: apiKey,
client: client, client: client,
} }
} }
func (c *BaoTaPanelClient) WithTimeout(timeout time.Duration) *BaoTaPanelClient { func (c *Client) WithTimeout(timeout time.Duration) *Client {
c.client.SetTimeout(timeout) c.client.SetTimeout(timeout)
return c return c
} }
func (c *BaoTaPanelClient) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) { func (c *Client) generateSignature(timestamp string) string {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := ConfigSavePanelSSLResponse{}
err := c.sendRequestWithResult("/config?action=SavePanelSSL", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *BaoTaPanelClient) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := SiteSetSSLResponse{}
err := c.sendRequestWithResult("/site?action=SetSSL", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *BaoTaPanelClient) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := SystemServiceAdminResponse{}
err := c.sendRequestWithResult("/system?action=ServiceAdmin", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *BaoTaPanelClient) generateSignature(timestamp string) string {
keyMd5 := md5.Sum([]byte(c.apiKey)) keyMd5 := md5.Sum([]byte(c.apiKey))
keyMd5Hex := strings.ToLower(hex.EncodeToString(keyMd5[:])) keyMd5Hex := strings.ToLower(hex.EncodeToString(keyMd5[:]))
@ -80,7 +41,7 @@ func (c *BaoTaPanelClient) generateSignature(timestamp string) string {
return signMd5Hex return signMd5Hex
} }
func (c *BaoTaPanelClient) sendRequest(path string, params map[string]any) (*resty.Response, error) { func (c *Client) sendRequest(path string, params map[string]any) (*resty.Response, error) {
if params == nil { if params == nil {
params = make(map[string]any) params = make(map[string]any)
} }
@ -105,7 +66,7 @@ func (c *BaoTaPanelClient) sendRequest(path string, params map[string]any) (*res
return resp, nil return resp, nil
} }
func (c *BaoTaPanelClient) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error { func (c *Client) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error {
resp, err := c.sendRequest(path, params) resp, err := c.sendRequest(path, params)
if err != nil { if err != nil {
return err return err

View File

@ -0,0 +1,48 @@
package btpanelsdk
type BaseResponse interface {
GetStatus() *bool
GetMsg() *string
}
type baseResponse struct {
Status *bool `json:"status,omitempty"`
Msg *string `json:"msg,omitempty"`
}
func (r *baseResponse) GetStatus() *bool {
return r.Status
}
func (r *baseResponse) GetMsg() *string {
return r.Msg
}
type ConfigSavePanelSSLRequest struct {
PrivateKey string `json:"privateKey"`
Certificate string `json:"certPem"`
}
type ConfigSavePanelSSLResponse struct {
baseResponse
}
type SiteSetSSLRequest struct {
Type string `json:"type"`
SiteName string `json:"siteName"`
PrivateKey string `json:"key"`
Certificate string `json:"csr"`
}
type SiteSetSSLResponse struct {
baseResponse
}
type SystemServiceAdminRequest struct {
Name string `json:"name"`
Type string `json:"type"`
}
type SystemServiceAdminResponse struct {
baseResponse
}

View File

@ -1,79 +1,57 @@
package gnamesdk package gnamesdk
type BaseResponse interface { import (
GetCode() int "encoding/json"
GetMsg() string )
func (c *Client) AddDomainResolution(req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := AddDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/add", params, &result)
if err != nil {
return nil, err
}
return &result, nil
} }
type baseResponse struct { func (c *Client) ModifyDomainResolution(req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) {
Code int `json:"code"` params := make(map[string]any)
Msg string `json:"msg"` jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := ModifyDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/edit", params, &result)
if err != nil {
return nil, err
}
return &result, nil
} }
func (r *baseResponse) GetCode() int { func (c *Client) DeleteDomainResolution(req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) {
return r.Code params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := DeleteDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/delete", params, &result)
if err != nil {
return nil, err
}
return &result, nil
} }
func (r *baseResponse) GetMsg() string { func (c *Client) ListDomainResolution(req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) {
return r.Msg params := make(map[string]any)
} jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
type AddDomainResolutionRequest struct { result := ListDomainResolutionResponse{}
ZoneName string `json:"ym"` err := c.sendRequestWithResult("/api/resolution/list", params, &result)
RecordType string `json:"lx"` if err != nil {
RecordName string `json:"zj"` return nil, err
RecordValue string `json:"jlz"` }
MX int `json:"mx"` return &result, nil
TTL int `json:"ttl"`
}
type AddDomainResolutionResponse struct {
baseResponse
Data int `json:"data"`
}
type ModifyDomainResolutionRequest struct {
ID string `json:"jxid"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zj"`
RecordValue string `json:"jlz"`
MX int `json:"mx"`
TTL int `json:"ttl"`
}
type ModifyDomainResolutionResponse struct {
baseResponse
}
type DeleteDomainResolutionRequest struct {
ZoneName string `json:"ym"`
RecordID string `json:"jxid"`
}
type DeleteDomainResolutionResponse struct {
baseResponse
}
type ListDomainResolutionRequest struct {
ZoneName string `json:"ym"`
Page *int `json:"page,omitempty"`
PageSize *int `json:"limit,omitempty"`
}
type ListDomainResolutionResponse struct {
baseResponse
Count int `json:"count"`
Data []*ResolutionRecord `json:"data"`
Page int `json:"page"`
PageSize int `json:"pagesize"`
}
type ResolutionRecord struct {
ID string `json:"id"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zjt"`
RecordValue string `json:"jxz"`
MX int `json:"mx"`
} }

View File

@ -12,80 +12,28 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
) )
type GnameClient struct { type Client struct {
appId string appId string
appKey string appKey string
client *resty.Client client *resty.Client
} }
func NewGnameClient(appId, appKey string) *GnameClient { func NewClient(appId, appKey string) *Client {
client := resty.New() client := resty.New()
return &GnameClient{ return &Client{
appId: appId, appId: appId,
appKey: appKey, appKey: appKey,
client: client, client: client,
} }
} }
func (c *GnameClient) WithTimeout(timeout time.Duration) *GnameClient { func (c *Client) WithTimeout(timeout time.Duration) *Client {
c.client.SetTimeout(timeout) c.client.SetTimeout(timeout)
return c return c
} }
func (c *GnameClient) AddDomainResolution(req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) { func (c *Client) generateSignature(params map[string]string) string {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := AddDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/add", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *GnameClient) ModifyDomainResolution(req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := ModifyDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/edit", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *GnameClient) DeleteDomainResolution(req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := DeleteDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/delete", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *GnameClient) ListDomainResolution(req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := ListDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/list", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *GnameClient) generateSignature(params map[string]string) string {
// Step 1: Sort parameters by ASCII order // Step 1: Sort parameters by ASCII order
var keys []string var keys []string
for k := range params { for k := range params {
@ -109,7 +57,7 @@ func (c *GnameClient) generateSignature(params map[string]string) string {
return strings.ToUpper(fmt.Sprintf("%x", hash)) return strings.ToUpper(fmt.Sprintf("%x", hash))
} }
func (c *GnameClient) sendRequest(path string, params map[string]any) (*resty.Response, error) { func (c *Client) sendRequest(path string, params map[string]any) (*resty.Response, error) {
if params == nil { if params == nil {
params = make(map[string]any) params = make(map[string]any)
} }
@ -136,7 +84,7 @@ func (c *GnameClient) sendRequest(path string, params map[string]any) (*resty.Re
return resp, nil return resp, nil
} }
func (c *GnameClient) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error { func (c *Client) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error {
resp, err := c.sendRequest(path, params) resp, err := c.sendRequest(path, params)
if err != nil { if err != nil {
return err return err

View File

@ -0,0 +1,79 @@
package gnamesdk
type BaseResponse interface {
GetCode() int
GetMsg() string
}
type baseResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func (r *baseResponse) GetCode() int {
return r.Code
}
func (r *baseResponse) GetMsg() string {
return r.Msg
}
type AddDomainResolutionRequest struct {
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zj"`
RecordValue string `json:"jlz"`
MX int `json:"mx"`
TTL int `json:"ttl"`
}
type AddDomainResolutionResponse struct {
baseResponse
Data int `json:"data"`
}
type ModifyDomainResolutionRequest struct {
ID string `json:"jxid"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zj"`
RecordValue string `json:"jlz"`
MX int `json:"mx"`
TTL int `json:"ttl"`
}
type ModifyDomainResolutionResponse struct {
baseResponse
}
type DeleteDomainResolutionRequest struct {
ZoneName string `json:"ym"`
RecordID string `json:"jxid"`
}
type DeleteDomainResolutionResponse struct {
baseResponse
}
type ListDomainResolutionRequest struct {
ZoneName string `json:"ym"`
Page *int `json:"page,omitempty"`
PageSize *int `json:"limit,omitempty"`
}
type ListDomainResolutionResponse struct {
baseResponse
Count int `json:"count"`
Data []*ResolutionRecord `json:"data"`
Page int `json:"page"`
PageSize int `json:"pagesize"`
}
type ResolutionRecord struct {
ID string `json:"id"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zjt"`
RecordValue string `json:"jxz"`
MX int `json:"mx"`
}

View File

@ -1,34 +1,18 @@
package safelinesdk package safelinesdk
type BaseResponse interface { import (
GetErrCode() *string "encoding/json"
GetErrMsg() *string )
}
type baseResponse struct { func (c *Client) UpdateCertificate(req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) {
ErrCode *string `json:"err,omitempty"` params := make(map[string]any)
ErrMsg *string `json:"msg,omitempty"` jsonData, _ := json.Marshal(req)
} json.Unmarshal(jsonData, &params)
func (r *baseResponse) GetErrCode() *string { result := UpdateCertificateResponse{}
return r.ErrCode err := c.sendRequestWithResult("/api/open/cert", params, &result)
} if err != nil {
return nil, err
func (r *baseResponse) GetErrMsg() *string { }
return r.ErrMsg return &result, nil
}
type UpdateCertificateRequest struct {
Id int32 `json:"id"`
Type int32 `json:"type"`
Manual *UpdateCertificateRequestBodyManul `json:"manual"`
}
type UpdateCertificateRequestBodyManul struct {
Crt string `json:"crt"`
Key string `json:"key"`
}
type UpdateCertificateResponse struct {
baseResponse
} }

View File

@ -9,41 +9,28 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
) )
type SafeLineClient struct { type Client struct {
apiHost string apiHost string
apiToken string apiToken string
client *resty.Client client *resty.Client
} }
func NewSafeLineClient(apiHost, apiToken string) *SafeLineClient { func NewClient(apiHost, apiToken string) *Client {
client := resty.New() client := resty.New()
return &SafeLineClient{ return &Client{
apiHost: apiHost, apiHost: apiHost,
apiToken: apiToken, apiToken: apiToken,
client: client, client: client,
} }
} }
func (c *SafeLineClient) WithTimeout(timeout time.Duration) *SafeLineClient { func (c *Client) WithTimeout(timeout time.Duration) *Client {
c.client.SetTimeout(timeout) c.client.SetTimeout(timeout)
return c return c
} }
func (c *SafeLineClient) UpdateCertificate(req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { func (c *Client) sendRequest(path string, params map[string]any) (*resty.Response, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, &params)
result := UpdateCertificateResponse{}
err := c.sendRequestWithResult("/api/open/cert", params, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (c *SafeLineClient) sendRequest(path string, params map[string]any) (*resty.Response, error) {
if params == nil { if params == nil {
params = make(map[string]any) params = make(map[string]any)
} }
@ -65,7 +52,7 @@ func (c *SafeLineClient) sendRequest(path string, params map[string]any) (*resty
return resp, nil return resp, nil
} }
func (c *SafeLineClient) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error { func (c *Client) sendRequestWithResult(path string, params map[string]any, result BaseResponse) error {
resp, err := c.sendRequest(path, params) resp, err := c.sendRequest(path, params)
if err != nil { if err != nil {
return err return err

View File

@ -0,0 +1,34 @@
package safelinesdk
type BaseResponse interface {
GetErrCode() *string
GetErrMsg() *string
}
type baseResponse struct {
ErrCode *string `json:"err,omitempty"`
ErrMsg *string `json:"msg,omitempty"`
}
func (r *baseResponse) GetErrCode() *string {
return r.ErrCode
}
func (r *baseResponse) GetErrMsg() *string {
return r.ErrMsg
}
type UpdateCertificateRequest struct {
Id int32 `json:"id"`
Type int32 `json:"type"`
Manual *UpdateCertificateRequestBodyManul `json:"manual"`
}
type UpdateCertificateRequestBodyManul struct {
Crt string `json:"crt"`
Key string `json:"key"`
}
type UpdateCertificateResponse struct {
baseResponse
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -14,6 +14,7 @@ import AccessFormAliyunConfig from "./AccessFormAliyunConfig";
import AccessFormAWSConfig from "./AccessFormAWSConfig"; import AccessFormAWSConfig from "./AccessFormAWSConfig";
import AccessFormAzureConfig from "./AccessFormAzureConfig"; import AccessFormAzureConfig from "./AccessFormAzureConfig";
import AccessFormBaiduCloudConfig from "./AccessFormBaiduCloudConfig"; import AccessFormBaiduCloudConfig from "./AccessFormBaiduCloudConfig";
import AccessFormBaishanConfig from "./AccessFormBaishanConfig";
import AccessFormBaotaPanelConfig from "./AccessFormBaotaPanelConfig"; import AccessFormBaotaPanelConfig from "./AccessFormBaotaPanelConfig";
import AccessFormBytePlusConfig from "./AccessFormBytePlusConfig"; import AccessFormBytePlusConfig from "./AccessFormBytePlusConfig";
import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig"; import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig";
@ -101,6 +102,8 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
return <AccessFormAzureConfig {...nestedFormProps} />; return <AccessFormAzureConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.BAIDUCLOUD: case ACCESS_PROVIDERS.BAIDUCLOUD:
return <AccessFormBaiduCloudConfig {...nestedFormProps} />; return <AccessFormBaiduCloudConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.BAISHAN:
return <AccessFormBaishanConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.BAOTAPANEL: case ACCESS_PROVIDERS.BAOTAPANEL:
return <AccessFormBaotaPanelConfig {...nestedFormProps} />; return <AccessFormBaotaPanelConfig {...nestedFormProps} />;
case ACCESS_PROVIDERS.BYTEPLUS: case ACCESS_PROVIDERS.BYTEPLUS:

View File

@ -0,0 +1,56 @@
import { useTranslation } from "react-i18next";
import { Form, type FormInstance, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import { type AccessConfigForBaishan } from "@/domain/access";
type AccessFormBaishanConfigFieldValues = Nullish<AccessConfigForBaishan>;
export type AccessFormBaishanConfigProps = {
form: FormInstance;
formName: string;
disabled?: boolean;
initialValues?: AccessFormBaishanConfigFieldValues;
onValuesChange?: (values: AccessFormBaishanConfigFieldValues) => void;
};
const initFormModel = (): AccessFormBaishanConfigFieldValues => {
return {
apiToken: "",
};
};
const AccessFormBaishanConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormBaishanConfigProps) => {
const { t } = useTranslation();
const formSchema = z.object({
apiToken: z
.string()
.min(1, t("access.form.baishan_api_token.placeholder"))
.max(64, t("common.errmsg.string_max", { max: 64 }))
.trim(),
});
const formRule = createSchemaFieldRule(formSchema);
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="apiToken" label={t("access.form.baishan_api_token.label")} rules={[formRule]}>
<Input.Password autoComplete="new-password" placeholder={t("access.form.baishan_api_token.placeholder")} />
</Form.Item>
</Form>
);
};
export default AccessFormBaishanConfig;

View File

@ -27,6 +27,7 @@ import DeployNodeConfigFormAliyunOSSConfig from "./DeployNodeConfigFormAliyunOSS
import DeployNodeConfigFormAliyunWAFConfig from "./DeployNodeConfigFormAliyunWAFConfig"; import DeployNodeConfigFormAliyunWAFConfig from "./DeployNodeConfigFormAliyunWAFConfig";
import DeployNodeConfigFormAWSCloudFrontConfig from "./DeployNodeConfigFormAWSCloudFrontConfig"; import DeployNodeConfigFormAWSCloudFrontConfig from "./DeployNodeConfigFormAWSCloudFrontConfig";
import DeployNodeConfigFormBaiduCloudCDNConfig from "./DeployNodeConfigFormBaiduCloudCDNConfig"; import DeployNodeConfigFormBaiduCloudCDNConfig from "./DeployNodeConfigFormBaiduCloudCDNConfig";
import DeployNodeConfigFormBaishanCDNConfig from "./DeployNodeConfigFormBaishanCDNConfig";
import DeployNodeConfigFormBaotaPanelConsoleConfig from "./DeployNodeConfigFormBaotaPanelConsoleConfig"; import DeployNodeConfigFormBaotaPanelConsoleConfig from "./DeployNodeConfigFormBaotaPanelConsoleConfig";
import DeployNodeConfigFormBaotaPanelSiteConfig from "./DeployNodeConfigFormBaotaPanelSiteConfig"; import DeployNodeConfigFormBaotaPanelSiteConfig from "./DeployNodeConfigFormBaotaPanelSiteConfig";
import DeployNodeConfigFormBytePlusCDNConfig from "./DeployNodeConfigFormBytePlusCDNConfig"; import DeployNodeConfigFormBytePlusCDNConfig from "./DeployNodeConfigFormBytePlusCDNConfig";
@ -154,6 +155,8 @@ const DeployNodeConfigForm = forwardRef<DeployNodeConfigFormInstance, DeployNode
return <DeployNodeConfigFormAWSCloudFrontConfig {...nestedFormProps} />; return <DeployNodeConfigFormAWSCloudFrontConfig {...nestedFormProps} />;
case DEPLOY_PROVIDERS.BAIDUCLOUD_CDN: case DEPLOY_PROVIDERS.BAIDUCLOUD_CDN:
return <DeployNodeConfigFormBaiduCloudCDNConfig {...nestedFormProps} />; return <DeployNodeConfigFormBaiduCloudCDNConfig {...nestedFormProps} />;
case DEPLOY_PROVIDERS.BAISHAN_CDN:
return <DeployNodeConfigFormBaishanCDNConfig {...nestedFormProps} />;
case DEPLOY_PROVIDERS.BAOTAPANEL_CONSOLE: case DEPLOY_PROVIDERS.BAOTAPANEL_CONSOLE:
return <DeployNodeConfigFormBaotaPanelConsoleConfig {...nestedFormProps} />; return <DeployNodeConfigFormBaotaPanelConsoleConfig {...nestedFormProps} />;
case DEPLOY_PROVIDERS.BAOTAPANEL_SITE: case DEPLOY_PROVIDERS.BAOTAPANEL_SITE:

View File

@ -0,0 +1,65 @@
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 DeployNodeConfigFormBaishanCDNConfigFieldValues = Nullish<{
domain: string;
}>;
export type DeployNodeConfigFormBaishanCDNConfigProps = {
form: FormInstance;
formName: string;
disabled?: boolean;
initialValues?: DeployNodeConfigFormBaishanCDNConfigFieldValues;
onValuesChange?: (values: DeployNodeConfigFormBaishanCDNConfigFieldValues) => void;
};
const initFormModel = (): DeployNodeConfigFormBaishanCDNConfigFieldValues => {
return {};
};
const DeployNodeConfigFormBaishanCDNConfig = ({
form: formInst,
formName,
disabled,
initialValues,
onValuesChange,
}: DeployNodeConfigFormBaishanCDNConfigProps) => {
const { t } = useTranslation();
const formSchema = z.object({
domain: z
.string({ message: t("workflow_node.deploy.form.baishan_cdn_domain.placeholder") })
.refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
});
const formRule = createSchemaFieldRule(formSchema);
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="domain"
label={t("workflow_node.deploy.form.baishan_cdn_domain.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baishan_cdn_domain.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.baishan_cdn_domain.placeholder")} />
</Form.Item>
</Form>
);
};
export default DeployNodeConfigFormBaishanCDNConfig;

View File

@ -11,6 +11,7 @@ export interface AccessModel extends BaseModel {
| AccessConfigForAWS | AccessConfigForAWS
| AccessConfigForAzure | AccessConfigForAzure
| AccessConfigForBaiduCloud | AccessConfigForBaiduCloud
| AccessConfigForBaishan
| AccessConfigForBaotaPanel | AccessConfigForBaotaPanel
| AccessConfigForBytePlus | AccessConfigForBytePlus
| AccessConfigForCloudflare | AccessConfigForCloudflare
@ -67,6 +68,10 @@ export type AccessConfigForBaiduCloud = {
secretAccessKey: string; secretAccessKey: string;
}; };
export type AccessConfigForBaishan = {
apiToken: string;
};
export type AccessConfigForBaotaPanel = { export type AccessConfigForBaotaPanel = {
apiUrl: string; apiUrl: string;
apiKey: string; apiKey: string;

View File

@ -9,6 +9,7 @@ export const ACCESS_PROVIDERS = Object.freeze({
AWS: "aws", AWS: "aws",
AZURE: "azure", AZURE: "azure",
BAIDUCLOUD: "baiducloud", BAIDUCLOUD: "baiducloud",
BAISHAN: "baishan",
BAOTAPANEL: "baotapanel", BAOTAPANEL: "baotapanel",
BYTEPLUS: "byteplus", BYTEPLUS: "byteplus",
CLOUDFLARE: "cloudflare", CLOUDFLARE: "cloudflare",
@ -68,6 +69,7 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.AWS, "provider.aws", "/imgs/providers/aws.svg", [ACCESS_USAGES.APPLY, ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.AWS, "provider.aws", "/imgs/providers/aws.svg", [ACCESS_USAGES.APPLY, ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.BAIDUCLOUD, "provider.baiducloud", "/imgs/providers/baiducloud.svg", [ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.BAIDUCLOUD, "provider.baiducloud", "/imgs/providers/baiducloud.svg", [ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.QINIU, "provider.qiniu", "/imgs/providers/qiniu.svg", [ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.QINIU, "provider.qiniu", "/imgs/providers/qiniu.svg", [ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.BAISHAN, "provider.baishan", "/imgs/providers/baishan.png", [ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.DOGECLOUD, "provider.dogecloud", "/imgs/providers/dogecloud.svg", [ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.DOGECLOUD, "provider.dogecloud", "/imgs/providers/dogecloud.svg", [ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.BYTEPLUS, "provider.byteplus", "/imgs/providers/byteplus.svg", [ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.BYTEPLUS, "provider.byteplus", "/imgs/providers/byteplus.svg", [ACCESS_USAGES.DEPLOY]],
[ACCESS_PROVIDERS.UCLOUD, "provider.ucloud", "/imgs/providers/ucloud.svg", [ACCESS_USAGES.DEPLOY]], [ACCESS_PROVIDERS.UCLOUD, "provider.ucloud", "/imgs/providers/ucloud.svg", [ACCESS_USAGES.DEPLOY]],
@ -190,6 +192,7 @@ export const DEPLOY_PROVIDERS = Object.freeze({
ALIYUN_WAF: `${ACCESS_PROVIDERS.ALIYUN}-waf`, ALIYUN_WAF: `${ACCESS_PROVIDERS.ALIYUN}-waf`,
AWS_CLOUDFRONT: `${ACCESS_PROVIDERS.AWS}-cloudfront`, AWS_CLOUDFRONT: `${ACCESS_PROVIDERS.AWS}-cloudfront`,
BAIDUCLOUD_CDN: `${ACCESS_PROVIDERS.BAIDUCLOUD}-cdn`, BAIDUCLOUD_CDN: `${ACCESS_PROVIDERS.BAIDUCLOUD}-cdn`,
BAISHAN_CDN: `${ACCESS_PROVIDERS.BAISHAN}-cdn`,
BAOTAPANEL_CONSOLE: `${ACCESS_PROVIDERS.BAOTAPANEL}-console`, BAOTAPANEL_CONSOLE: `${ACCESS_PROVIDERS.BAOTAPANEL}-console`,
BAOTAPANEL_SITE: `${ACCESS_PROVIDERS.BAOTAPANEL}-site`, BAOTAPANEL_SITE: `${ACCESS_PROVIDERS.BAOTAPANEL}-site`,
BYTEPLUS_CDN: `${ACCESS_PROVIDERS.BYTEPLUS}-cdn`, BYTEPLUS_CDN: `${ACCESS_PROVIDERS.BYTEPLUS}-cdn`,
@ -286,6 +289,7 @@ export const deployProvidersMap: Map<DeployProvider["type"] | string, DeployProv
[DEPLOY_PROVIDERS.VOLCENGINE_LIVE, "provider.volcengine.live", DEPLOY_CATEGORIES.LIVE], [DEPLOY_PROVIDERS.VOLCENGINE_LIVE, "provider.volcengine.live", DEPLOY_CATEGORIES.LIVE],
[DEPLOY_PROVIDERS.QINIU_CDN, "provider.qiniu.cdn", DEPLOY_CATEGORIES.CDN], [DEPLOY_PROVIDERS.QINIU_CDN, "provider.qiniu.cdn", DEPLOY_CATEGORIES.CDN],
[DEPLOY_PROVIDERS.QINIU_PILI, "provider.qiniu.pili", DEPLOY_CATEGORIES.LIVE], [DEPLOY_PROVIDERS.QINIU_PILI, "provider.qiniu.pili", DEPLOY_CATEGORIES.LIVE],
[DEPLOY_PROVIDERS.BAISHAN_CDN, "provider.baishan.cdn", DEPLOY_CATEGORIES.CDN],
[DEPLOY_PROVIDERS.DOGECLOUD_CDN, "provider.dogecloud.cdn", DEPLOY_CATEGORIES.CDN], [DEPLOY_PROVIDERS.DOGECLOUD_CDN, "provider.dogecloud.cdn", DEPLOY_CATEGORIES.CDN],
[DEPLOY_PROVIDERS.BYTEPLUS_CDN, "provider.byteplus.cdn", DEPLOY_CATEGORIES.CDN], [DEPLOY_PROVIDERS.BYTEPLUS_CDN, "provider.byteplus.cdn", DEPLOY_CATEGORIES.CDN],
[DEPLOY_PROVIDERS.UCLOUD_US3, "provider.ucloud.us3", DEPLOY_CATEGORIES.STORAGE], [DEPLOY_PROVIDERS.UCLOUD_US3, "provider.ucloud.us3", DEPLOY_CATEGORIES.STORAGE],

View File

@ -65,6 +65,8 @@
"access.form.baiducloud_secret_access_key.label": "Baidu Cloud SecretAccessKey", "access.form.baiducloud_secret_access_key.label": "Baidu Cloud SecretAccessKey",
"access.form.baiducloud_secret_access_key.placeholder": "Please enter Baidu Cloud SecretAccessKey", "access.form.baiducloud_secret_access_key.placeholder": "Please enter Baidu Cloud SecretAccessKey",
"access.form.baiducloud_secret_access_key.tooltip": "For more information, see <a href=\"https://intl.cloud.baidu.com/doc/Reference/s/jjwvz2e3p-en\" target=\"_blank\">https://intl.cloud.baidu.com/doc/Reference/s/jjwvz2e3p-en</a>", "access.form.baiducloud_secret_access_key.tooltip": "For more information, see <a href=\"https://intl.cloud.baidu.com/doc/Reference/s/jjwvz2e3p-en\" target=\"_blank\">https://intl.cloud.baidu.com/doc/Reference/s/jjwvz2e3p-en</a>",
"access.form.baishan_api_token.label": "Baishan Cloud API token",
"access.form.baishan_api_token.placeholder": "Please enter Baishan Cloud API token",
"access.form.baotapanel_api_url.label": "BaoTa Panel URL", "access.form.baotapanel_api_url.label": "BaoTa Panel URL",
"access.form.baotapanel_api_url.placeholder": "Please enter BaoTa Panel URL", "access.form.baotapanel_api_url.placeholder": "Please enter BaoTa Panel URL",
"access.form.baotapanel_api_url.tooltip": "For more information, see <a href=\"https://www.bt.cn/bbs/thread-20376-1-1.html\" target=\"_blank\">https://www.bt.cn/bbs/thread-20376-1-1.html</a>", "access.form.baotapanel_api_url.tooltip": "For more information, see <a href=\"https://www.bt.cn/bbs/thread-20376-1-1.html\" target=\"_blank\">https://www.bt.cn/bbs/thread-20376-1-1.html</a>",

View File

@ -190,6 +190,9 @@
"workflow_node.deploy.form.baiducloud_cdn_domain.label": "Baidu Cloud CDN domain", "workflow_node.deploy.form.baiducloud_cdn_domain.label": "Baidu Cloud CDN domain",
"workflow_node.deploy.form.baiducloud_cdn_domain.placeholder": "Please enter Baidu Cloud CDN domain name", "workflow_node.deploy.form.baiducloud_cdn_domain.placeholder": "Please enter Baidu Cloud CDN domain name",
"workflow_node.deploy.form.baiducloud_cdn_domain.tooltip": "For more information, see <a href=\"https://console.bce.baidu.com/cdn\" target=\"_blank\">https://console.bce.baidu.com/cdn</a>", "workflow_node.deploy.form.baiducloud_cdn_domain.tooltip": "For more information, see <a href=\"https://console.bce.baidu.com/cdn\" target=\"_blank\">https://console.bce.baidu.com/cdn</a>",
"workflow_node.deploy.form.baishan_cdn_domain.label": "Baishan CDN domain",
"workflow_node.deploy.form.baishan_cdn_domain.placeholder": "Please enter Baishan CDN domain name",
"workflow_node.deploy.form.baishan_cdn_domain.tooltip": "For more information, see <a href=\"https://cdnx.console.baishan.com\" target=\"_blank\">https://cdnx.console.baishan.com</a>",
"workflow_node.deploy.form.baotapanel_console_auto_restart.label": "Auto restart after deployment", "workflow_node.deploy.form.baotapanel_console_auto_restart.label": "Auto restart after deployment",
"workflow_node.deploy.form.baotapanel_site_name.label": "BaoTa Panel site name", "workflow_node.deploy.form.baotapanel_site_name.label": "BaoTa Panel site name",
"workflow_node.deploy.form.baotapanel_site_name.placeholder": "Please enter BaoTa Panel site name", "workflow_node.deploy.form.baotapanel_site_name.placeholder": "Please enter BaoTa Panel site name",

View File

@ -65,6 +65,8 @@
"access.form.baiducloud_secret_access_key.label": "百度智能云 SecretAccessKey", "access.form.baiducloud_secret_access_key.label": "百度智能云 SecretAccessKey",
"access.form.baiducloud_secret_access_key.placeholder": "请输入百度智能云 SecretAccessKey", "access.form.baiducloud_secret_access_key.placeholder": "请输入百度智能云 SecretAccessKey",
"access.form.baiducloud_secret_access_key.tooltip": "这是什么?请参阅 <a href=\"https://cloud.baidu.com/doc/Reference/s/jjwvz2e3p\" target=\"_blank\">https://cloud.baidu.com/doc/Reference/s/jjwvz2e3p</a>", "access.form.baiducloud_secret_access_key.tooltip": "这是什么?请参阅 <a href=\"https://cloud.baidu.com/doc/Reference/s/jjwvz2e3p\" target=\"_blank\">https://cloud.baidu.com/doc/Reference/s/jjwvz2e3p</a>",
"access.form.baishan_api_token.label": "白山云 API Token",
"access.form.baishan_api_token.placeholder": "请输入白山云 API Token",
"access.form.baotapanel_api_url.label": "宝塔面板 URL", "access.form.baotapanel_api_url.label": "宝塔面板 URL",
"access.form.baotapanel_api_url.placeholder": "请输入宝塔面板 URL", "access.form.baotapanel_api_url.placeholder": "请输入宝塔面板 URL",
"access.form.baotapanel_api_url.tooltip": "这是什么?请参阅 <a href=\"https://www.bt.cn/bbs/thread-20376-1-1.html\" target=\"_blank\">https://www.bt.cn/bbs/thread-20376-1-1.html</a>", "access.form.baotapanel_api_url.tooltip": "这是什么?请参阅 <a href=\"https://www.bt.cn/bbs/thread-20376-1-1.html\" target=\"_blank\">https://www.bt.cn/bbs/thread-20376-1-1.html</a>",

View File

@ -137,10 +137,10 @@
"workflow_node.deploy.form.aliyun_clb_snidomain.tooltip": "这是什么?请参阅 <a href=\"https://slb.console.aliyun.com/clb\" target=\"_blank\">https://slb.console.aliyun.com/clb</a><br><br>不填写时,将替换监听器的默认证书。", "workflow_node.deploy.form.aliyun_clb_snidomain.tooltip": "这是什么?请参阅 <a href=\"https://slb.console.aliyun.com/clb\" target=\"_blank\">https://slb.console.aliyun.com/clb</a><br><br>不填写时,将替换监听器的默认证书。",
"workflow_node.deploy.form.aliyun_cdn_domain.label": "阿里云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.aliyun_cdn_domain.label": "阿里云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "请输入阿里云 CDN 加速域名", "workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "请输入阿里云 CDN 加速域名",
"workflow_node.deploy.form.aliyun_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://cdn.console.aliyun.com\" target=\"_blank\">https://cdn.console.aliyun.com</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.aliyun_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://cdn.console.aliyun.com\" target=\"_blank\">https://cdn.console.aliyun.com</a>",
"workflow_node.deploy.form.aliyun_dcdn_domain.label": "阿里云 DCDN 加速域名(支持泛域名)", "workflow_node.deploy.form.aliyun_dcdn_domain.label": "阿里云 DCDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "请输入阿里云 DCDN 加速域名", "workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "请输入阿里云 DCDN 加速域名",
"workflow_node.deploy.form.aliyun_dcdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://dcdn.console.aliyun.com\" target=\"_blank\">https://dcdn.console.aliyun.com</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.aliyun_dcdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://dcdn.console.aliyun.com\" target=\"_blank\">https://dcdn.console.aliyun.com</a>",
"workflow_node.deploy.form.aliyun_esa_region.label": "阿里云 ESA 服务地域", "workflow_node.deploy.form.aliyun_esa_region.label": "阿里云 ESA 服务地域",
"workflow_node.deploy.form.aliyun_esa_region.placeholder": "请输入阿里云 ESA 服务地域例如cn-hangzhou", "workflow_node.deploy.form.aliyun_esa_region.placeholder": "请输入阿里云 ESA 服务地域例如cn-hangzhou",
"workflow_node.deploy.form.aliyun_esa_region.tooltip": "这是什么?请参阅 <a href=\"https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint\" target=\"_blank\">https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint</a>", "workflow_node.deploy.form.aliyun_esa_region.tooltip": "这是什么?请参阅 <a href=\"https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint\" target=\"_blank\">https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint</a>",
@ -189,14 +189,17 @@
"workflow_node.deploy.form.aws_cloudfront_distribution_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html\" target=\"_blank\">https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html</a>", "workflow_node.deploy.form.aws_cloudfront_distribution_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html\" target=\"_blank\">https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html</a>",
"workflow_node.deploy.form.baiducloud_cdn_domain.label": "百度智能云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.baiducloud_cdn_domain.label": "百度智能云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.baiducloud_cdn_domain.placeholder": "请输入百度智能云 CDN 加速域名", "workflow_node.deploy.form.baiducloud_cdn_domain.placeholder": "请输入百度智能云 CDN 加速域名",
"workflow_node.deploy.form.baiducloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.bce.baidu.com/cdn\" target=\"_blank\">https://console.bce.baidu.com/cdn</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.baiducloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.bce.baidu.com/cdn\" target=\"_blank\">https://console.bce.baidu.com/cdn</a>",
"workflow_node.deploy.form.baishan_cdn_domain.label": "白山云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.baishan_cdn_domain.placeholder": "请输入白山云 CDN 加速域名",
"workflow_node.deploy.form.baishan_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://cdnx.console.baishan.com\" target=\"_blank\">https://cdnx.console.baishan.com</a>",
"workflow_node.deploy.form.baotapanel_console_auto_restart.label": "部署后自动重启面板服务", "workflow_node.deploy.form.baotapanel_console_auto_restart.label": "部署后自动重启面板服务",
"workflow_node.deploy.form.baotapanel_site_name.label": "宝塔面板网站名称", "workflow_node.deploy.form.baotapanel_site_name.label": "宝塔面板网站名称",
"workflow_node.deploy.form.baotapanel_site_name.placeholder": "请输入宝塔面板网站名称", "workflow_node.deploy.form.baotapanel_site_name.placeholder": "请输入宝塔面板网站名称",
"workflow_node.deploy.form.baotapanel_site_name.tooltip": "通常为网站域名。", "workflow_node.deploy.form.baotapanel_site_name.tooltip": "通常为网站域名。",
"workflow_node.deploy.form.byteplus_cdn_domain.label": "BytePlus CDN 域名(支持泛域名)", "workflow_node.deploy.form.byteplus_cdn_domain.label": "BytePlus CDN 域名(支持泛域名)",
"workflow_node.deploy.form.byteplus_cdn_domain.placeholder": "请输入 BytePlus CDN 域名", "workflow_node.deploy.form.byteplus_cdn_domain.placeholder": "请输入 BytePlus CDN 域名",
"workflow_node.deploy.form.byteplus_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.byteplus.com/cdn\" target=\"_blank\">https://console.byteplus.com/cdn</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.byteplus_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.byteplus.com/cdn\" target=\"_blank\">https://console.byteplus.com/cdn</a>",
"workflow_node.deploy.form.dogecloud_cdn_domain.label": "多吉云 CDN 加速域名", "workflow_node.deploy.form.dogecloud_cdn_domain.label": "多吉云 CDN 加速域名",
"workflow_node.deploy.form.dogecloud_cdn_domain.placeholder": "请输入多吉云 CDN 加速域名", "workflow_node.deploy.form.dogecloud_cdn_domain.placeholder": "请输入多吉云 CDN 加速域名",
"workflow_node.deploy.form.dogecloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.dogecloud.com\" target=\"_blank\">https://console.dogecloud.com</a>", "workflow_node.deploy.form.dogecloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.dogecloud.com\" target=\"_blank\">https://console.dogecloud.com</a>",
@ -293,7 +296,7 @@
"workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - 导入并绑定到 netsh需管理员权限", "workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - 导入并绑定到 netsh需管理员权限",
"workflow_node.deploy.form.qiniu_cdn_domain.label": "七牛云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.qiniu_cdn_domain.label": "七牛云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "请输入七牛云 CDN 加速域名", "workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "请输入七牛云 CDN 加速域名",
"workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://portal.qiniu.com/cdn\" target=\"_blank\">https://portal.qiniu.com/cdn</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://portal.qiniu.com/cdn\" target=\"_blank\">https://portal.qiniu.com/cdn</a>",
"workflow_node.deploy.form.qiniu_pili_hub.label": "七牛云视频直播空间名", "workflow_node.deploy.form.qiniu_pili_hub.label": "七牛云视频直播空间名",
"workflow_node.deploy.form.qiniu_pili_hub.placeholder": "请输入七牛云视频直播空间名", "workflow_node.deploy.form.qiniu_pili_hub.placeholder": "请输入七牛云视频直播空间名",
"workflow_node.deploy.form.qiniu_pili_hub.tooltip": "这是什么?请参阅 <a href=\"https://portal.qiniu.com/hub\" target=\"_blank\">https://portal.qiniu.com/hub</a>", "workflow_node.deploy.form.qiniu_pili_hub.tooltip": "这是什么?请参阅 <a href=\"https://portal.qiniu.com/hub\" target=\"_blank\">https://portal.qiniu.com/hub</a>",
@ -340,7 +343,7 @@
"workflow_node.deploy.form.ssh_use_scp.tooltip": "如果你的远程服务器不支持 SFTP请开启此选项回退为 SCP。", "workflow_node.deploy.form.ssh_use_scp.tooltip": "如果你的远程服务器不支持 SFTP请开启此选项回退为 SCP。",
"workflow_node.deploy.form.tencentcloud_cdn_domain.label": "腾讯云 CDN 加速域名(支持泛域名)", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "腾讯云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "请输入腾讯云 CDN 加速域名", "workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "请输入腾讯云 CDN 加速域名",
"workflow_node.deploy.form.tencentcloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/cdn\" target=\"_blank\">https://console.cloud.tencent.com/cdn</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.tencentcloud_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/cdn\" target=\"_blank\">https://console.cloud.tencent.com/cdn</a>",
"workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "证书替换方式", "workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "证书替换方式",
"workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder": "请选择证书替换方式", "workflow_node.deploy.form.tencentcloud_clb_resource_type.placeholder": "请选择证书替换方式",
"workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ssl_deploy.label": "通过 SSL 服务部署到云资源实例", "workflow_node.deploy.form.tencentcloud_clb_resource_type.option.ssl_deploy.label": "通过 SSL 服务部署到云资源实例",
@ -376,7 +379,7 @@
"workflow_node.deploy.form.tencentcloud_css_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/live/livestat\" target=\"_blank\">https://console.cloud.tencent.com/live/livestat</a>", "workflow_node.deploy.form.tencentcloud_css_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/live/livestat\" target=\"_blank\">https://console.cloud.tencent.com/live/livestat</a>",
"workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "腾讯云 ECDN 加速域名(支持泛域名)", "workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "腾讯云 ECDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "请输入腾讯云 ECDN 加速域名", "workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "请输入腾讯云 ECDN 加速域名",
"workflow_node.deploy.form.tencentcloud_ecdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/cdn\" target=\"_blank\">https://console.cloud.tencent.com/cdn</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.tencentcloud_ecdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/cdn\" target=\"_blank\">https://console.cloud.tencent.com/cdn</a>",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "请输入腾讯云 EdgeOne 站点 ID", "workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "请输入腾讯云 EdgeOne 站点 ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>", "workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
@ -422,7 +425,7 @@
"workflow_node.deploy.form.ucloud_us3_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.ucloud.cn/ufile\" target=\"_blank\">https://console.ucloud.cn/ufile</a>", "workflow_node.deploy.form.ucloud_us3_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.ucloud.cn/ufile\" target=\"_blank\">https://console.ucloud.cn/ufile</a>",
"workflow_node.deploy.form.volcengine_cdn_domain.label": "火山引擎 CDN 加速域名(支持泛域名)", "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.placeholder": "请输入火山引擎 CDN 加速域名",
"workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/cdn/homepage\" target=\"_blank\">https://console.volcengine.com/cdn/homepage</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.volcengine_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/cdn/homepage\" target=\"_blank\">https://console.volcengine.com/cdn/homepage</a>",
"workflow_node.deploy.form.volcengine_clb_resource_type.label": "证书替换方式", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "证书替换方式",
"workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "请选择证书替换方式", "workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "请选择证书替换方式",
"workflow_node.deploy.form.volcengine_clb_resource_type.option.listener.label": "替换指定监听器的证书", "workflow_node.deploy.form.volcengine_clb_resource_type.option.listener.label": "替换指定监听器的证书",
@ -434,7 +437,7 @@
"workflow_node.deploy.form.volcengine_clb_listener_id.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/clb/LoadBalancer\" target=\"_blank\">https://console.volcengine.com/clb/LoadBalancer</a>", "workflow_node.deploy.form.volcengine_clb_listener_id.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/clb/LoadBalancer\" target=\"_blank\">https://console.volcengine.com/clb/LoadBalancer</a>",
"workflow_node.deploy.form.volcengine_dcdn_domain.label": "火山引擎 DCDN 加速域名(支持泛域名)", "workflow_node.deploy.form.volcengine_dcdn_domain.label": "火山引擎 DCDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.volcengine_dcdn_domain.placeholder": "请输入火山引擎 DCDN 加速域名", "workflow_node.deploy.form.volcengine_dcdn_domain.placeholder": "请输入火山引擎 DCDN 加速域名",
"workflow_node.deploy.form.volcengine_dcdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/dcdn/dashboard\" target=\"_blank\">https://console.volcengine.com/dcdn/dashboard</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.volcengine_dcdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/dcdn/dashboard\" target=\"_blank\">https://console.volcengine.com/dcdn/dashboard</a>",
"workflow_node.deploy.form.volcengine_imagex_region.label": "火山引擎 ImageX 服务地域", "workflow_node.deploy.form.volcengine_imagex_region.label": "火山引擎 ImageX 服务地域",
"workflow_node.deploy.form.volcengine_imagex_region.placeholder": "请输入火山引擎 ImageX 服务地域例如cn-north-1", "workflow_node.deploy.form.volcengine_imagex_region.placeholder": "请输入火山引擎 ImageX 服务地域例如cn-north-1",
"workflow_node.deploy.form.volcengine_imagex_region.tooltip": "这是什么?请参阅 <a href=\"https://www.volcengine.com/docs/508/23757\" target=\"_blank\">https://www.volcengine.com/docs/508/23757</a>", "workflow_node.deploy.form.volcengine_imagex_region.tooltip": "这是什么?请参阅 <a href=\"https://www.volcengine.com/docs/508/23757\" target=\"_blank\">https://www.volcengine.com/docs/508/23757</a>",
@ -446,7 +449,7 @@
"workflow_node.deploy.form.volcengine_imagex_domain.tooltip": "这是什么?请参阅 see <a href=\"https://console.volcengine.com/imagex\" target=\"_blank\">https://console.volcengine.com/imagex</a>", "workflow_node.deploy.form.volcengine_imagex_domain.tooltip": "这是什么?请参阅 see <a href=\"https://console.volcengine.com/imagex\" target=\"_blank\">https://console.volcengine.com/imagex</a>",
"workflow_node.deploy.form.volcengine_live_domain.label": "火山引擎视频直播流域名(支持泛域名)", "workflow_node.deploy.form.volcengine_live_domain.label": "火山引擎视频直播流域名(支持泛域名)",
"workflow_node.deploy.form.volcengine_live_domain.placeholder": "请输入火山引擎视频直播流域名", "workflow_node.deploy.form.volcengine_live_domain.placeholder": "请输入火山引擎视频直播流域名",
"workflow_node.deploy.form.volcengine_live_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/live\" target=\"_blank\">https://console.volcengine.com/live</a><br><br>泛域名表示形式为:*.example.com", "workflow_node.deploy.form.volcengine_live_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.volcengine.com/live\" target=\"_blank\">https://console.volcengine.com/live</a>",
"workflow_node.deploy.form.volcengine_tos_region.label": "火山引擎 TOS 服务地域", "workflow_node.deploy.form.volcengine_tos_region.label": "火山引擎 TOS 服务地域",
"workflow_node.deploy.form.volcengine_tos_region.placeholder": "请输入火山引擎 TOS 服务地域例如cn-beijing", "workflow_node.deploy.form.volcengine_tos_region.placeholder": "请输入火山引擎 TOS 服务地域例如cn-beijing",
"workflow_node.deploy.form.volcengine_tos_region.tooltip": "这是什么?请参阅 <a href=\"https://www.volcengine.com/docs/6349/107356\" target=\"_blank\">https://www.volcengine.com/docs/6349/107356</a>", "workflow_node.deploy.form.volcengine_tos_region.tooltip": "这是什么?请参阅 <a href=\"https://www.volcengine.com/docs/6349/107356\" target=\"_blank\">https://www.volcengine.com/docs/6349/107356</a>",