feat: support configuring huaweicloud enterprise project id

This commit is contained in:
Fu Diwei 2025-05-27 17:28:06 +08:00
parent a4f736e0f3
commit b8b94dfd77
14 changed files with 137 additions and 59 deletions

View File

@ -676,40 +676,44 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider { switch options.Provider {
case domain.DeploymentProviderTypeHuaweiCloudCDN: case domain.DeploymentProviderTypeHuaweiCloudCDN:
deployer, err := pHuaweiCloudCDN.NewDeployer(&pHuaweiCloudCDN.DeployerConfig{ deployer, err := pHuaweiCloudCDN.NewDeployer(&pHuaweiCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"), EnterpriseProjectId: access.EnterpriseProjectId,
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"), Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
}) })
return deployer, err return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudELB: case domain.DeploymentProviderTypeHuaweiCloudELB:
deployer, err := pHuaweiCloudELB.NewDeployer(&pHuaweiCloudELB.DeployerConfig{ deployer, err := pHuaweiCloudELB.NewDeployer(&pHuaweiCloudELB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"), EnterpriseProjectId: access.EnterpriseProjectId,
ResourceType: pHuaweiCloudELB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")), Region: maputil.GetString(options.ProviderServiceConfig, "region"),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"), ResourceType: pHuaweiCloudELB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"), CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"), LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"),
}) })
return deployer, err return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudSCM: case domain.DeploymentProviderTypeHuaweiCloudSCM:
deployer, err := pHuaweiCloudSCM.NewDeployer(&pHuaweiCloudSCM.DeployerConfig{ deployer, err := pHuaweiCloudSCM.NewDeployer(&pHuaweiCloudSCM.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
EnterpriseProjectId: access.EnterpriseProjectId,
}) })
return deployer, err return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudWAF: case domain.DeploymentProviderTypeHuaweiCloudWAF:
deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{ deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"), EnterpriseProjectId: access.EnterpriseProjectId,
ResourceType: pHuaweiCloudWAF.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")), Region: maputil.GetString(options.ProviderServiceConfig, "region"),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"), ResourceType: pHuaweiCloudWAF.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"), CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
}) })
return deployer, err return deployer, err

View File

@ -199,8 +199,9 @@ type AccessConfigForHetzner struct {
} }
type AccessConfigForHuaweiCloud struct { type AccessConfigForHuaweiCloud struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
} }
type AccessConfigForJDCloud struct { type AccessConfigForJDCloud struct {

View File

@ -21,6 +21,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
// 加速域名(不支持泛域名)。 // 加速域名(不支持泛域名)。
@ -51,8 +53,9 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
} }
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err) return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@ -88,7 +91,8 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
// 查询加速域名配置 // 查询加速域名配置
// REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html // REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html
showDomainFullConfigReq := &hccdnmodel.ShowDomainFullConfigRequest{ showDomainFullConfigReq := &hccdnmodel.ShowDomainFullConfigRequest{
DomainName: d.config.Domain, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
DomainName: d.config.Domain,
} }
showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq) showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq)
d.logger.Debug("sdk request 'cdn.ShowDomainFullConfig'", slog.Any("request", showDomainFullConfigReq), slog.Any("response", showDomainFullConfigResp)) d.logger.Debug("sdk request 'cdn.ShowDomainFullConfig'", slog.Any("request", showDomainFullConfigReq), slog.Any("response", showDomainFullConfigResp))
@ -107,6 +111,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
updateDomainMultiCertificatesReqBodyContent.CertName = typeutil.ToPtr(upres.CertName) updateDomainMultiCertificatesReqBodyContent.CertName = typeutil.ToPtr(upres.CertName)
updateDomainMultiCertificatesReqBodyContent = assign(updateDomainMultiCertificatesReqBodyContent, showDomainFullConfigResp.Configs) updateDomainMultiCertificatesReqBodyContent = assign(updateDomainMultiCertificatesReqBodyContent, showDomainFullConfigResp.Configs)
updateDomainMultiCertificatesReq := &hccdnmodel.UpdateDomainMultiCertificatesRequest{ updateDomainMultiCertificatesReq := &hccdnmodel.UpdateDomainMultiCertificatesRequest{
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Body: &hccdnmodel.UpdateDomainMultiCertificatesRequestBody{ Body: &hccdnmodel.UpdateDomainMultiCertificatesRequestBody{
Https: updateDomainMultiCertificatesReqBodyContent, Https: updateDomainMultiCertificatesReqBodyContent,
}, },

View File

@ -27,6 +27,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
@ -62,9 +64,10 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
} }
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
Region: config.Region, EnterpriseProjectId: config.EnterpriseProjectId,
Region: config.Region,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err) return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@ -172,6 +175,9 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, certPEM str
Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"}, Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"},
LoadbalancerId: &[]string{showLoadBalancerResp.Loadbalancer.Id}, LoadbalancerId: &[]string{showLoadBalancerResp.Loadbalancer.Id},
} }
if d.config.EnterpriseProjectId != "" {
listListenersReq.EnterpriseProjectId = typeutil.ToPtr([]string{d.config.EnterpriseProjectId})
}
listListenersResp, err := d.sdkClient.ListListeners(listListenersReq) listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
d.logger.Debug("sdk request 'elb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp)) d.logger.Debug("sdk request 'elb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp))
if err != nil { if err != nil {

View File

@ -15,6 +15,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
} }
type DeployerProvider struct { type DeployerProvider struct {
@ -31,8 +33,9 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
} }
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err) return nil, fmt.Errorf("failed to create ssl uploader: %w", err)

