mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-10 14:39:50 +00:00
feat: add huaweicloud waf uploader
This commit is contained in:
parent
b734ffcf9d
commit
a6f1f21c18
2
go.mod
2
go.mod
@ -24,7 +24,7 @@ require (
|
|||||||
github.com/go-acme/lego/v4 v4.21.0
|
github.com/go-acme/lego/v4 v4.21.0
|
||||||
github.com/go-resty/resty/v2 v2.16.5
|
github.com/go-resty/resty/v2 v2.16.5
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1
|
github.com/go-viper/mapstructure/v2 v2.2.1
|
||||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135
|
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136
|
||||||
github.com/nikoksr/notify v1.3.0
|
github.com/nikoksr/notify v1.3.0
|
||||||
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
|
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
|
||||||
github.com/pkg/sftp v1.13.7
|
github.com/pkg/sftp v1.13.7
|
||||||
|
2
go.sum
2
go.sum
@ -558,6 +558,8 @@ github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKEN
|
|||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135 h1:UbNMlPfh0GhRY3iVkvv4fXFJ+bLqXoVCwjqe6geFdPs=
|
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135 h1:UbNMlPfh0GhRY3iVkvv4fXFJ+bLqXoVCwjqe6geFdPs=
|
||||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
|
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
|
||||||
|
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136 h1:T785NUg5245nWpPVHLVR8lBd+zGQYR14Vi/TCX1iu3A=
|
||||||
|
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
|
||||||
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
|
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
|
||||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
|
@ -29,15 +29,15 @@ type AliyunALBDeployerConfig struct {
|
|||||||
// 阿里云地域。
|
// 阿里云地域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 负载均衡实例 ID。
|
// 负载均衡实例 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
|
||||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||||
// 负载均衡监听 ID。
|
// 负载均衡监听 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
ListenerId string `json:"listenerId,omitempty"`
|
ListenerId string `json:"listenerId,omitempty"`
|
||||||
// SNI 域名(支持泛域名)。
|
// SNI 域名(支持泛域名)。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时选填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
|
||||||
Domain string `json:"domain,omitempty"`
|
Domain string `json:"domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,12 +97,12 @@ func (d *AliyunALBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_LOADBALANCER:
|
case RESOURCE_TYPE_LOADBALANCER:
|
||||||
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER,
|
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
})
|
})
|
||||||
@ -102,7 +102,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
})
|
})
|
||||||
|
10
internal/pkg/core/deployer/providers/aliyun-alb/consts.go
Normal file
10
internal/pkg/core/deployer/providers/aliyun-alb/consts.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package aliyunalb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:部署到指定负载均衡器。
|
||||||
|
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
)
|
@ -1,10 +0,0 @@
|
|||||||
package aliyunalb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:部署到指定负载均衡器。
|
|
||||||
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
)
|
|
@ -24,15 +24,15 @@ type AliyunCLBDeployerConfig struct {
|
|||||||
// 阿里云地域。
|
// 阿里云地域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 负载均衡实例 ID。
|
// 负载均衡实例 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||||
// 负载均衡监听端口。
|
// 负载均衡监听端口。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
ListenerPort int32 `json:"listenerPort,omitempty"`
|
ListenerPort int32 `json:"listenerPort,omitempty"`
|
||||||
// SNI 域名(支持泛域名)。
|
// SNI 域名(支持泛域名)。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时选填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
|
||||||
Domain string `json:"domain,omitempty"`
|
Domain string `json:"domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,12 +91,12 @@ func (d *AliyunCLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_LOADBALANCER:
|
case RESOURCE_TYPE_LOADBALANCER:
|
||||||
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER,
|
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
})
|
})
|
||||||
@ -103,7 +103,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
ListenerPort: int32(fListenerPort),
|
ListenerPort: int32(fListenerPort),
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
|
10
internal/pkg/core/deployer/providers/aliyun-clb/consts.go
Normal file
10
internal/pkg/core/deployer/providers/aliyun-clb/consts.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package aliyunclb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:部署到指定负载均衡器。
|
||||||
|
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
)
|
@ -1,10 +0,0 @@
|
|||||||
package aliyunclb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:部署到指定负载均衡器。
|
|
||||||
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
)
|
|
@ -25,12 +25,12 @@ type AliyunNLBDeployerConfig struct {
|
|||||||
// 阿里云地域。
|
// 阿里云地域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 负载均衡实例 ID。
|
// 负载均衡实例 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
|
||||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||||
// 负载均衡监听 ID。
|
// 负载均衡监听 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
ListenerId string `json:"listenerId,omitempty"`
|
ListenerId string `json:"listenerId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +85,12 @@ func (d *AliyunNLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_LOADBALANCER:
|
case RESOURCE_TYPE_LOADBALANCER:
|
||||||
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER,
|
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -98,7 +98,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
10
internal/pkg/core/deployer/providers/aliyun-nlb/consts.go
Normal file
10
internal/pkg/core/deployer/providers/aliyun-nlb/consts.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package aliyunnlb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:部署到指定负载均衡器。
|
||||||
|
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
)
|
@ -1,10 +0,0 @@
|
|||||||
package aliyunnlb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:部署到指定负载均衡器。
|
|
||||||
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
)
|
|
@ -0,0 +1,12 @@
|
|||||||
|
package huaweicloudelb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:替换指定证书。
|
||||||
|
RESOURCE_TYPE_CERTIFICATE = ResourceType("certificate")
|
||||||
|
// 资源类型:部署到指定负载均衡器。
|
||||||
|
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
)
|
@ -1,12 +0,0 @@
|
|||||||
package huaweicloudelb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:替换指定证书。
|
|
||||||
DEPLOY_RESOURCE_CERTIFICATE = DeployResourceType("certificate")
|
|
||||||
// 资源类型:部署到指定负载均衡器。
|
|
||||||
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
)
|
|
@ -31,15 +31,15 @@ type HuaweiCloudELBDeployerConfig struct {
|
|||||||
// 华为云区域。
|
// 华为云区域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 证书 ID。
|
// 证书 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_CERTIFICATE] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_CERTIFICATE] 时必填。
|
||||||
CertificateId string `json:"certificateId,omitempty"`
|
CertificateId string `json:"certificateId,omitempty"`
|
||||||
// 负载均衡器 ID。
|
// 负载均衡器 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
|
||||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||||
// 负载均衡监听 ID。
|
// 负载均衡监听 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
ListenerId string `json:"listenerId,omitempty"`
|
ListenerId string `json:"listenerId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,17 +98,17 @@ func (d *HuaweiCloudELBDeployer) Deploy(ctx context.Context, certPem string, pri
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_CERTIFICATE:
|
case RESOURCE_TYPE_CERTIFICATE:
|
||||||
if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil {
|
if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LOADBALANCER:
|
case RESOURCE_TYPE_LOADBALANCER:
|
||||||
if err := d.deployToLoadbalancer(ctx, certPem, privkeyPem); err != nil {
|
if err := d.deployToLoadbalancer(ctx, certPem, privkeyPem); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, certPem, privkeyPem); err != nil {
|
if err := d.deployToListener(ctx, certPem, privkeyPem); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
SecretAccessKey: fSecretAccessKey,
|
SecretAccessKey: fSecretAccessKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_CERTIFICATE,
|
ResourceType: provider.RESOURCE_TYPE_CERTIFICATE,
|
||||||
CertificateId: fCertificateId,
|
CertificateId: fCertificateId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -100,7 +100,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
SecretAccessKey: fSecretAccessKey,
|
SecretAccessKey: fSecretAccessKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER,
|
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -134,7 +134,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
SecretAccessKey: fSecretAccessKey,
|
SecretAccessKey: fSecretAccessKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package tencentcloudclb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:通过 SSL 服务部署到云资源实例。
|
||||||
|
RESOURCE_TYPE_VIA_SSLDEPLOY = ResourceType("ssl-deploy")
|
||||||
|
// 资源类型:部署到指定负载均衡器。
|
||||||
|
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
// 资源类型:部署到指定转发规则域名。
|
||||||
|
RESOURCE_TYPE_RULEDOMAIN = ResourceType("ruledomain")
|
||||||
|
)
|
@ -1,14 +0,0 @@
|
|||||||
package tencentcloudclb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:通过 SSL 服务部署到云资源实例。
|
|
||||||
DEPLOY_RESOURCE_VIA_SSLDEPLOY = DeployResourceType("ssl-deploy")
|
|
||||||
// 资源类型:部署到指定负载均衡器。
|
|
||||||
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
// 资源类型:部署到指定转发规则域名。
|
|
||||||
DEPLOY_RESOURCE_RULEDOMAIN = DeployResourceType("ruledomain")
|
|
||||||
)
|
|
@ -25,15 +25,15 @@ type TencentCloudCLBDeployerConfig struct {
|
|||||||
// 腾讯云地域。
|
// 腾讯云地域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 负载均衡器 ID。
|
// 负载均衡器 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_SSLDEPLOY]、[DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_RULEDOMAIN] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_SSLDEPLOY]、[RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_RULEDOMAIN] 时必填。
|
||||||
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
LoadbalancerId string `json:"loadbalancerId,omitempty"`
|
||||||
// 负载均衡监听 ID。
|
// 负载均衡监听 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_SSLDEPLOY]、[DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER]、[DEPLOY_RESOURCE_RULEDOMAIN] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_SSLDEPLOY]、[RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER]、[RESOURCE_TYPE_RULEDOMAIN] 时必填。
|
||||||
ListenerId string `json:"listenerId,omitempty"`
|
ListenerId string `json:"listenerId,omitempty"`
|
||||||
// SNI 域名或七层转发规则域名(支持泛域名)。
|
// SNI 域名或七层转发规则域名(支持泛域名)。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_SSLDEPLOY] 时选填;部署资源类型为 [DEPLOY_RESOURCE_RULEDOMAIN] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_SSLDEPLOY] 时选填;部署资源类型为 [RESOURCE_TYPE_RULEDOMAIN] 时必填。
|
||||||
Domain string `json:"domain,omitempty"`
|
Domain string `json:"domain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,22 +96,22 @@ func (d *TencentCloudCLBDeployer) Deploy(ctx context.Context, certPem string, pr
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_VIA_SSLDEPLOY:
|
case RESOURCE_TYPE_VIA_SSLDEPLOY:
|
||||||
if err := d.deployViaSslService(ctx, upres.CertId); err != nil {
|
if err := d.deployViaSslService(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LOADBALANCER:
|
case RESOURCE_TYPE_LOADBALANCER:
|
||||||
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
case DEPLOY_RESOURCE_RULEDOMAIN:
|
case RESOURCE_TYPE_RULEDOMAIN:
|
||||||
if err := d.deployToRuleDomain(ctx, upres.CertId); err != nil {
|
if err := d.deployToRuleDomain(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
SecretId: fSecretId,
|
SecretId: fSecretId,
|
||||||
SecretKey: fSecretKey,
|
SecretKey: fSecretKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_VIA_SSLDEPLOY,
|
ResourceType: provider.RESOURCE_TYPE_VIA_SSLDEPLOY,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
@ -104,7 +104,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
SecretId: fSecretId,
|
SecretId: fSecretId,
|
||||||
SecretKey: fSecretKey,
|
SecretKey: fSecretKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER,
|
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -139,7 +139,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
SecretId: fSecretId,
|
SecretId: fSecretId,
|
||||||
SecretKey: fSecretKey,
|
SecretKey: fSecretKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
})
|
})
|
||||||
@ -176,7 +176,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
SecretId: fSecretId,
|
SecretId: fSecretId,
|
||||||
SecretKey: fSecretKey,
|
SecretKey: fSecretKey,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_RULEDOMAIN,
|
ResourceType: provider.RESOURCE_TYPE_RULEDOMAIN,
|
||||||
LoadbalancerId: fLoadbalancerId,
|
LoadbalancerId: fLoadbalancerId,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
Domain: fDomain,
|
Domain: fDomain,
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package volcengineclb
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 资源类型:部署到指定监听器。
|
||||||
|
RESOURCE_TYPE_LISTENER = ResourceType("listener")
|
||||||
|
)
|
@ -1,8 +0,0 @@
|
|||||||
package volcengineclb
|
|
||||||
|
|
||||||
type DeployResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// 资源类型:部署到指定监听器。
|
|
||||||
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
|
|
||||||
)
|
|
@ -24,9 +24,9 @@ type VolcEngineCLBDeployerConfig struct {
|
|||||||
// 火山引擎地域。
|
// 火山引擎地域。
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
// 部署资源类型。
|
// 部署资源类型。
|
||||||
ResourceType DeployResourceType `json:"resourceType"`
|
ResourceType ResourceType `json:"resourceType"`
|
||||||
// 负载均衡监听器 ID。
|
// 负载均衡监听器 ID。
|
||||||
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。
|
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
|
||||||
ListenerId string `json:"listenerId,omitempty"`
|
ListenerId string `json:"listenerId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ func (d *VolcEngineCLBDeployer) Deploy(ctx context.Context, certPem string, priv
|
|||||||
|
|
||||||
// 根据部署资源类型决定部署方式
|
// 根据部署资源类型决定部署方式
|
||||||
switch d.config.ResourceType {
|
switch d.config.ResourceType {
|
||||||
case DEPLOY_RESOURCE_LISTENER:
|
case RESOURCE_TYPE_LISTENER:
|
||||||
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
if err := d.deployToListener(ctx, upres.CertId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func TestDeploy(t *testing.T) {
|
|||||||
AccessKeyId: fAccessKeyId,
|
AccessKeyId: fAccessKeyId,
|
||||||
AccessKeySecret: fAccessKeySecret,
|
AccessKeySecret: fAccessKeySecret,
|
||||||
Region: fRegion,
|
Region: fRegion,
|
||||||
ResourceType: provider.DEPLOY_RESOURCE_LISTENER,
|
ResourceType: provider.RESOURCE_TYPE_LISTENER,
|
||||||
ListenerId: fListenerId,
|
ListenerId: fListenerId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -112,7 +112,7 @@ func (u *AliyunCASUploader) Upload(ctx context.Context, certPem string, privkeyP
|
|||||||
if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) {
|
if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
listUserCertificateOrderPage += 1
|
listUserCertificateOrderPage++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,167 @@
|
|||||||
|
package huaweicloudwaf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
|
||||||
|
hcWaf "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1"
|
||||||
|
hcWafModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/model"
|
||||||
|
hcWafRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/region"
|
||||||
|
xerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/utils/certs"
|
||||||
|
hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HuaweiCloudWAFUploaderConfig struct {
|
||||||
|
// 华为云 AccessKeyId。
|
||||||
|
AccessKeyId string `json:"accessKeyId"`
|
||||||
|
// 华为云 SecretAccessKey。
|
||||||
|
SecretAccessKey string `json:"secretAccessKey"`
|
||||||
|
// 华为云区域。
|
||||||
|
Region string `json:"region"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HuaweiCloudWAFUploader struct {
|
||||||
|
config *HuaweiCloudWAFUploaderConfig
|
||||||
|
sdkClient *hcWaf.WafClient
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ uploader.Uploader = (*HuaweiCloudWAFUploader)(nil)
|
||||||
|
|
||||||
|
func New(config *HuaweiCloudWAFUploaderConfig) (*HuaweiCloudWAFUploader, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.New("config is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := createSdkClient(
|
||||||
|
config.AccessKeyId,
|
||||||
|
config.SecretAccessKey,
|
||||||
|
config.Region,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Wrap(err, "failed to create sdk client")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HuaweiCloudWAFUploader{
|
||||||
|
config: config,
|
||||||
|
sdkClient: client,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *HuaweiCloudWAFUploader) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
|
||||||
|
// 解析证书内容
|
||||||
|
certX509, err := certs.ParseCertificateFromPEM(certPem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历查询已有证书,避免重复上传
|
||||||
|
// REF: https://support.huaweicloud.com/api-waf/ListCertificates.html
|
||||||
|
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
|
||||||
|
listCertificatesPage := int32(1)
|
||||||
|
listCertificatesLimit := int32(100)
|
||||||
|
for {
|
||||||
|
listCertificatesReq := &hcWafModel.ListCertificatesRequest{
|
||||||
|
Page: hwsdk.Int32Ptr(listCertificatesPage),
|
||||||
|
Pagesize: hwsdk.Int32Ptr(listCertificatesLimit),
|
||||||
|
}
|
||||||
|
listCertificatesResp, err := u.sdkClient.ListCertificates(listCertificatesReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ListCertificates'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if listCertificatesResp.Items != nil {
|
||||||
|
for _, certItem := range *listCertificatesResp.Items {
|
||||||
|
showCertificateReq := &hcWafModel.ShowCertificateRequest{
|
||||||
|
CertificateId: certItem.Id,
|
||||||
|
}
|
||||||
|
showCertificateResp, err := u.sdkClient.ShowCertificate(showCertificateReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ShowCertificate'")
|
||||||
|
}
|
||||||
|
|
||||||
|
var isSameCert bool
|
||||||
|
if *showCertificateResp.Content == certPem {
|
||||||
|
isSameCert = true
|
||||||
|
} else {
|
||||||
|
oldCertX509, err := certs.ParseCertificateFromPEM(*showCertificateResp.Content)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
isSameCert = certs.EqualCertificate(certX509, oldCertX509)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已存在相同证书,直接返回已有的证书信息
|
||||||
|
if isSameCert {
|
||||||
|
return &uploader.UploadResult{
|
||||||
|
CertId: certItem.Id,
|
||||||
|
CertName: certItem.Name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if listCertificatesResp.Items == nil || len(*listCertificatesResp.Items) < int(listCertificatesLimit) {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
listCertificatesPage++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成新证书名(需符合华为云命名规则)
|
||||||
|
var certId, certName string
|
||||||
|
certName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
|
||||||
|
|
||||||
|
// 创建证书
|
||||||
|
// REF: https://support.huaweicloud.com/api-waf/CreateCertificate.html
|
||||||
|
createCertificateReq := &hcWafModel.CreateCertificateRequest{
|
||||||
|
Body: &hcWafModel.CreateCertificateRequestBody{
|
||||||
|
Name: certName,
|
||||||
|
Content: certPem,
|
||||||
|
Key: privkeyPem,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
createCertificateResp, err := u.sdkClient.CreateCertificate(createCertificateReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.CreateCertificate'")
|
||||||
|
}
|
||||||
|
|
||||||
|
certId = *createCertificateResp.Id
|
||||||
|
certName = *createCertificateResp.Name
|
||||||
|
return &uploader.UploadResult{
|
||||||
|
CertId: certId,
|
||||||
|
CertName: certName,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcWaf.WafClient, error) {
|
||||||
|
auth, err := basic.NewCredentialsBuilder().
|
||||||
|
WithAk(accessKeyId).
|
||||||
|
WithSk(secretAccessKey).
|
||||||
|
SafeBuild()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hcRegion, err := hcWafRegion.SafeValueOf(region)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hcClient, err := hcWaf.WafClientBuilder().
|
||||||
|
WithRegion(hcRegion).
|
||||||
|
WithCredential(auth).
|
||||||
|
SafeBuild()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := hcWaf.NewWafClient(hcClient)
|
||||||
|
return client, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user