mirror of
https://github.com/certimate-go/certimate.git
synced 2026-07-20 21:01:41 +08:00
feat(provider): new deployment provider: huaweicloud vod
This commit is contained in:
parent
78a61e256c
commit
757b299654
@ -20,6 +20,7 @@ func init() {
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
SecretAccessKey: credentials.SecretAccessKey,
|
||||
EnterpriseProjectId: credentials.EnterpriseProjectId,
|
||||
Region: xmaps.GetString(options.ProviderExtendedConfig, "region"),
|
||||
InstanceId: xmaps.GetString(options.ProviderExtendedConfig, "instanceId"),
|
||||
DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
|
||||
29
internal/certmgmt/deployers/sp_huaweicloud_vod.go
Normal file
29
internal/certmgmt/deployers/sp_huaweicloud_vod.go
Normal file
@ -0,0 +1,29 @@
|
||||
package deployers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/domain"
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
dplyimpl "github.com/certimate-go/certimate/pkg/core/deployer/providers/huaweicloud-vod"
|
||||
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Registries.MustRegister(domain.DeploymentProviderTypeHuaweiCloudVOD, func(options *ProviderFactoryOptions) (core.Deployer, error) {
|
||||
credentials := domain.AccessConfigForHuaweiCloud{}
|
||||
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
|
||||
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
||||
}
|
||||
|
||||
provider, err := dplyimpl.NewDeployer(&dplyimpl.DeployerConfig{
|
||||
AccessKeyId: credentials.AccessKeyId,
|
||||
SecretAccessKey: credentials.SecretAccessKey,
|
||||
EnterpriseProjectId: credentials.EnterpriseProjectId,
|
||||
Region: xmaps.GetString(options.ProviderExtendedConfig, "region"),
|
||||
DomainMatchPattern: xmaps.GetString(options.ProviderExtendedConfig, "domainMatchPattern"),
|
||||
Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"),
|
||||
})
|
||||
return provider, err
|
||||
})
|
||||
}
|
||||
@ -388,6 +388,7 @@ const (
|
||||
DeploymentProviderTypeHuaweiCloudLive = DeploymentProviderType(AccessProviderTypeHuaweiCloud + "-live")
|
||||
DeploymentProviderTypeHuaweiCloudOBS = DeploymentProviderType(AccessProviderTypeHuaweiCloud + "-obs")
|
||||
DeploymentProviderTypeHuaweiCloudSCM = DeploymentProviderType(AccessProviderTypeHuaweiCloud + "-scm")
|
||||
DeploymentProviderTypeHuaweiCloudVOD = DeploymentProviderType(AccessProviderTypeHuaweiCloud + "-vod")
|
||||
DeploymentProviderTypeHuaweiCloudWAF = DeploymentProviderType(AccessProviderTypeHuaweiCloud + "-waf")
|
||||
DeploymentProviderTypeJDCloudALB = DeploymentProviderType(AccessProviderTypeJDCloud + "-alb")
|
||||
DeploymentProviderTypeJDCloudCDN = DeploymentProviderType(AccessProviderTypeJDCloud + "-cdn")
|
||||
|
||||
@ -32,6 +32,8 @@ type DeployerConfig struct {
|
||||
SecretAccessKey string `json:"secretAccessKey"`
|
||||
// 华为云企业项目 ID。
|
||||
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
|
||||
// 华为云区域。
|
||||
Region string `json:"region"`
|
||||
// DDoS 高防实例 ID。
|
||||
InstanceId string `json:"instanceId"`
|
||||
// 域名匹配模式。
|
||||
@ -59,7 +61,7 @@ func NewDeployer(config *DeployerConfig) (*Deployer, error) {
|
||||
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
|
||||
}
|
||||
|
||||
clients, err := createSDKClients(config.AccessKeyId, config.SecretAccessKey)
|
||||
clients, err := createSDKClients(config.AccessKeyId, config.SecretAccessKey, config.Region)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create client: %w", err)
|
||||
}
|
||||
@ -251,12 +253,14 @@ func (d *Deployer) updateDomainCertificate(ctx context.Context, cloudDomainId st
|
||||
return nil
|
||||
}
|
||||
|
||||
func createSDKClients(accessKeyId, secretAccessKey string) (*wSDKClients, error) {
|
||||
func createSDKClients(accessKeyId, secretAccessKey, region string) (*wSDKClients, error) {
|
||||
wsdk := &wSDKClients{}
|
||||
|
||||
{
|
||||
region := "cn-north-4" // AAD 服务默认区域:华北北京四
|
||||
if region == "" {
|
||||
region = "cn-north-4" // AAD 服务默认区域:华北北京四
|
||||
}
|
||||
|
||||
{
|
||||
auth, err := global.NewCredentialsBuilder().
|
||||
WithAk(accessKeyId).
|
||||
WithSk(secretAccessKey).
|
||||
@ -283,8 +287,6 @@ func createSDKClients(accessKeyId, secretAccessKey string) (*wSDKClients, error)
|
||||
}
|
||||
|
||||
{
|
||||
region := "cn-north-4" // AAD 服务默认区域:华北北京四
|
||||
|
||||
auth, err := global.NewCredentialsBuilder().
|
||||
WithAk(accessKeyId).
|
||||
WithSk(secretAccessKey).
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
hwapigmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/apig/v2/model"
|
||||
hwapigregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/apig/v2/region"
|
||||
hwiam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
|
||||
hwiamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiammodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
|
||||
"github.com/samber/lo"
|
||||
|
||||
@ -188,7 +188,7 @@ func getSDKProjectId(accessKeyId, secretAccessKey, region string) (string, error
|
||||
|
||||
client := hwiam.NewIamClient(hcClient)
|
||||
|
||||
request := &hwiamModel.KeystoneListProjectsRequest{
|
||||
request := &hwiammodel.KeystoneListProjectsRequest{
|
||||
Name: ®ion,
|
||||
}
|
||||
response, err := client.KeystoneListProjects(request)
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
|
||||
hwiam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
|
||||
hwiamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiammodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
|
||||
hwlivemodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/live/v1/model"
|
||||
hwliveregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/live/v1/region"
|
||||
@ -262,7 +262,7 @@ func getSDKProjectId(accessKeyId, secretAccessKey, region string) (string, error
|
||||
|
||||
client := hwiam.NewIamClient(hcClient)
|
||||
|
||||
request := &hwiamModel.KeystoneListProjectsRequest{
|
||||
request := &hwiammodel.KeystoneListProjectsRequest{
|
||||
Name: ®ion,
|
||||
}
|
||||
response, err := client.KeystoneListProjects(request)
|
||||
|
||||
6
pkg/core/deployer/providers/huaweicloud-vod/consts.go
Normal file
6
pkg/core/deployer/providers/huaweicloud-vod/consts.go
Normal file
@ -0,0 +1,6 @@
|
||||
package huaweicloudvod
|
||||
|
||||
const (
|
||||
// 匹配模式:精确匹配。
|
||||
DOMAIN_MATCH_PATTERN_EXACT = "exact"
|
||||
)
|
||||
249
pkg/core/deployer/providers/huaweicloud-vod/huaweicloud_vod.go
Normal file
249
pkg/core/deployer/providers/huaweicloud-vod/huaweicloud_vod.go
Normal file
@ -0,0 +1,249 @@
|
||||
package huaweicloudvod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
|
||||
hwiam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
|
||||
hwiammodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
|
||||
hwvodmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1/model"
|
||||
hwvodregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1/region"
|
||||
"github.com/samber/lo"
|
||||
|
||||
hwvod "github.com/certimate-go/certimate/pkg/sdk3rd-trimmed/github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core"
|
||||
cmgrimpl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/huaweicloud-scm"
|
||||
)
|
||||
|
||||
type (
|
||||
Provider = core.Deployer
|
||||
DeployResult = core.DeployerDeployResult
|
||||
)
|
||||
|
||||
type DeployerConfig struct {
|
||||
// 华为云 AccessKeyId。
|
||||
AccessKeyId string `json:"accessKeyId"`
|
||||
// 华为云 SecretAccessKey。
|
||||
SecretAccessKey string `json:"secretAccessKey"`
|
||||
// 华为云企业项目 ID。
|
||||
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
|
||||
// 华为云区域。
|
||||
Region string `json:"region"`
|
||||
// 域名匹配模式。
|
||||
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
|
||||
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
|
||||
// 点播加速域名(不支持泛域名)。
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
|
||||
type Deployer struct {
|
||||
config *DeployerConfig
|
||||
logger *slog.Logger
|
||||
sdkClient *hwvod.VodClient
|
||||
sdkCertmgr core.Certmgr
|
||||
}
|
||||
|
||||
var _ Provider = (*Deployer)(nil)
|
||||
|
||||
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
|
||||
}
|
||||
|
||||
client, err := createSDKClient(
|
||||
config.AccessKeyId,
|
||||
config.SecretAccessKey,
|
||||
config.Region,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create client: %w", err)
|
||||
}
|
||||
|
||||
pcertmgr, err := cmgrimpl.NewCertmgr(&cmgrimpl.CertmgrConfig{
|
||||
AccessKeyId: config.AccessKeyId,
|
||||
SecretAccessKey: config.SecretAccessKey,
|
||||
EnterpriseProjectId: config.EnterpriseProjectId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create certmgr: %w", err)
|
||||
}
|
||||
|
||||
return &Deployer{
|
||||
config: config,
|
||||
logger: slog.Default(),
|
||||
sdkClient: client,
|
||||
sdkCertmgr: pcertmgr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Deployer) SetLogger(logger *slog.Logger) {
|
||||
if logger == nil {
|
||||
d.logger = slog.New(slog.DiscardHandler)
|
||||
} else {
|
||||
d.logger = logger
|
||||
}
|
||||
|
||||
d.sdkCertmgr.SetLogger(logger)
|
||||
}
|
||||
|
||||
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*DeployResult, error) {
|
||||
// 上传证书
|
||||
upres, err := d.sdkCertmgr.Upload(ctx, certPEM, privkeyPEM)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
|
||||
} else {
|
||||
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
|
||||
}
|
||||
|
||||
// 获取待部署的域名列表
|
||||
var domains []string
|
||||
switch d.config.DomainMatchPattern {
|
||||
case "", DOMAIN_MATCH_PATTERN_EXACT:
|
||||
{
|
||||
if d.config.Domain == "" {
|
||||
return nil, fmt.Errorf("config `domain` is required")
|
||||
}
|
||||
|
||||
domains = []string{d.config.Domain}
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported domain match pattern: '%s'", d.config.DomainMatchPattern)
|
||||
}
|
||||
|
||||
// 遍历更新域名证书
|
||||
if len(domains) == 0 {
|
||||
d.logger.Info("no vod domains to deploy")
|
||||
} else {
|
||||
d.logger.Info("found vod domains to deploy", slog.Any("domains", domains))
|
||||
var errs []error
|
||||
|
||||
for _, domain := range domains {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
if err := d.updateDomainsCertificate(ctx, domain, upres.CertId); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return nil, errors.Join(errs...)
|
||||
}
|
||||
}
|
||||
|
||||
return &DeployResult{}, nil
|
||||
}
|
||||
|
||||
func (d *Deployer) updateDomainsCertificate(ctx context.Context, domain string, cloudCertId string) error {
|
||||
// 查询 HTTPS 配置
|
||||
// REF: https://support.huaweicloud.com/api-vod/ShowHttpsConfig.html
|
||||
showHttpsConfigReq := &hwvodmodel.ShowHttpsConfigRequest{
|
||||
Domain: domain,
|
||||
}
|
||||
showHttpsConfigResp, err := d.sdkClient.ShowHttpsConfig(showHttpsConfigReq)
|
||||
d.logger.Debug("sdk request 'vod.ShowHttpsConfig'", slog.Any("request", showHttpsConfigReq), slog.Any("response", showHttpsConfigResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'vod.ShowHttpsConfig': %w", err)
|
||||
} else if lo.FromPtr(showHttpsConfigResp.CertId) == cloudCertId {
|
||||
// 已部署过,直接返回
|
||||
return nil
|
||||
}
|
||||
|
||||
// 配置 HTTPS
|
||||
// REF: https://support.huaweicloud.com/api-vod/UpdateHttpsConfig.html
|
||||
updateHttpsConfigReq := &hwvodmodel.UpdateHttpsConfigRequest{
|
||||
Body: &hwvodmodel.ConfigCdnHttpsReq{
|
||||
Domain: domain,
|
||||
Source: lo.ToPtr("scm"),
|
||||
CertId: lo.ToPtr(cloudCertId),
|
||||
HttpsStatus: lo.ToPtr(int32(1)),
|
||||
Http2: showHttpsConfigResp.Http2,
|
||||
ForceRedirectHttps: showHttpsConfigResp.ForceRedirectHttps,
|
||||
},
|
||||
}
|
||||
updateHttpsConfigResp, err := d.sdkClient.UpdateHttpsConfig(updateHttpsConfigReq)
|
||||
d.logger.Debug("sdk request 'vod.UpdateHttpsConfig'", slog.Any("request", updateHttpsConfigReq), slog.Any("response", updateHttpsConfigResp))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute sdk request 'vod.UpdateHttpsConfig': %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createSDKClient(accessKeyId, secretAccessKey, region string) (*hwvod.VodClient, error) {
|
||||
projectId, err := getSDKProjectId(accessKeyId, secretAccessKey, region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auth, err := basic.NewCredentialsBuilder().
|
||||
WithAk(accessKeyId).
|
||||
WithSk(secretAccessKey).
|
||||
WithProjectId(projectId).
|
||||
SafeBuild()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hcRegion, err := hwvodregion.SafeValueOf(region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hcClient, err := hwvod.VodClientBuilder().
|
||||
WithRegion(hcRegion).
|
||||
WithCredential(auth).
|
||||
SafeBuild()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := hwvod.NewVodClient(hcClient)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func getSDKProjectId(accessKeyId, secretAccessKey, region string) (string, error) {
|
||||
auth, err := global.NewCredentialsBuilder().
|
||||
WithAk(accessKeyId).
|
||||
WithSk(secretAccessKey).
|
||||
SafeBuild()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hcRegion, err := hwiamregion.SafeValueOf(region)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hcClient, err := hwiam.IamClientBuilder().
|
||||
WithRegion(hcRegion).
|
||||
WithCredential(auth).
|
||||
SafeBuild()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
client := hwiam.NewIamClient(hcClient)
|
||||
|
||||
request := &hwiammodel.KeystoneListProjectsRequest{
|
||||
Name: ®ion,
|
||||
}
|
||||
response, err := client.KeystoneListProjects(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if response.Projects == nil || len(*response.Projects) == 0 {
|
||||
return "", fmt.Errorf("huaweicloud: no project found")
|
||||
}
|
||||
|
||||
return (*response.Projects)[0].Id, nil
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package huaweicloudvod_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/certimate-go/certimate/pkg/core/deployer/internal/tester"
|
||||
impl "github.com/certimate-go/certimate/pkg/core/deployer/providers/huaweicloud-vod"
|
||||
)
|
||||
|
||||
var (
|
||||
fp = tester.Args("HUAWEICLOUDVOD_")
|
||||
fTestCertPath string
|
||||
fTestKeyPath string
|
||||
fAccessKeyId string
|
||||
fSecretAccessKey string
|
||||
fRegion string
|
||||
fDomain string
|
||||
)
|
||||
|
||||
func init() {
|
||||
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
|
||||
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
|
||||
fp.DefineString(&fAccessKeyId, "ACCESSKEYID")
|
||||
fp.DefineString(&fSecretAccessKey, "SECRETACCESSKEY")
|
||||
fp.DefineString(&fRegion, "REGION")
|
||||
fp.DefineString(&fDomain, "DOMAIN")
|
||||
}
|
||||
|
||||
/*
|
||||
Shell command to run this test:
|
||||
|
||||
go test -v ./huaweicloud_vod_test.go -args \
|
||||
--HUAWEICLOUDVOD_TESTCERTPATH="/path/to/your-test-cert.pem" \
|
||||
--HUAWEICLOUDVOD_TESTKEYPATH="/path/to/your-test-key.pem" \
|
||||
--HUAWEICLOUDVOD_ACCESSKEYID="your-access-key-id" \
|
||||
--HUAWEICLOUDVOD_SECRETACCESSKEY="your-secret-access-key" \
|
||||
--HUAWEICLOUDVOD_REGION="cn-north-1" \
|
||||
--HUAWEICLOUDVOD_DOMAIN="example.com"
|
||||
*/
|
||||
func TestProvider(t *testing.T) {
|
||||
fp.Parse()
|
||||
|
||||
t.Run("Deploy", func(t *testing.T) {
|
||||
provider, err := impl.NewDeployer(&impl.DeployerConfig{
|
||||
AccessKeyId: fAccessKeyId,
|
||||
SecretAccessKey: fSecretAccessKey,
|
||||
Region: fRegion,
|
||||
DomainMatchPattern: impl.DOMAIN_MATCH_PATTERN_EXACT,
|
||||
Domain: fDomain,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("err: %+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
tester.TestDeploy(t, provider, tester.TestDeployArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
|
||||
})
|
||||
}
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
|
||||
hwiam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
|
||||
hwiamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiammodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
|
||||
hwiamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
|
||||
hwwafmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/model"
|
||||
hwwafregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/region"
|
||||
@ -372,7 +372,7 @@ func getSDKProjectId(accessKeyId, secretAccessKey, region string) (string, error
|
||||
|
||||
client := hwiam.NewIamClient(hcClient)
|
||||
|
||||
request := &hwiamModel.KeystoneListProjectsRequest{
|
||||
request := &hwiammodel.KeystoneListProjectsRequest{
|
||||
Name: ®ion,
|
||||
}
|
||||
response, err := client.KeystoneListProjects(request)
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
httpclient "github.com/huaweicloud/huaweicloud-sdk-go-v3/core"
|
||||
vod "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1"
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1/model"
|
||||
)
|
||||
|
||||
type VodClient struct {
|
||||
HcClient *httpclient.HcHttpClient
|
||||
}
|
||||
|
||||
func NewVodClient(hcClient *httpclient.HcHttpClient) *VodClient {
|
||||
return &VodClient{HcClient: hcClient}
|
||||
}
|
||||
|
||||
func VodClientBuilder() *httpclient.HcHttpClientBuilder {
|
||||
return vod.VodClientBuilder()
|
||||
}
|
||||
|
||||
func (c *VodClient) ShowHttpsConfig(request *model.ShowHttpsConfigRequest) (*model.ShowHttpsConfigResponse, error) {
|
||||
requestDef := GenReqDefForShowHttpsConfig()
|
||||
|
||||
if resp, err := c.HcClient.Sync(request, requestDef); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return resp.(*model.ShowHttpsConfigResponse), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *VodClient) UpdateHttpsConfig(request *model.UpdateHttpsConfigRequest) (*model.UpdateHttpsConfigResponse, error) {
|
||||
requestDef := GenReqDefForUpdateHttpsConfig()
|
||||
|
||||
if resp, err := c.HcClient.Sync(request, requestDef); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return resp.(*model.UpdateHttpsConfigResponse), nil
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/def"
|
||||
vod "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/vod/v1"
|
||||
)
|
||||
|
||||
func GenReqDefForShowHttpsConfig() *def.HttpRequestDef {
|
||||
return vod.GenReqDefForShowHttpsConfig()
|
||||
}
|
||||
|
||||
func GenReqDefForUpdateHttpsConfig() *def.HttpRequestDef {
|
||||
return vod.GenReqDefForUpdateHttpsConfig()
|
||||
}
|
||||
@ -72,6 +72,7 @@ import BizDeployNodeConfigFieldsProviderHuaweiCloudCDN from "./BizDeployNodeConf
|
||||
import BizDeployNodeConfigFieldsProviderHuaweiCloudELB from "./BizDeployNodeConfigFieldsProviderHuaweiCloudELB";
|
||||
import BizDeployNodeConfigFieldsProviderHuaweiCloudLive from "./BizDeployNodeConfigFieldsProviderHuaweiCloudLive";
|
||||
import BizDeployNodeConfigFieldsProviderHuaweiCloudOBS from "./BizDeployNodeConfigFieldsProviderHuaweiCloudOBS";
|
||||
import BizDeployNodeConfigFieldsProviderHuaweiCloudVOD from "./BizDeployNodeConfigFieldsProviderHuaweiCloudVOD";
|
||||
import BizDeployNodeConfigFieldsProviderHuaweiCloudWAF from "./BizDeployNodeConfigFieldsProviderHuaweiCloudWAF";
|
||||
import BizDeployNodeConfigFieldsProviderJDCloudALB from "./BizDeployNodeConfigFieldsProviderJDCloudALB";
|
||||
import BizDeployNodeConfigFieldsProviderJDCloudCDN from "./BizDeployNodeConfigFieldsProviderJDCloudCDN";
|
||||
@ -219,6 +220,7 @@ const providerComponentMap: Partial<Record<DeploymentProviderType, React.Compone
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_ELB]: BizDeployNodeConfigFieldsProviderHuaweiCloudELB,
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_LIVE]: BizDeployNodeConfigFieldsProviderHuaweiCloudLive,
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_OBS]: BizDeployNodeConfigFieldsProviderHuaweiCloudOBS,
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_VOD]: BizDeployNodeConfigFieldsProviderHuaweiCloudVOD,
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_WAF]: BizDeployNodeConfigFieldsProviderHuaweiCloudWAF,
|
||||
[DEPLOYMENT_PROVIDERS.JDCLOUD_ALB]: BizDeployNodeConfigFieldsProviderJDCloudALB,
|
||||
[DEPLOYMENT_PROVIDERS.JDCLOUD_CDN]: BizDeployNodeConfigFieldsProviderJDCloudCDN,
|
||||
|
||||
@ -27,6 +27,16 @@ const BizDeployNodeConfigFieldsProviderHuaweiCloudAAD = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.huaweicloud_aad_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.huaweicloud_aad_region.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.huaweicloud_aad_region.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "instanceId"]}
|
||||
initialValue={initialValues.instanceId}
|
||||
@ -74,6 +84,7 @@ const BizDeployNodeConfigFieldsProviderHuaweiCloudAAD = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
instanceId: "",
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domain: "",
|
||||
@ -85,6 +96,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
|
||||
|
||||
return z
|
||||
.object({
|
||||
region: z.string().nonempty(),
|
||||
instanceId: z.string().nonempty(),
|
||||
domainMatchPattern: z.string().nonempty().default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domain: z.string().nullish(),
|
||||
|
||||
@ -26,6 +26,16 @@ const BizDeployNodeConfigFieldsProviderHuaweiCloudLive = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.huaweicloud_live_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.huaweicloud_live_region.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.huaweicloud_live_region.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domainMatchPattern"]}
|
||||
initialValue={initialValues.domainMatchPattern}
|
||||
@ -56,6 +66,7 @@ const BizDeployNodeConfigFieldsProviderHuaweiCloudLive = () => {
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domain: "",
|
||||
};
|
||||
@ -66,6 +77,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> })
|
||||
|
||||
return z
|
||||
.object({
|
||||
region: z.string().nonempty(),
|
||||
domainMatchPattern: z.string().nonempty().default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domain: z.string().nullish(),
|
||||
})
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Form, Input, Radio } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { isDomain } from "@/utils/validator";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
const DOMAIN_MATCH_PATTERN_EXACT = "exact" as const;
|
||||
|
||||
const BizDeployNodeConfigFieldsProviderHuaweiCloudVOD = () => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const { parentNamePath } = useFormNestedFieldsContext();
|
||||
const formSchema = z.object({
|
||||
[parentNamePath]: getSchema({ i18n }),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const initialValues = getInitialValues();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.huaweicloud_vod_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.huaweicloud_vod_region.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.huaweicloud_vod_region.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domainMatchPattern"]}
|
||||
initialValue={initialValues.domainMatchPattern}
|
||||
label={t("workflow_node.deploy.form.shared_domain_match_pattern.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Radio.Group
|
||||
options={[DOMAIN_MATCH_PATTERN_EXACT].map((s) => ({
|
||||
label: t(`workflow_node.deploy.form.shared_domain_match_pattern.option.${s}.label`),
|
||||
value: s,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.huaweicloud_vod_domain.label")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.huaweicloud_vod_domain.placeholder")} />
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
return {
|
||||
region: "",
|
||||
domainMatchPattern: DOMAIN_MATCH_PATTERN_EXACT,
|
||||
domain: "",
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
.object({
|
||||
region: z.string().nonempty(),
|
||||
domainMatchPattern: z.string().nonempty().default(DOMAIN_MATCH_PATTERN_EXACT),
|
||||
domain: z.string().nullish(),
|
||||
})
|
||||
.superRefine((values, ctx) => {
|
||||
if (values.domainMatchPattern) {
|
||||
switch (values.domainMatchPattern) {
|
||||
case DOMAIN_MATCH_PATTERN_EXACT:
|
||||
{
|
||||
const scDomain = z.string().refine((v) => isDomain(v), t("common.errmsg.domain_invalid"));
|
||||
const spDomain = scDomain.safeParse(values.domain);
|
||||
if (!spDomain.success) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: z.treeifyError(spDomain.error).errors.join(),
|
||||
path: ["domain"],
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const _default = Object.assign(BizDeployNodeConfigFieldsProviderHuaweiCloudVOD, {
|
||||
getInitialValues,
|
||||
getSchema,
|
||||
});
|
||||
|
||||
export default _default;
|
||||
@ -678,6 +678,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
|
||||
HUAWEICLOUD_LIVE: `${ACCESS_PROVIDERS.HUAWEICLOUD}-live`,
|
||||
HUAWEICLOUD_OBS: `${ACCESS_PROVIDERS.HUAWEICLOUD}-obs`,
|
||||
HUAWEICLOUD_SCM: `${ACCESS_PROVIDERS.HUAWEICLOUD}-scm`,
|
||||
HUAWEICLOUD_VOD: `${ACCESS_PROVIDERS.HUAWEICLOUD}-vod`,
|
||||
HUAWEICLOUD_WAF: `${ACCESS_PROVIDERS.HUAWEICLOUD}-waf`,
|
||||
JDCLOUD_ALB: `${ACCESS_PROVIDERS.JDCLOUD}-alb`,
|
||||
JDCLOUD_CDN: `${ACCESS_PROVIDERS.JDCLOUD}-cdn`,
|
||||
@ -829,6 +830,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_WAF, "provider.huaweicloud_waf", DEPLOYMENT_CATEGORIES.FIREWALL],
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_AAD, "provider.huaweicloud_aad", DEPLOYMENT_CATEGORIES.FIREWALL],
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_LIVE, "provider.huaweicloud_live", DEPLOYMENT_CATEGORIES.AV],
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_VOD, "provider.huaweicloud_vod", DEPLOYMENT_CATEGORIES.AV],
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_APIG, "provider.huaweicloud_apig", DEPLOYMENT_CATEGORIES.APIGATEWAY],
|
||||
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_SCM, "provider.huaweicloud_scm_upload", DEPLOYMENT_CATEGORIES.SSL],
|
||||
[DEPLOYMENT_PROVIDERS.VOLCENGINE_TOS, "provider.volcengine_tos", DEPLOYMENT_CATEGORIES.STORAGE],
|
||||
|
||||
@ -168,6 +168,7 @@
|
||||
"huaweicloud_live": "Huawei Cloud - Cloud Live",
|
||||
"huaweicloud_obs": "Huawei Cloud - OBS (Object Storage Service)",
|
||||
"huaweicloud_scm_upload": "Huawei Cloud - Upload to SCM (SSL Certificate Manager)",
|
||||
"huaweicloud_vod": "Huawei Cloud - VOD (Video on Demand)",
|
||||
"huaweicloud_waf": "Huawei Cloud - WAF (Web Application Firewall)",
|
||||
"infomaniak": "Infomaniak",
|
||||
"ionos": "IONOS",
|
||||
|
||||
@ -1581,15 +1581,20 @@
|
||||
"placeholder": "Please enter GoEdge certificate ID",
|
||||
"tooltip": "You can find it on GoEdge dashboard. <br><br>(Please open the browser devtools, and visit the \"网站列表 -> 证书管理 -> 证书\" page to capture network requests, then you can get the certificate ID.)"
|
||||
},
|
||||
"huaweicloud_aad_domain": {
|
||||
"label": "Huawei Cloud AAD domain",
|
||||
"placeholder": "Please enter Huawei Cloud AAD domain name"
|
||||
"huaweicloud_aad_region": {
|
||||
"label": "Huawei Cloud region",
|
||||
"placeholder": "Please enter Huawei Cloud AAD region (e.g. cn-north-4)",
|
||||
"tooltip": "For more information, see <a href=\"https://console-intl.huaweicloud.com/apiexplorer/#/endpoint?locale=en-us\" target=\"_blank\">https://console-intl.huaweicloud.com/apiexplorer/#/endpoint</a>"
|
||||
},
|
||||
"huaweicloud_aad_instance_id": {
|
||||
"label": "Huawei Cloud AAD instance ID",
|
||||
"placeholder": "Please enter Huawei Cloud AAD instance ID",
|
||||
"tooltip": "For more information, see <a href=\"https://console-intl.huaweicloud.com/cnad/#/cnad/cad/list\" target=\"_blank\">https://console-intl.huaweicloud.com/cnad/#/cnad/cad/list</a>"
|
||||
},
|
||||
"huaweicloud_aad_domain": {
|
||||
"label": "Huawei Cloud AAD domain",
|
||||
"placeholder": "Please enter Huawei Cloud AAD domain name"
|
||||
},
|
||||
"huaweicloud_apig_region": {
|
||||
"label": "Huawei Cloud region",
|
||||
"placeholder": "Please enter Huawei Cloud API gateway region (e.g. cn-north-1)",
|
||||
@ -1671,6 +1676,15 @@
|
||||
"label": "Huawei Cloud Live streaming domain",
|
||||
"placeholder": "Please enter Huawei Cloud Live streaming domain name"
|
||||
},
|
||||
"huaweicloud_vod_region": {
|
||||
"label": "Huawei Cloud region",
|
||||
"placeholder": "Please enter Huawei Cloud VOD region (e.g. cn-north-1)",
|
||||
"tooltip": "For more information, see <a href=\"https://console-intl.huaweicloud.com/apiexplorer/#/endpoint?locale=en-us\" target=\"_blank\">https://console-intl.huaweicloud.com/apiexplorer/#/endpoint</a>"
|
||||
},
|
||||
"huaweicloud_vod_domain": {
|
||||
"label": "Huawei Cloud VOD domain",
|
||||
"placeholder": "Please enter Huawei Cloud VOD domain name"
|
||||
},
|
||||
"huaweicloud_waf_region": {
|
||||
"label": "Huawei Cloud region",
|
||||
"placeholder": "Please enter Huawei Cloud WAF region (e.g. cn-north-1)",
|
||||
|
||||
@ -168,6 +168,7 @@
|
||||
"huaweicloud_live": "华为云 - 视频直播 Live",
|
||||
"huaweicloud_obs": "华为云 - 对象储存服务 OBS",
|
||||
"huaweicloud_scm_upload": "华为云 - 上传到云证书管理服务 SCM",
|
||||
"huaweicloud_vod": "华为云 - 视频点播 VOD",
|
||||
"huaweicloud_waf": "华为云 - Web 应用防火墙 WAF",
|
||||
"infomaniak": "Infomaniak",
|
||||
"ionos": "IONOS",
|
||||
|
||||
@ -1580,6 +1580,11 @@
|
||||
"placeholder": "请输入 GoEdge 证书 ID",
|
||||
"tooltip": "请登录 GoEdge 控制台查看<br><br>(目前需要在「网站列表 -> 证书管理 -> 证书」页面,并打开浏览器开发者工具抓取网络请求后得到证书 ID)"
|
||||
},
|
||||
"huaweicloud_aad_region": {
|
||||
"label": "华为云服务区域",
|
||||
"placeholder": "请输入华为云 DDoS 高防服务区域(例如:cn-north-4)",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://console.huaweicloud.com/apiexplorer/#/endpoint\" target=\"_blank\">https://console.huaweicloud.com/apiexplorer/#/endpoint</a>"
|
||||
},
|
||||
"huaweicloud_aad_instance_id": {
|
||||
"label": "华为云 DDoS 高防实例 ID",
|
||||
"placeholder": "请输入华为云 DDoS 高防实例 ID",
|
||||
@ -1670,6 +1675,15 @@
|
||||
"label": "华为云视频直播流域名",
|
||||
"placeholder": "请输入华为云视频直播流域名"
|
||||
},
|
||||
"huaweicloud_vod_region": {
|
||||
"label": "华为云服务区域",
|
||||
"placeholder": "请输入华为云视频点播服务区域(例如:cn-north-1)",
|
||||
"tooltip": "这是什么?请参阅 <a href=\"https://console.huaweicloud.com/apiexplorer/#/endpoint\" target=\"_blank\">https://console.huaweicloud.com/apiexplorer/#/endpoint</a>"
|
||||
},
|
||||
"huaweicloud_vod_domain": {
|
||||
"label": "华为云视频点播加速域名",
|
||||
"placeholder": "请输入华为云视频点播加速域名"
|
||||
},
|
||||
"huaweicloud_waf_region": {
|
||||
"label": "华为云服务区域",
|
||||
"placeholder": "请输入华为云 WAF 服务区域(例如:cn-north-1)",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user