View File

@ -27,6 +27,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
@ -59,9 +61,10 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
} }
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
Region: config.Region, EnterpriseProjectId: config.EnterpriseProjectId,
Region: config.Region,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err) return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@ -126,7 +129,8 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
// 查询证书 // 查询证书
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html // REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
showCertificateReq := &hcwafmodel.ShowCertificateRequest{ showCertificateReq := &hcwafmodel.ShowCertificateRequest{
CertificateId: d.config.CertificateId, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
CertificateId: d.config.CertificateId,
} }
showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq) showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq)
d.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp)) d.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp))
@ -137,7 +141,8 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
// 更新证书 // 更新证书
// REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html // REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html
updateCertificateReq := &hcwafmodel.UpdateCertificateRequest{ updateCertificateReq := &hcwafmodel.UpdateCertificateRequest{
CertificateId: d.config.CertificateId, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
CertificateId: d.config.CertificateId,
Body: &hcwafmodel.UpdateCertificateRequestBody{ Body: &hcwafmodel.UpdateCertificateRequestBody{
Name: *showCertificateResp.Name, Name: *showCertificateResp.Name,
Content: typeutil.ToPtr(certPEM), Content: typeutil.ToPtr(certPEM),
@ -179,9 +184,10 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPEM stri
} }
listHostReq := &hcwafmodel.ListHostRequest{ listHostReq := &hcwafmodel.ListHostRequest{
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")), EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Page: typeutil.ToPtr(listHostPage), Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Pagesize: typeutil.ToPtr(listHostPageSize), Page: typeutil.ToPtr(listHostPage),
Pagesize: typeutil.ToPtr(listHostPageSize),
} }
listHostResp, err := d.sdkClient.ListHost(listHostReq) listHostResp, err := d.sdkClient.ListHost(listHostReq)
d.logger.Debug("sdk request 'waf.ListHost'", slog.Any("request", listHostReq), slog.Any("response", listHostResp)) d.logger.Debug("sdk request 'waf.ListHost'", slog.Any("request", listHostReq), slog.Any("response", listHostResp))
@ -211,7 +217,8 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPEM stri
// 更新云模式防护域名的配置 // 更新云模式防护域名的配置
// REF: https://support.huaweicloud.com/api-waf/UpdateHost.html // REF: https://support.huaweicloud.com/api-waf/UpdateHost.html
updateHostReq := &hcwafmodel.UpdateHostRequest{ updateHostReq := &hcwafmodel.UpdateHostRequest{
InstanceId: hostId, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
InstanceId: hostId,
Body: &hcwafmodel.UpdateHostRequestBody{ Body: &hcwafmodel.UpdateHostRequestBody{
Certificateid: typeutil.ToPtr(upres.CertId), Certificateid: typeutil.ToPtr(upres.CertId),
Certificatename: typeutil.ToPtr(upres.CertName), Certificatename: typeutil.ToPtr(upres.CertName),
@ -252,9 +259,10 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPEM stri
} }
listPremiumHostReq := &hcwafmodel.ListPremiumHostRequest{ listPremiumHostReq := &hcwafmodel.ListPremiumHostRequest{
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")), EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Page: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPage)), Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Pagesize: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPageSize)), Page: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPage)),
Pagesize: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPageSize)),
} }
listPremiumHostResp, err := d.sdkClient.ListPremiumHost(listPremiumHostReq) listPremiumHostResp, err := d.sdkClient.ListPremiumHost(listPremiumHostReq)
d.logger.Debug("sdk request 'waf.ListPremiumHost'", slog.Any("request", listPremiumHostReq), slog.Any("response", listPremiumHostResp)) d.logger.Debug("sdk request 'waf.ListPremiumHost'", slog.Any("request", listPremiumHostReq), slog.Any("response", listPremiumHostResp))
@ -284,7 +292,8 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPEM stri
// 修改独享模式域名配置 // 修改独享模式域名配置
// REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html // REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html
updatePremiumHostReq := &hcwafmodel.UpdatePremiumHostRequest{ updatePremiumHostReq := &hcwafmodel.UpdatePremiumHostRequest{
HostId: hostId, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
HostId: hostId,
Body: &hcwafmodel.UpdatePremiumHostRequestBody{ Body: &hcwafmodel.UpdatePremiumHostRequestBody{
Certificateid: typeutil.ToPtr(upres.CertId), Certificateid: typeutil.ToPtr(upres.CertId),
Certificatename: typeutil.ToPtr(upres.CertName), Certificatename: typeutil.ToPtr(upres.CertName),

View File

@ -26,6 +26,8 @@ type UploaderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
} }
@ -141,10 +143,11 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
createCertificateReq := &hcelbmodel.CreateCertificateRequest{ createCertificateReq := &hcelbmodel.CreateCertificateRequest{
Body: &hcelbmodel.CreateCertificateRequestBody{ Body: &hcelbmodel.CreateCertificateRequestBody{
Certificate: &hcelbmodel.CreateCertificateOption{ Certificate: &hcelbmodel.CreateCertificateOption{
ProjectId: typeutil.ToPtr(projectId), EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
Name: typeutil.ToPtr(certName), ProjectId: typeutil.ToPtr(projectId),
Certificate: typeutil.ToPtr(certPEM), Name: typeutil.ToPtr(certName),
PrivateKey: typeutil.ToPtr(privkeyPEM), Certificate: typeutil.ToPtr(certPEM),
PrivateKey: typeutil.ToPtr(privkeyPEM),
}, },
}, },
} }

View File

@ -21,6 +21,8 @@ type UploaderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
} }
@ -79,10 +81,11 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
} }
listCertificatesReq := &hcscmmodel.ListCertificatesRequest{ listCertificatesReq := &hcscmmodel.ListCertificatesRequest{
Limit: typeutil.ToPtr(listCertificatesLimit), EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
Offset: typeutil.ToPtr(listCertificatesOffset), Limit: typeutil.ToPtr(listCertificatesLimit),
SortDir: typeutil.ToPtr("DESC"), Offset: typeutil.ToPtr(listCertificatesOffset),
SortKey: typeutil.ToPtr("certExpiredTime"), SortDir: typeutil.ToPtr("DESC"),
SortKey: typeutil.ToPtr("certExpiredTime"),
} }
listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq) listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq)
u.logger.Debug("sdk request 'scm.ListCertificates'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp)) u.logger.Debug("sdk request 'scm.ListCertificates'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
@ -142,9 +145,10 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
// REF: https://support.huaweicloud.com/api-ccm/ImportCertificate.html // REF: https://support.huaweicloud.com/api-ccm/ImportCertificate.html
importCertificateReq := &hcscmmodel.ImportCertificateRequest{ importCertificateReq := &hcscmmodel.ImportCertificateRequest{
Body: &hcscmmodel.ImportCertificateRequestBody{ Body: &hcscmmodel.ImportCertificateRequestBody{
Name: certName, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
Certificate: certPEM, Name: certName,
PrivateKey: privkeyPEM, Certificate: certPEM,
PrivateKey: privkeyPEM,
}, },
} }
importCertificateResp, err := u.sdkClient.ImportCertificate(importCertificateReq) importCertificateResp, err := u.sdkClient.ImportCertificate(importCertificateReq)

View File

@ -26,6 +26,8 @@ type UploaderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
} }
@ -84,8 +86,9 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
} }
listCertificatesReq := &hcwafmodel.ListCertificatesRequest{ listCertificatesReq := &hcwafmodel.ListCertificatesRequest{
Page: typeutil.ToPtr(listCertificatesPage), EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
Pagesize: typeutil.ToPtr(listCertificatesPageSize), Page: typeutil.ToPtr(listCertificatesPage),
Pagesize: typeutil.ToPtr(listCertificatesPageSize),
} }
listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq) listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq)
u.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp)) u.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
@ -96,7 +99,8 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
if listCertificatesResp.Items != nil { if listCertificatesResp.Items != nil {
for _, certItem := range *listCertificatesResp.Items { for _, certItem := range *listCertificatesResp.Items {
showCertificateReq := &hcwafmodel.ShowCertificateRequest{ showCertificateReq := &hcwafmodel.ShowCertificateRequest{
CertificateId: certItem.Id, EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
CertificateId: certItem.Id,
} }
showCertificateResp, err := u.sdkClient.ShowCertificate(showCertificateReq) showCertificateResp, err := u.sdkClient.ShowCertificate(showCertificateReq)
u.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp)) u.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp))
@ -141,6 +145,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
// 创建证书 // 创建证书
// REF: https://support.huaweicloud.com/api-waf/CreateCertificate.html // REF: https://support.huaweicloud.com/api-waf/CreateCertificate.html
createCertificateReq := &hcwafmodel.CreateCertificateRequest{ createCertificateReq := &hcwafmodel.CreateCertificateRequest{
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(u.config.EnterpriseProjectId),
Body: &hcwafmodel.CreateCertificateRequestBody{ Body: &hcwafmodel.CreateCertificateRequestBody{
Name: certName, Name: certName,
Content: certPEM, Content: certPEM,

View File

@ -1,5 +1,7 @@
package typeutil package typeutil
import "reflect"
// 将对象转换为指针。 // 将对象转换为指针。
// //
// 入参: // 入参:
@ -11,6 +13,21 @@ func ToPtr[T any](v T) (p *T) {
return &v return &v
} }
// 将非零值的对象转换为指针。
// 与 [ToPtr] 不同的是,如果对象的值为零值,则返回 nil。
//
// 入参:
// - 待转换的对象。
//
// 出参:
// - 返回对象的指针。
func ToPtrOrZeroNil[T any](v T) (p *T) {
if !reflect.ValueOf(v).IsZero() {
return &v
}
return nil
}
// 将指针转换为对象。 // 将指针转换为对象。
// //
// 入参: // 入参:

View File

@ -28,14 +28,19 @@ const AccessFormHuaweiCloudConfig = ({ form: formInst, formName, disabled, initi
const formSchema = z.object({ const formSchema = z.object({
accessKeyId: z accessKeyId: z
.string() .string()
.trim()
.min(1, t("access.form.huaweicloud_access_key_id.placeholder")) .min(1, t("access.form.huaweicloud_access_key_id.placeholder"))
.max(64, t("common.errmsg.string_max", { max: 64 })) .max(64, t("common.errmsg.string_max", { max: 64 })),
.trim(),
secretAccessKey: z secretAccessKey: z
.string() .string()
.trim()
.min(1, t("access.form.huaweicloud_secret_access_key.placeholder")) .min(1, t("access.form.huaweicloud_secret_access_key.placeholder"))
.max(64, t("common.errmsg.string_max", { max: 64 })),
enterpriseProjectId: z
.string()
.trim()
.max(64, t("common.errmsg.string_max", { max: 64 })) .max(64, t("common.errmsg.string_max", { max: 64 }))
.trim(), .nullish(),
}); });
const formRule = createSchemaFieldRule(formSchema); const formRule = createSchemaFieldRule(formSchema);
@ -69,6 +74,15 @@ const AccessFormHuaweiCloudConfig = ({ form: formInst, formName, disabled, initi
> >
<Input.Password autoComplete="new-password" placeholder={t("access.form.huaweicloud_secret_access_key.placeholder")} /> <Input.Password autoComplete="new-password" placeholder={t("access.form.huaweicloud_secret_access_key.placeholder")} />
</Form.Item> </Form.Item>
<Form.Item
name="enterpriseProjectId"
label={t("access.form.huaweicloud_enterprise_project_id.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.huaweicloud_enterprise_project_id.tooltip") }}></span>}
>
<Input allowClear autoComplete="new-password" placeholder={t("access.form.huaweicloud_enterprise_project_id.placeholder")} />
</Form.Item>
</Form> </Form>
); );
}; };

View File

@ -264,6 +264,7 @@ export type AccessConfigForHetzner = {
export type AccessConfigForHuaweiCloud = { export type AccessConfigForHuaweiCloud = {
accessKeyId: string; accessKeyId: string;
secretAccessKey: string; secretAccessKey: string;
enterpriseProjectId?: string;
}; };
export type AccessConfigForJDCloud = { export type AccessConfigForJDCloud = {

View File

@ -252,6 +252,9 @@
"access.form.huaweicloud_secret_access_key.label": "Huawei Cloud SecretAccessKey", "access.form.huaweicloud_secret_access_key.label": "Huawei Cloud SecretAccessKey",
"access.form.huaweicloud_secret_access_key.placeholder": "Please enter Huawei Cloud SecretAccessKey", "access.form.huaweicloud_secret_access_key.placeholder": "Please enter Huawei Cloud SecretAccessKey",
"access.form.huaweicloud_secret_access_key.tooltip": "For more information, see <a href=\"https://support.huaweicloud.com/intl/en-us/usermanual-ca/ca_01_0003.html\" target=\"_blank\">https://support.huaweicloud.com/intl/en-us/usermanual-ca/ca_01_0003.html</a>", "access.form.huaweicloud_secret_access_key.tooltip": "For more information, see <a href=\"https://support.huaweicloud.com/intl/en-us/usermanual-ca/ca_01_0003.html\" target=\"_blank\">https://support.huaweicloud.com/intl/en-us/usermanual-ca/ca_01_0003.html</a>",
"access.form.huaweicloud_enterprise_project_id.label": "Huawei Cloud enterprise project ID (Optional)",
"access.form.huaweicloud_enterprise_project_id.placeholder": "Please enter Huawei Cloud enterprise project ID",
"access.form.huaweicloud_enterprise_project_id.tooltip": "For more information, see <a href=\"https://support.huaweicloud.com/intl/en-us/usermanual-em/em_03_0000.html\" target=\"_blank\">https://support.huaweicloud.com/intl/en-us/usermanual-em/em_03_0000.html</a>",
"access.form.jdcloud_access_key_id.label": "JD Cloud AccessKeyId", "access.form.jdcloud_access_key_id.label": "JD Cloud AccessKeyId",
"access.form.jdcloud_access_key_id.placeholder": "Please enter JD Cloud AccessKeyId", "access.form.jdcloud_access_key_id.placeholder": "Please enter JD Cloud AccessKeyId",
"access.form.jdcloud_access_key_id.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/en/account-management/accesskey-management</a>", "access.form.jdcloud_access_key_id.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/en/account-management/accesskey-management</a>",

View File

@ -252,6 +252,9 @@
"access.form.huaweicloud_secret_access_key.label": "华为云 SecretAccessKey", "access.form.huaweicloud_secret_access_key.label": "华为云 SecretAccessKey",
"access.form.huaweicloud_secret_access_key.placeholder": "请输入华为云 SecretAccessKey", "access.form.huaweicloud_secret_access_key.placeholder": "请输入华为云 SecretAccessKey",
"access.form.huaweicloud_secret_access_key.tooltip": "这是什么?请参阅 <a href=\"https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html\" target=\"_blank\">https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html</a>", "access.form.huaweicloud_secret_access_key.tooltip": "这是什么?请参阅 <a href=\"https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html\" target=\"_blank\">https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html</a>",
"access.form.huaweicloud_enterprise_project_id.label": "华为云企业项目 ID可选",
"access.form.huaweicloud_enterprise_project_id.placeholder": "请输入华为云企业项目 ID",
"access.form.huaweicloud_enterprise_project_id.tooltip": "这是什么?请参阅 <a href=\"https://support.huaweicloud.com/usermanual-em/zh-cn_topic_0126101490.html\" target=\"_blank\">https://support.huaweicloud.com/usermanual-em/zh-cn_topic_0126101490.html</a>",
"access.form.jdcloud_access_key_id.label": "京东云 AccessKeyId", "access.form.jdcloud_access_key_id.label": "京东云 AccessKeyId",
"access.form.jdcloud_access_key_id.placeholder": "请输入京东云 AccessKeyId", "access.form.jdcloud_access_key_id.placeholder": "请输入京东云 AccessKeyId",
"access.form.jdcloud_access_key_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/cn/account-management/accesskey-management</a>", "access.form.jdcloud_access_key_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/cn/account-management/accesskey-management</a>",