diff --git a/README.md b/README.md index ecd74b8..251d12c 100644 --- a/README.md +++ b/README.md @@ -284,3 +284,4 @@ SNIC服务网卡 | SNIC | github.com/baidubce/bce-sdk-go/services/endpoint VPN网关 | VPN | github.com/baidubce/bce-sdk-go/services/vpn | [VPN.md](./doc/VPN.md) 多模态媒资检索 | MMS | github.com/baidubce/bce-sdk-go/services/mms | [MMS.md](./doc/MMS.md) 数据库专属集群 | DDC | github.com/baidubce/bce-sdk-go/services/ddc | [DDC.md](./doc/DDC.md) +资源管理 | RES_MANAGER | github.com/baidubce/bce-sdk-go/services/resmanager | [RES_MANAGER.md](./doc/RES_MANAGER.md) diff --git a/bce/config.go b/bce/config.go index d1c53a6..3081145 100644 --- a/bce/config.go +++ b/bce/config.go @@ -26,7 +26,7 @@ import ( // Constants and default values for the package bce const ( - SDK_VERSION = "0.9.176" + SDK_VERSION = "0.9.177" URI_PREFIX = "/" // now support uri without prefix "v1" so just set root path DEFAULT_DOMAIN = "baidubce.com" DEFAULT_PROTOCOL = "http" diff --git a/doc/BCC.md b/doc/BCC.md index 767331e..6514d4a 100644 --- a/doc/BCC.md +++ b/doc/BCC.md @@ -3540,7 +3540,90 @@ if res, err := bccClient.GetStockWithSpec(args); err != nil { fmt.Println("GetStockWithSpec failed: ", err) } else { fmt.Println("GetStockWithSpec success: ", res) +``` +### 对预留实例券发起转移 +对预留实例券发起转移(仅支持0预付的预留实例券) +```go +args := &api.TransferReservedInstanceRequest{ +ReservedInstanceIds: []string{ +// 预留实例券id +"r-3p89YnJf", +}, +RecipientAccountId: "", +} +result, err := BCC_CLIENT.TransferReservedInstanceOrder(args) +ExpectEqual(t.Errorf, err, nil) +fmt.Println(result) +``` + +### 撤销预留实例券转移 +撤销预留实例券转移 +```go +args := &api.TransferReservedInstanceOperateRequest{ +TransferRecordIds: []string{ +// 预留实例券转移记录id +"t-tgQYk4Rx", +}, +} +err := BCC_CLIENT.RevokeTransferReservedInstanceOrder(args) +ExpectEqual(t.Errorf, err, nil) +``` + +### 拒绝预留实例券转移 +拒绝预留实例券转移 +```go +args := &api.TransferReservedInstanceOperateRequest{ +TransferRecordIds: []string{ +// 预留实例券转移记录id +"t-tgQYk4Rx", +}, +} +err := BCC_CLIENT.RefuseTransferReservedInstanceOrder(args) +ExpectEqual(t.Errorf, err, nil) +``` +### 接受预留实例券转移 +接受预留实例券转移 +```go +args := &api.AcceptTransferReservedInstanceRequest{ +// 预留实例券转移记录id +TransferRecordId: "t-uNwDdZO9", +} +err := BCC_CLIENT.AcceptTransferReservedInstanceOrder(args) +ExpectEqual(t.Errorf, err, nil) +``` +### 预留实例券转入列表 +预留实例券转入列表 +```go +args := &api.DescribeTransferReservedInstancesRequest{ +ReservedInstanceIds: []string{ +"r-I8rLAfcM", +}, +TransferRecordIds: []string{ +"t-FoM4l1xI", +}, +Spec: "bcc.g3.c1m1", +Status: "timeout", } +result, err := BCC_CLIENT.TransferInReservedInstanceOrders(args) +ExpectEqual(t.Errorf, err, nil) +fmt.Println(result) +``` +### 预留实例券转出列表 +预留实例券转出列表 +```go +args := &api.DescribeTransferReservedInstancesRequest{ +ReservedInstanceIds: []string{ +"r-ObFTPNIp", +}, +TransferRecordIds: []string{ +"t-PKnSYeWh", +}, +Spec: "bcc.ic4.c2m2", +Status: "fail", +} +result, err := BCC_CLIENT.TransferOutReservedInstanceOrders(args) +ExpectEqual(t.Errorf, err, nil) +fmt.Println(result) ``` ### 查询实例套餐库存 diff --git a/doc/RES_MANAGER.md b/doc/RES_MANAGER.md new file mode 100644 index 0000000..128ece6 --- /dev/null +++ b/doc/RES_MANAGER.md @@ -0,0 +1,412 @@ +# 资源管理服务 + +# 概述 + +本文档主要介绍资源管理 GO SDK的使用。在使用本文档前,您需要先了解资源管理的一些基本知识。若您还不了解资源管理,可以参考[产品描述](https://cloud.baidu.com/doc/ResManagement/s/eklm4lri0)和[操作指南](https://cloud.baidu.com/doc/ResManagement/s/eklq4p17g)。 + +# 初始化 + +## 确认Endpoint + +在确认您使用SDK时配置的Endpoint时,资源管理服务不分区域,使用全局域名,可先阅读开发人员指南中关于[API参考-域名](https://cloud.baidu.com/doc/ResManagement/s/Llth1oso4)的部分。 + +## 获取密钥 + +要使用百度云资源管理,您需要拥有一个有效的AK(Access Key ID)和SK(Secret Access Key)用来进行签名认证。AK/SK是由系统分配给用户的,均为字符串,用于标识用户,为访问资源管理做签名验证。 + +可以通过如下步骤获得并了解您的AK/SK信息: + +[注册百度云账号](https://login.bce.baidu.com/reg.html?tpl=bceplat&from=portal) + +[创建AK/SK](https://console.bce.baidu.com/iam/?_=1513940574695#/iam/accesslist) + +## 新建资源管理 Client + +资源管理 Client是资源管理服务的客户端,为开发者与资源管理服务进行交互提供了一系列的方法。 + +### 使用AK/SK新建resmanager Client + +通过AK/SK方式访问资源管理服务,用户可以参考如下代码新建一个resmanager Client: + +```go +import ( + "github.com/baidubce/bce-sdk-go/services/resmanager" +) + +func main() { + // 用户的Access Key ID和Secret Access Key + AK, SK := , + + // 用户指定的Endpoint + ENDPOINT := + + // 初始化一个resmanagerClient + resmanagerClient, err := resmanager.NewClient(AK, SK, ENDPOINT) +} +``` + +在上面代码中,`AK`对应控制台中的“Access Key ID”,`SK`对应控制台中的“Access Key Secret”。资源管理为全局服务,第三个参数`ENDPOINT`,直接设置为空字符串,会使用默认域名作为资源管理的服务地址。 + +### 使用STS创建资源管理 Client + +**申请STS token** + +资源管理可以通过STS机制实现第三方的临时授权访问。STS(Security Token Service)是百度云提供的临时授权服务。通过STS,您可以为第三方用户颁发一个自定义时效和权限的访问凭证。第三方用户可以使用该访问凭证直接调用百度云的API或SDK访问百度云资源。 + +通过STS方式访问资源管理,用户需要先通过STS的client申请一个认证字符串,申请方式可参见[百度云STS使用介绍](https://cloud.baidu.com/doc/IAM/s/gjwvyc7n7)。 + +**用STS token新建resmanager Client** + +申请好STS后,可将STS Token配置到resmanager Client中,从而实现通过STS Token创建resmanager Client。 + +**代码示例** + +GO SDK实现了STS服务的接口,用户可以参考如下完整代码,实现申请STS Token和创建resmanager Client对象: + +```go +import ( + "fmt" + + "github.com/baidubce/bce-sdk-go/auth" //导入认证模块 + "github.com/baidubce/bce-sdk-go/services/resmanager" //导入资源管理服务模块 + "github.com/baidubce/bce-sdk-go/services/sts" //导入STS服务模块 +) + +func main() { + // 创建STS服务的Client对象,Endpoint使用默认值 + AK, SK := , + stsClient, err := sts.NewClient(AK, SK) + if err != nil { + fmt.Println("create sts client object :", err) + return + } + + // 获取临时认证token,有效期为60秒,ACL为空 + stsObj, err := stsClient.GetSessionToken(60, "") + if err != nil { + fmt.Println("get session token failed:", err) + return + } + fmt.Println("GetSessionToken result:") + fmt.Println(" accessKeyId:", stsObj.AccessKeyId) + fmt.Println(" secretAccessKey:", stsObj.SecretAccessKey) + fmt.Println(" sessionToken:", stsObj.SessionToken) + fmt.Println(" createTime:", stsObj.CreateTime) + fmt.Println(" expiration:", stsObj.Expiration) + fmt.Println(" userId:", stsObj.UserId) + + // 使用申请的临时STS创建资源管理服务的Client对象,Endpoint使用默认值 + resmanagerClient, err := resmanager.NewClient(stsObj.AccessKeyId, stsObj.SecretAccessKey, "") + if err != nil { + fmt.Println("create resmanager client failed:", err) + return + } + stsCredential, err := auth.NewSessionBceCredentials( + stsObj.AccessKeyId, + stsObj.SecretAccessKey, + stsObj.SessionToken) + if err != nil { + fmt.Println("create sts credential object failed:", err) + return + } + resmanagerClient.Config.Credentials = stsCredential +} +``` + +> 注意: +> 目前使用STS配置资源管理 Client时,无论对应资源管理服务的Endpoint在哪里,STS的Endpoint都需配置为http://sts.bj.baidubce.com。上述代码中创建STS对象时使用此默认值。 + +## 配置HTTPS协议访问资源管理 + +资源管理支持HTTPS传输协议,您可以通过在创建resmanager Client对象时指定的Endpoint中指明HTTPS的方式,在资源管理 GO SDK中使用HTTPS访问资源管理服务: + +```go +// import "github.com/baidubce/bce-sdk-go/services/resmanager" + +ENDPOINT := "https://resourcemanager.baidubce.com" //指明使用HTTPS协议 +AK, SK := , +resmanagerClient, _ := resmanager.NewClient(AK, SK, ENDPOINT) +``` + +## 配置资源管理 Client + +如果用户需要配置resmanager Client的一些细节的参数,可以在创建resmanager Client对象之后,使用该对象的导出字段`Config`进行自定义配置,可以为客户端配置代理,最大连接数等参数。 + +### 使用代理 + +下面一段代码可以让客户端使用代理访问资源管理服务: + +```go +// import "github.com/baidubce/bce-sdk-go/services/resmanager" + +//创建资源管理 Client对象 +AK, SK := , +ENDPOINT := "resourcemanager.baidubce.com" +client, _ := resmanager.NewClient(AK, SK, ENDPOINT) + +//代理使用本地的8080端口 +client.Config.ProxyUrl = "127.0.0.1:8080" +``` + +### 设置网络参数 + +用户可以通过如下的示例代码进行网络参数的设置: + +```go +// import "github.com/baidubce/bce-sdk-go/services/resmanager" + +AK, SK := , +ENDPOINT := "resourcemanager.baidubce.com" +client, _ := resmanager.NewClient(AK, SK, ENDPOINT) + +// 配置不进行重试,默认为Back Off重试 +client.Config.Retry = bce.NewNoRetryPolicy() + +// 配置连接超时时间为30秒 +client.Config.ConnectionTimeoutInMillis = 30 * 1000 +``` + +### 配置生成签名字符串选项 + +```go +// import "github.com/baidubce/bce-sdk-go/services/resmanager" + +AK, SK := , +ENDPOINT := "resourcemanager.baidubce.com" +client, _ := resmanager.NewClient(AK, SK, ENDPOINT) + +// 配置签名使用的HTTP请求头为`Host` +headersToSign := map[string]struct{}{"Host": struct{}{}} +client.Config.SignOption.HeadersToSign = HeadersToSign + +// 配置签名的有效期为30秒 +client.Config.SignOption.ExpireSeconds = 30 +``` + +**参数说明** + +用户使用GO SDK访问资源管理时,创建的资源管理 Client对象的`Config`字段支持的所有参数如下表所示: + +配置项名称 | 类型 | 含义 +-----------|---------|-------- +Endpoint | string | 请求服务的域名 +ProxyUrl | string | 客户端请求的代理地址 +Region | string | 请求资源的区域 +UserAgent | string | 用户名称,HTTP请求的User-Agent头 +Credentials| \*auth.BceCredentials | 请求的鉴权对象,分为普通AK/SK与STS两种 +SignOption | \*auth.SignOptions | 认证字符串签名选项 +Retry | RetryPolicy | 连接重试策略 +ConnectionTimeoutInMillis| int | 连接超时时间,单位毫秒,默认20分钟 + +说明: + +1. `Credentials`字段使用`auth.NewBceCredentials`与`auth.NewSessionBceCredentials`函数创建,默认使用前者,后者为使用STS鉴权时使用,详见“使用STS创建资源管理 Client”小节。 +2. `SignOption`字段为生成签名字符串时的选项,详见下表说明: + +名称 | 类型 | 含义 +--------------|-------|----------- +HeadersToSign |map[string]struct{} | 生成签名字符串时使用的HTTP头 +Timestamp | int64 | 生成的签名字符串中使用的时间戳,默认使用请求发送时的值 +ExpireSeconds | int | 签名字符串的有效期 + + 其中,HeadersToSign默认为`Host`,`Content-Type`,`Content-Length`,`Content-MD5`;TimeStamp一般为零值,表示使用调用生成认证字符串时的时间戳,用户一般不应该明确指定该字段的值;ExpireSeconds默认为1800秒即30分钟。 +3. `Retry`字段指定重试策略,目前支持两种:`NoRetryPolicy`和`BackOffRetryPolicy`。默认使用后者,该重试策略是指定最大重试次数、最长重试时间和重试基数,按照重试基数乘以2的指数级增长的方式进行重试,直到达到最大重试测试或者最长重试时间为止。 + + +# 主要接口 + +资源管理API对于每个HTTP请求,认证签名放在Authorization头域中,后端统一认证。且后端在Response头域中会添加x-bce-request-id,作为请求唯一标识,方便追踪定位问题。 + +目前支持的资源管理API接口如下: + +- 资源加入资源分组 +- 资源从资源分组移除 +- 变更资源绑定的资源分组 +- 查询资源分组列表 +- 资源ID查询资源资源分组 + +### 资源加入资源分组 + +使用以下代码可以将资源加入资源分组 +```go +args := &BindResourceToGroupArgs{ + ResourceBrief:[]ResourceBrief{ + { + // 资源ID + ResourceId:"123.org", + // 资源类型 + ResourceType:"CDN", + // 资源区域 + ResourceRegion: "global", + // 资源分组ID + GroupId:"group-123", + }, + }, + } + +result, err := client.BindResourceToGroup(args) +if err != nil { + fmt.Println("BindResourceToGroup failed:", err) +} else { + fmt.Println("BindResourceToGroup success: ", result) +} +``` + +> **提示:** +> 1. 接口详细描述请参考资源管理[API文档](https://cloud.baidu.com/doc/ResManagement/s/ilth0vmb9)。 + +### 资源从资源分组移除 + +使用以下代码可以将资源从资源分组移除 +```go +args := &BindResourceToGroupArgs{ + ResourceBrief:[]ResourceBrief{ + { + // 资源ID + ResourceId:"123.org", + // 资源类型 + ResourceType:"CDN", + // 资源区域 + ResourceRegion: "global", + // 资源分组ID + GroupId:"group-123", + }, + }, + } + +result, err := client.RemoveResourceFromGroup(args) +if err != nil { + fmt.Println("RemoveResourceFromGroup failed:", err) +} else { + fmt.Println("RemoveResourceFromGroup success: ") +} +``` + +> **提示:** +> 1. 接口详细描述请参考资源管理[API文档](https://cloud.baidu.com/doc/ResManagement/s/ilth0vmb9)。 + +### 变更资源绑定的资源分组 + +使用以下代码变更资源绑定的资源分组 +```go +args := &ChangeResourceGroupArgs{ + MoveResModels:[]MoveResModels{ + { + // 目标分组 + TargetGroupId: "group-456", + // 原有的绑定关系信息 + OldGroupResInfo: OldGroupResInfo{ + // 资源ID + ResourceId: "123.org", + // 资源类型 + ResourceType: "CDN", + // 资源区域 + ResourceRegion: "global", + // 资源分组ID + GroupId: "group-123", + }, + }, + }, + } + +result, err := client.ChangeResourceGroup(args) +if err != nil { + fmt.Println("ChangeResourceGroup failed:", err) +} else { + fmt.Println("ChangeResourceGroup success: ", result) +} +``` + +> **提示:** +> 1. 接口详细描述请参考资源管理[API文档](https://cloud.baidu.com/doc/ResManagement/s/ilth0vmb9)。 + + +### 查询资源分组列表 + + +使用以下代码可以查询资源资源分组 +```go +// 资源分组名称 +name := "test" + +result, err := client.QueryGroupList(name) +if err != nil { + fmt.Println("QueryGroupList failed:", err) +} else { + fmt.Println("QueryGroupList success: ", result) +} +``` + +> **提示:** +> 1. 接口详细描述请参考资源管理[API文档](https://cloud.baidu.com/doc/ResManagement/s/ilth0vmb9)。 + +### 资源ID查询资源资源分组 + +使用以下代码可以查询资源资源分组 +```go +args := &ResGroupDetailRequest{ + ResourceBrief:[]ResourceBrief{ + { + // 资源ID + ResourceId:"123.org", + // 资源类型 + ResourceType:"CDN", + // 资源区域 + ResourceRegion: "global", + }, + }, + } + +result, err := client.GetResGroupBatch(args) +if err != nil { + fmt.Println("GetResGroupBatch failed:", err) +} else { + fmt.Println("GetResGroupBatch success: ", result) +} +``` + +> **提示:** +> 1. 资源ID查询资源分组接口支持批量查询,一次最多支持查询2000个资源。 +> 2. 仅能查询当前账号资源,也就是根据AK, SK签名解析的账号下的资源。 +> 3. 接口详细描述请参考资源管理[API文档](https://cloud.baidu.com/doc/ResManagement/s/ilth0vmb9)。 + + +# 错误处理 + +GO语言以error类型标识错误,资源管理支持两种错误见下表: + +错误类型 | 说明 +----------------|------------------- +BceClientError | 用户操作产生的错误 +BceServiceError | 资源管理服务返回的错误 + +用户使用SDK调用资源管理相关接口,除了返回所需的结果之外还会返回错误,用户可以获取相关错误进行处理。实例如下: + +``` +// resmanager Client 为已创建的resmanager Client对象 +result, err := resmanagerClient.QueryGroupList(name) +if err != nil { + switch realErr := err.(type) { + case *bce.BceClientError: + fmt.Println("client occurs error:", realErr.Error()) + case *bce.BceServiceError: + fmt.Println("service occurs error:", realErr.Error()) + default: + fmt.Println("unknown error:", err) + } +} else { + fmt.Println("QueryGroupList success: ", result) +} +``` + +## 客户端异常 + +客户端异常表示客户端尝试向资源管理服务发送请求以及数据传输时遇到的异常。例如,当发送请求时网络连接不可用时,则会返回BceClientError;当上传文件时发生IO异常时,也会抛出BceClientError。 + +# 版本变更记录 + +## v0.9.175 [2024-04-10] + +首次发布: +- 资源加入资源分组、资源从资源分组移除、变更资源绑定的资源分组、查询资源分组列表 +- 资源ID查询资源资源分组 \ No newline at end of file diff --git a/services/bcc/api/instance.go b/services/bcc/api/instance.go index 11d4351..81540b4 100644 --- a/services/bcc/api/instance.go +++ b/services/bcc/api/instance.go @@ -2252,3 +2252,188 @@ func AddIpv6(cli bce.Client, reqBody *bce.Body) (*AddIpv6Result, error) { return jsonBody, nil } + +// TransferReservedInstanceOrder - Batch transfer reserved instance orders to designated users +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - reqBody: the arguments to initiate transfer reserved instance order +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - []string: transfer record ids +func TransferReservedInstanceOrder(cli bce.Client, reqBody *bce.Body) (*[]string, error) { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getCreateTransferReservedInstanceOrderUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return nil, err + } + if resp.IsFail() { + return nil, resp.ServiceError() + } + + jsonBody := &[]string{} + if err := resp.ParseJsonBody(jsonBody); err != nil { + return nil, err + } + + return jsonBody, nil +} + +// RevokeTransferReservedInstanceOrder - Batch revoke transfer reserved instance orders +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - reqBody: transfer record ids for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func RevokeTransferReservedInstanceOrder(cli bce.Client, reqBody *bce.Body) error { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getRevokeTransferReservedInstanceOrderUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return err + } + if resp.IsFail() { + return resp.ServiceError() + } + + defer func() { resp.Body().Close() }() + + return nil +} + +// RefuseTransferReservedInstanceOrder - Batch refuse transfer reserved instance orders +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - reqBody: transfer record ids for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func RefuseTransferReservedInstanceOrder(cli bce.Client, reqBody *bce.Body) error { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getRefuseTransferReservedInstanceOrderUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return err + } + if resp.IsFail() { + return resp.ServiceError() + } + + defer func() { resp.Body().Close() }() + + return nil +} + +// AcceptTransferReservedInstanceOrder - Accept a transfer reserved instance order +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - reqBody: transfer record id for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func AcceptTransferReservedInstanceOrder(cli bce.Client, reqBody *bce.Body) error { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getAcceptTransferReservedInstanceOrderUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return err + } + if resp.IsFail() { + return resp.ServiceError() + } + + defer func() { resp.Body().Close() }() + return nil +} + +// TransferInReservedInstanceOrders - Search transfer in reserved instance orders +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - args: the arguments to search transfer in reserved instance orders +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - DescribeTransferInRecordsResponse: search result +func TransferInReservedInstanceOrders(cli bce.Client, reqBody *bce.Body) (*DescribeTransferInRecordsResponse, error) { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getTransferInReservedInstanceOrdersUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return nil, err + } + if resp.IsFail() { + return nil, resp.ServiceError() + } + + jsonBody := &DescribeTransferInRecordsResponse{} + if err := resp.ParseJsonBody(jsonBody); err != nil { + return nil, err + } + + return jsonBody, nil +} + +// TransferOutReservedInstanceOrders - Search transfer out reserved instance orders +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - args: the arguments to search transfer out reserved instance orders +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - DescribeTransferOutRecordsResponse: search result +func TransferOutReservedInstanceOrders(cli bce.Client, reqBody *bce.Body) (*DescribeTransferOutRecordsResponse, error) { + // Build the request + req := &bce.BceRequest{} + req.SetUri(getTransferOutReservedInstanceOrdersUri()) + req.SetMethod(http.POST) + req.SetBody(reqBody) + + // Send request and get response + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return nil, err + } + if resp.IsFail() { + return nil, resp.ServiceError() + } + + jsonBody := &DescribeTransferOutRecordsResponse{} + if err := resp.ParseJsonBody(jsonBody); err != nil { + return nil, err + } + + return jsonBody, nil +} diff --git a/services/bcc/api/model.go b/services/bcc/api/model.go index 78056f1..3791295 100644 --- a/services/bcc/api/model.go +++ b/services/bcc/api/model.go @@ -186,22 +186,23 @@ type BbcStock struct { } type NicInfo struct { - Status string `json:"status"` - MacAddress string `json:"macAddress"` - DeviceId string `json:"deviceId"` - VpcId string `json:"vpcId"` - EniId string `json:"eniId"` - Name string `json:"name"` - Type string `json:"type"` - CreatedTime string `json:"createdTime"` - SubnetType string `json:"subnetType"` - SubnetId string `json:"subnetId"` - EniNum int `json:"eniNum"` - Az string `json:"az"` - EniUuid string `json:"eniUuid"` - Description string `json:"description"` - Ips []IpModel `json:"ips"` - SecurityGroups []string `json:"securityGroups"` + Status string `json:"status"` + MacAddress string `json:"macAddress"` + DeviceId string `json:"deviceId"` + VpcId string `json:"vpcId"` + EniId string `json:"eniId"` + Name string `json:"name"` + Type string `json:"type"` + CreatedTime string `json:"createdTime"` + SubnetType string `json:"subnetType"` + SubnetId string `json:"subnetId"` + EniNum int `json:"eniNum"` + Az string `json:"az"` + EniUuid string `json:"eniUuid"` + Description string `json:"description"` + Ips []IpModel `json:"ips"` + SecurityGroups []string `json:"securityGroups"` + EnterpriseSecurityGroups []string `json:"enterpriseSecurityGroups"` } type IpModel struct { @@ -997,6 +998,89 @@ type ReleasePrepaidInstanceResponse struct { InstanceRefundFlag bool `json:"instanceRefundFlag"` } +type DescribeTransferReservedInstancesRequest struct { + ReservedInstanceIds []string `json:"reservedInstanceIds"` + TransferRecordIds []string `json:"transferRecordIds"` + Spec string `json:"spec"` + Status string `json:"status"` +} + +type TransferReservedInstanceRequest struct { + ReservedInstanceIds []string `json:"reservedInstanceIds"` + RecipientAccountId string `json:"recipientAccountId"` +} + +type TransferReservedInstanceOperateRequest struct { + TransferRecordIds []string `json:"transferRecordIds"` +} + +type AcceptTransferReservedInstanceRequest struct { + TransferRecordId string `json:"transferRecordId"` +} + +type TransferSuccessInfo struct { + TransferRecordId string `json:"transferRecordId"` + TransferOrderId string `json:"transferOrderId"` +} + +type TransferFailInfo struct { + TransferRecordId string `json:"transferRecordId"` +} + +type AcceptTransferResponse struct { + Success []TransferSuccessInfo `json:"success"` + Fail []TransferFailInfo `json:"fail"` +} + +type DescribeTransferInRecordsResponse struct { + TotalCount int `json:"totalCount"` + TransferRecords []TransferInRecord `json:"transferRecords"` +} + +type DescribeTransferOutRecordsResponse struct { + TotalCount int `json:"totalCount"` + TransferRecords []TransferOutRecord `json:"transferRecords"` +} + +type TransferInRecord struct { + TransferRecordId string `json:"transferRecordId"` + GrantorUserId string `json:"grantorUserId"` + Status string `json:"status"` + ReservedInstanceInfo ReservedInstanceModel `json:"reservedInstanceInfo"` + ApplicationTime string `json:"applicationTime"` + ExpireTime string `json:"expireTime"` + EndTime string `json:"endTime"` +} + +type TransferOutRecord struct { + TransferRecordId string `json:"transferRecordId"` + RecipientUserId string `json:"recipientUserId"` + Status string `json:"status"` + ReservedInstanceInfo ReservedInstanceModel `json:"reservedInstanceInfo"` + ApplicationTime string `json:"applicationTime"` + ExpireTime string `json:"expireTime"` + EndTime string `json:"endTime"` +} + +type ReservedInstanceModel struct { + ReservedInstanceId string `json:"reservedInstanceId"` + ReservedInstanceName string `json:"reservedInstanceName"` + Scope string `json:"scope"` + ZoneName string `json:"zoneName"` + Spec string `json:"spec"` + ReservedType string `json:"reservedType"` + OfferingType string `json:"offeringType"` + OsType string `json:"osType"` + ReservedInstanceStatus string `json:"reservedInstanceStatus"` + InstanceCount int `json:"instanceCount"` + EffectiveTime string `json:"effectiveTime"` + ExpireTime string `json:"expireTime"` + AutoRenew bool `json:"autoRenew"` + RenewTimeUnit string `json:"renewTimeUnit"` + RenewTime int `json:"renewTime"` + NextRenewTime string `json:"nextRenewTime"` +} + type InstanceDeleteResultModel struct { InstanceId string `json:"instanceId"` Eip string `json:"eip"` diff --git a/services/bcc/api/util.go b/services/bcc/api/util.go index 3b0b9f0..8dc4243 100644 --- a/services/bcc/api/util.go +++ b/services/bcc/api/util.go @@ -82,6 +82,12 @@ const ( REQUEST_GET_STOCK_WITH_SPEC = "/getStockWithSpec" REQUEST_GET_AVAILABLE_STOCK_WITH_SPEC = "/getAvailableStockWithSpec" REQUEST_DELETION_PROTECTION = "/deletionProtection" + REQUEST_TRANSFER_CREATE_URI = "/reserved/transfer/create" + REQUEST_TRANSFER_REVOKE_URI = "/reserved/transfer/revoke" + REQUEST_TRANSFER_REFUSE_URI = "/reserved/transfer/refuse" + REQUEST_TRANSFER_ACCEPT_URI = "/reserved/transfer/accept" + REQUEST_TRANSFER_IN_URI = "/reserved/transfer/in/list" + REQUEST_TRANSFER_OUT_URI = "/reserved/transfer/out/list" ) func getInstanceUri() string { @@ -459,3 +465,27 @@ func getBatchRefundResourceUri() string { func getAvailableImagesBySpecUri() string { return URI_PREFIXV2 + "/image/getAvailableImagesBySpec" } + +func getCreateTransferReservedInstanceOrderUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_CREATE_URI +} + +func getRevokeTransferReservedInstanceOrderUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_REVOKE_URI +} + +func getRefuseTransferReservedInstanceOrderUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_REFUSE_URI +} + +func getAcceptTransferReservedInstanceOrderUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_ACCEPT_URI +} + +func getTransferInReservedInstanceOrdersUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_IN_URI +} + +func getTransferOutReservedInstanceOrdersUri() string { + return URI_PREFIXV2 + REQUEST_INSTANCE_URI + REQUEST_TRANSFER_OUT_URI +} diff --git a/services/bcc/client.go b/services/bcc/client.go index cd2dbfa..c9cda90 100644 --- a/services/bcc/client.go +++ b/services/bcc/client.go @@ -20,7 +20,7 @@ package bcc import ( "encoding/json" - + "fmt" "github.com/baidubce/bce-sdk-go/auth" "github.com/baidubce/bce-sdk-go/bce" "github.com/baidubce/bce-sdk-go/services/bcc/api" @@ -2343,3 +2343,129 @@ func (c *Client) BatchRefundResource(arg *api.BatchRefundResourceArg) (*api.Batc func (c *Client) GetAvailableImagesBySpec(args *api.GetAvailableImagesBySpecArg) (*api.GetAvailableImagesBySpecResult, error) { return api.GetAvailableImagesBySpec(c, args) } + +// TransferReservedInstanceOrder - Batch transfer reserved instance orders to designated users +// +// PARAMS: +// - args: the arguments to initiate transfer reserved instance order +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - []string: transfer record ids +func (c *Client) TransferReservedInstanceOrder(args *api.TransferReservedInstanceRequest) (*[]string, error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return nil, jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return nil, err + } + + return api.TransferReservedInstanceOrder(c, body) +} + +// RevokeTransferReservedInstanceOrder - Batch revoke transfer reserved instance orders +// +// PARAMS: +// - args: transfer record ids for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RevokeTransferReservedInstanceOrder(args *api.TransferReservedInstanceOperateRequest) (error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return err + } + + return api.RevokeTransferReservedInstanceOrder(c, body) +} + +// RefuseTransferReservedInstanceOrder - Batch refuse transfer reserved instance orders +// +// PARAMS: +// - args: transfer record ids for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RefuseTransferReservedInstanceOrder(args *api.TransferReservedInstanceOperateRequest) (error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return err + } + + return api.RefuseTransferReservedInstanceOrder(c, body) +} + +// AcceptTransferReservedInstanceOrder - Accept a transfer reserved instance order +// +// PARAMS: +// - args: transfer record id for operation +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) AcceptTransferReservedInstanceOrder(args *api.AcceptTransferReservedInstanceRequest) (error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return err + } + + return api.AcceptTransferReservedInstanceOrder(c, body) +} + +// TransferInReservedInstanceOrders - Search transfer in reserved instance orders +// +// PARAMS: +// - args: the arguments to search transfer in reserved instance orders +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - DescribeTransferInRecordsResponse: search result +func (c *Client) TransferInReservedInstanceOrders(args *api.DescribeTransferReservedInstancesRequest) (*api.DescribeTransferInRecordsResponse, error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return nil, jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return nil, err + } + result := &api.DescribeTransferInRecordsResponse{} + result, err = api.TransferInReservedInstanceOrders(c, body) + + jsonString, err := json.Marshal(result); + fmt.Println(string(jsonString)) + return result, err; +} + +// TransferOutReservedInstanceOrders - Search transfer out reserved instance orders +// +// PARAMS: +// - args: the arguments to search transfer out reserved instance orders +// +// RETURNS: +// - error: nil if success otherwise the specific error +// - DescribeTransferOutRecordsResponse: search result +func (c *Client) TransferOutReservedInstanceOrders(args *api.DescribeTransferReservedInstancesRequest) (*api.DescribeTransferOutRecordsResponse, error) { + jsonBytes, jsonErr := json.Marshal(args) + if jsonErr != nil { + return nil, jsonErr + } + body, err := bce.NewBodyFromBytes(jsonBytes) + if err != nil { + return nil, err + } + return api.TransferOutReservedInstanceOrders(c, body) +} diff --git a/services/bcc/client_test.go b/services/bcc/client_test.go index b371693..af4fc9d 100644 --- a/services/bcc/client_test.go +++ b/services/bcc/client_test.go @@ -1874,3 +1874,77 @@ func TestGetAvailableStockWithSpec(t *testing.T) { ExpectEqual(t.Errorf, err, nil) fmt.Println(result) } + + +func TestTransferReservedInstanceOrder(t *testing.T) { + args := &api.TransferReservedInstanceRequest{ + ReservedInstanceIds: []string{ + "r-3p89YnJf", + }, + RecipientAccountId: "", + } + result, err := BCC_CLIENT.TransferReservedInstanceOrder(args) + ExpectEqual(t.Errorf, err, nil) + fmt.Println(result) +} + +func TestRevokeTransferReservedInstanceOrder(t *testing.T) { + args := &api.TransferReservedInstanceOperateRequest{ + TransferRecordIds: []string{ + "t-tgQYk4Rx", + }, + } + err := BCC_CLIENT.RevokeTransferReservedInstanceOrder(args) + ExpectEqual(t.Errorf, err, nil) +} + +func TestRefuseTransferReservedInstanceOrder(t *testing.T) { + args := &api.TransferReservedInstanceOperateRequest{ + TransferRecordIds: []string{ + "t-tgQYk4Rx", + }, + } + err := BCC_CLIENT.RefuseTransferReservedInstanceOrder(args) + ExpectEqual(t.Errorf, err, nil) +} + +func TestAcceptTransferReservedInstanceOrder(t *testing.T) { + args := &api.AcceptTransferReservedInstanceRequest{ + TransferRecordId: "t-uNwDdZO9", + } + err := BCC_CLIENT.AcceptTransferReservedInstanceOrder(args) + ExpectEqual(t.Errorf, err, nil) +} + +func TestTransferInReservedInstanceOrders(t *testing.T) { + args := &api.DescribeTransferReservedInstancesRequest{ + ReservedInstanceIds: []string{ + //"r-I8rLAfcM", + }, + TransferRecordIds: []string{ + //"t-FoM4l1xI", + }, + Spec: "bcc.g3.c1m1", + Status: "timeout", + } + result, err := BCC_CLIENT.TransferInReservedInstanceOrders(args) + ExpectEqual(t.Errorf, err, nil) + fmt.Println(result) + +} + +func TestTransferOutReservedInstanceOrders(t *testing.T) { + args := &api.DescribeTransferReservedInstancesRequest{ + ReservedInstanceIds: []string{ + "r-ObFTPNIp", + }, + TransferRecordIds: []string{ + "t-PKnSYeWh", + }, + Spec: "bcc.ic4.c2m2", + Status: "fail", + } + result, err := BCC_CLIENT.TransferOutReservedInstanceOrders(args) + ExpectEqual(t.Errorf, err, nil) + fmt.Println(result) +} \ No newline at end of file diff --git a/services/cdn/abroad/api/domain.go b/services/cdn/abroad/api/domain.go new file mode 100644 index 0000000..378c4cc --- /dev/null +++ b/services/cdn/abroad/api/domain.go @@ -0,0 +1,174 @@ +package api + +import ( + "errors" + "fmt" + + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/model" +) + +// DomainStatus defined a struct for domain info, +// the status only include "RUNNING", "OPERATING" and "STOPPED", +// the other status is undefined +type DomainStatus struct { + Domain string `json:"domain"` + Status string `json:"status"` +} + +// DomainCreatedInfo defined a struct for `CreateDomain` return +type DomainCreatedInfo struct { + Status string `json:"status"` + Cname string `json:"cname"` +} + +// ListDomains - list all domains that in ABROAD-CDN service +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/1kbsyj9m6 +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - marker: a marker is a start point of searching +// +// RETURNS: +// - []string: domains belongs to the user +// - string: a marker for next searching, empty if is in the end +// - error: nil if success otherwise the specific error +func ListDomains(cli bce.Client, marker string) ([]string, string, error) { + type domainInfo struct { + Name string `json:"name"` + } + + respObj := &struct { + IsTruncated bool `json:"isTruncated"` + Domains []domainInfo `json:"domains"` + NextMarker string `json:"nextMarker"` + }{} + + params := map[string]string{} + if marker != "" { + params["marker"] = marker + } + + err := httpRequest(cli, "GET", "/v2/abroad/domains", params, nil, respObj) + if err != nil { + return nil, "", err + } + + domains := make([]string, len(respObj.Domains)) + for i, domain := range respObj.Domains { + domains[i] = domain.Name + } + + return domains, respObj.NextMarker, nil +} + +// CreateDomain - add a specified domain into ABROAD-CDN service +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ekbsyn5o5 +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// - originInit: initialized data for a ABROAD-CDN domain +// - tags: bind with the specified tags +// +// RETURNS: +// - *DomainCreatedInfo: the details about created a ABROAD-CDN domain +// - error: nil if success otherwise the specific error +func CreateDomain(cli bce.Client, domain string, originConfig []OriginPeer, tags []model.TagModel) (*DomainCreatedInfo, error) { + urlPath := fmt.Sprintf("/v2/abroad/domain/%s", domain) + respObj := &DomainCreatedInfo{} + + type Request struct { + OriginConfig []OriginPeer `json:"originConfig"` + Tags []model.TagModel `json:"tags,omitempty"` + } + + requestObject := &Request{ + OriginConfig: originConfig, + Tags: tags, + } + err := httpRequest(cli, "POST", urlPath, nil, requestObject, respObj) + if err != nil { + return nil, err + } + + return respObj, nil +} + +// EnableDomain - enable a specified domain +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Zkbsypv9b +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func EnableDomain(cli bce.Client, domain string) error { + if domain == "" { + return errors.New("domain parameter could not be empty") + } + + params := map[string]string{ + "enable": "", + } + urlPath := fmt.Sprintf("/v2/abroad/domain/%s", domain) + + err := httpRequest(cli, "PUT", urlPath, params, nil, nil) + if err != nil { + return err + } + + return nil +} + +// DisableDomain - disable a specified domain +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/gkbsyrdck +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func DisableDomain(cli bce.Client, domain string) error { + if domain == "" { + return errors.New("domain parameter could not be empty") + } + + params := map[string]string{ + "disable": "", + } + urlPath := fmt.Sprintf("/v2/abroad/domain/%s", domain) + + err := httpRequest(cli, "PUT", urlPath, params, nil, nil) + if err != nil { + return err + } + + return nil +} + +// DeleteDomain - delete a specified domain from BCE CDN system +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/4kbsytf7q +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func DeleteDomain(cli bce.Client, domain string) error { + if domain == "" { + return errors.New("domain parameter could not be empty") + } + + urlPath := fmt.Sprintf("/v2/abroad/domain/%s", domain) + + err := httpRequest(cli, "DELETE", urlPath, nil, nil, nil) + if err != nil { + return err + } + + return nil +} diff --git a/services/cdn/abroad/api/domain_config.go b/services/cdn/abroad/api/domain_config.go index aeb5176..6d4e152 100644 --- a/services/cdn/abroad/api/domain_config.go +++ b/services/cdn/abroad/api/domain_config.go @@ -1,6 +1,7 @@ package api import ( + "errors" "fmt" "github.com/baidubce/bce-sdk-go/bce" @@ -15,6 +16,7 @@ type DomainConfig struct { OriginHost *string `json:"originHost"` RefererACL *RefererACL `json:"refererACL"` IpACL *IpACL `json:"ipACL"` + HTTPSConfig *HTTPSConfig `json:"https"` } // OriginPeer defined a struct for Origin server. @@ -46,6 +48,13 @@ type IpACL struct { WhiteList []string `json:"whiteList"` } +type HTTPSConfig struct { + Enabled bool `json:"enabled"` + CertId string `json:"certId,omitempty"` + HttpRedirect bool `json:"httpRedirect,omitempty"` + Http2Enabled bool `json:"http2Enabled,omitempty"` +} + // GetDomainConfig - get the configuration for the specified domain // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/9kbsye6k8 // @@ -225,3 +234,132 @@ func SetIpACL(cli bce.Client, domain string, ipACL *IpACL) error { return nil } + +// HTTPSConfigOption defined a method for setting optional configurations for HTTPS config. +type HTTPSConfigOption func(interface{}) + +// HTTPSConfigCertID defined a method to pass certId witch represents a certificate uploaded in BCE SSL platform: +// https://console.bce.baidu.com/cas/#/cas/purchased/common/list. +// This Option works while the HTTPS in enabled state. +func HTTPSConfigCertID(certId string) HTTPSConfigOption { + return func(o interface{}) { + cfg, ok := o.(*httpsConfig) + if ok { + cfg.certId = certId + } + } +} + +// HTTPSConfigRedirectWith301 defined a method to enable the CDN PoPs to redirect the requests in HTTP protocol +// to the HTTPS ones, with the status 301. +// e.g. Assume that you have a CDN domain cdn.baidu.com, configured HTTPSConfigRedirectWith301, while the request +// comes just like "http://cdn.baidu.com/1.txt", the CDN Edge server would respond 301 page with Location header +// https://cdn.baidu.com/1.txt which change the scheme from "http" to "https". +// This Option works while the HTTPS in enabled state. +func HTTPSConfigRedirectWith301() HTTPSConfigOption { + return func(o interface{}) { + cfg, ok := o.(*httpsConfig) + if ok { + cfg.httpRedirect301 = true + } + } +} + +// HTTPSConfigEnableH2 defined a method to enable HTTP2 in CDN Edge server. +// This Option works while the HTTPS in enabled state. +func HTTPSConfigEnableH2() HTTPSConfigOption { + return func(o interface{}) { + cfg, ok := o.(*httpsConfig) + if ok { + cfg.enableH2 = true + } + } +} + +type httpsConfig struct { + certId string + httpRedirect301 bool + enableH2 bool +} + +// SetHTTPSConfigWithOptions - enable or disable HTTPS. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ckb0fx9ea +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// - enabled: true means enable HTTPS, otherwise disable. +// - options: more operations to configure HTTPS, the valid options are: +// 1. HTTPSConfigCertID +// 2. HTTPSConfigRedirectWith301 +// 3. HTTPSConfigEnableH2 +// RETURNS: +// - error: nil if success otherwise the specific error +func SetHTTPSConfigWithOptions(cli bce.Client, domain string, enabled bool, options ...HTTPSConfigOption) error { + urlPath := fmt.Sprintf("/v2/abroad/domain/%s/config", domain) + params := map[string]string{ + "https": "", + } + + var config httpsConfig + for _, opt := range options { + opt(&config) + } + + requestObj := map[string]interface{}{ + "enabled": enabled, + } + if enabled { + if config.certId == "" { + return errors.New("try enable HTTPS but the certId is empty") + } + requestObj["certId"] = config.certId + requestObj["httpRedirect"] = config.httpRedirect301 + requestObj["http2Enabled"] = config.enableH2 + } else { + if config.enableH2 { + return errors.New("config conflict: try enable HTTP2 and disable HTTPS") + } + if config.httpRedirect301 { + return errors.New("config conflict: try enable redirecting HTTPS requests to HTTP ones and disable HTTPS") + } + } + + err := httpRequest(cli, "PUT", urlPath, params, &struct { + HTTPS interface{} `json:"https"` + }{ + HTTPS: requestObj, + }, nil) + if err != nil { + return err + } + + return nil +} + +// SetHTTPSConfig - enable or disable HTTPS. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ckb0fx9ea +// +// PARAMS: +// - cli: the client agent which can perform sending request +// - domain: the specified domain +// - httpsConfig: HTTPS configurations. +// RETURNS: +// - error: nil if success otherwise the specific error +func SetHTTPSConfig(cli bce.Client, domain string, httpsConfig *HTTPSConfig) error { + if httpsConfig == nil { + return errors.New("HTTPS config is empty") + } + + var options []HTTPSConfigOption + if httpsConfig.CertId != "" { + options = append(options, HTTPSConfigCertID(httpsConfig.CertId)) + } + if httpsConfig.HttpRedirect { + options = append(options, HTTPSConfigRedirectWith301()) + } + if httpsConfig.Http2Enabled { + options = append(options, HTTPSConfigEnableH2()) + } + return SetHTTPSConfigWithOptions(cli, domain, httpsConfig.Enabled, options...) +} diff --git a/services/cdn/abroad/client.go b/services/cdn/abroad/client.go index 50f8023..77c8339 100644 --- a/services/cdn/abroad/client.go +++ b/services/cdn/abroad/client.go @@ -3,6 +3,7 @@ package abroad import ( "github.com/baidubce/bce-sdk-go/auth" "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/model" "github.com/baidubce/bce-sdk-go/services/cdn/abroad/api" ) @@ -51,27 +52,129 @@ func NewClient(ak, sk, endpoint string) (*Client, error) { // SendCustomRequest - send a HTTP request, and response data or error, it use the default times for retrying // // PARAMS: -// - method: the HTTP requested method, e.g. "GET", "POST", "PUT" ... -// - urlPath: a path component, consisting of a sequence of path segments separated by a slash ( / ). -// - params: the query params, which will be append to the query path, and separate by "&" -// e.g. http://www.baidu.com?query_param1=value1&query_param2=value2 -// - reqHeaders: the request http headers -// - bodyObj: the HTTP requested body content transferred to a goland object -// - respObj: the HTTP response content transferred to a goland object +// - method: the HTTP requested method, e.g. "GET", "POST", "PUT" ... +// - urlPath: a path component, consisting of a sequence of path segments separated by a slash ( / ). +// - params: the query params, which will be append to the query path, and separate by "&" +// e.g. http://www.baidu.com?query_param1=value1&query_param2=value2 +// - reqHeaders: the request http headers +// - bodyObj: the HTTP requested body content transferred to a goland object +// - respObj: the HTTP response content transferred to a goland object +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SendCustomRequest(method string, urlPath string, params, reqHeaders map[string]string, bodyObj interface{}, respObj interface{}) error { return api.SendCustomRequest(cli, method, urlPath, params, reqHeaders, bodyObj, respObj) } +// ListDomains - list all domains that in ABROAD-CDN service +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/1kbsyj9m6 +// +// PARAMS: +// - marker: a marker is a start point of searching +// +// RETURNS: +// - []string: domains belongs to the user +// - string: a marker for next searching, empty if is in the end +// - error: nil if success otherwise the specific error +func (cli *Client) ListDomains(marker string) ([]string, string, error) { + return api.ListDomains(cli, marker) +} + +// CreateDomainOption defined a method for setting optional configurations. +type CreateDomainOption func(interface{}) + +// CreateDomainWithTags defined a method for binding a CDN domain with the specified tags. +func CreateDomainWithTags(tags []model.TagModel) CreateDomainOption { + return func(o interface{}) { + cfg, ok := o.(*createDomainOption) + if ok { + cfg.tags = tags + } + } +} + +type createDomainOption struct { + tags []model.TagModel +} + +// CreateDomain - create a BCE ABROAD-CDN domain +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ekbsyn5o5 +// +// PARAMS: +// - domain: the specified domain +// - originInit: origin server for a ABROAD-CDN domain +// +// RETURNS: +// - *DomainCreatedInfo: the details about created a ABROAD-CDN domain +// - error: nil if success otherwise the specific error +func (cli *Client) CreateDomain(domain string, originConfig []api.OriginPeer) (*api.DomainCreatedInfo, error) { + return api.CreateDomain(cli, domain, originConfig, nil) +} + +// CreateDomainWithOptions - create a BCE ABROAD-CDN domain with optional configurations. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ekbsyn5o5 +// +// PARAMS: +// - domain: the specified domain +// - origins: the origin servers +// - opts: optional configure for a CDN domain, e.g. bind with BCE tags. +// +// RETURNS: +// - *DomainCreatedInfo: the details about created a ABROAD-CDN domain +// - error: nil if success otherwise the specific error +func (cli *Client) CreateDomainWithOptions(domain string, origins []api.OriginPeer, opts ...CreateDomainOption) (*api.DomainCreatedInfo, error) { + var cfg createDomainOption + for _, opt := range opts { + opt(&cfg) + } + return api.CreateDomain(cli, domain, origins, cfg.tags) +} + +// EnableDomain - enable a specified domain +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Zkbsypv9b +// +// PARAMS: +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (cli *Client) EnableDomain(domain string) error { + return api.EnableDomain(cli, domain) +} + +// DisableDomain - disable a specified domain +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/gkbsyrdck +// +// PARAMS: +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (cli *Client) DisableDomain(domain string) error { + return api.DisableDomain(cli, domain) +} + +// DeleteDomain - delete a specified domain from BCE ABROAD-CDN system. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/4kbsytf7q +// +// PARAMS: +// - domain: the specified domain +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (cli *Client) DeleteDomain(domain string) error { + return api.DeleteDomain(cli, domain) +} + // GetDomainConfig - get the configuration for the specified domain. // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/9kbsye6k8 // // PARAMS: -// - domain: the specified domain +// - domain: the specified domain +// // RETURNS: -// - *DomainConfig: the configuration about the specified domain -// - error: nil if success otherwise the specific error +// - *DomainConfig: the configuration about the specified domain +// - error: nil if success otherwise the specific error func (cli *Client) GetDomainConfig(domain string) (*api.DomainConfig, error) { return api.GetDomainConfig(cli, domain) } @@ -80,10 +183,11 @@ func (cli *Client) GetDomainConfig(domain string) (*api.DomainConfig, error) { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Gkbstcgaa // // PARAMS: -// - domain: the specified domain -// - origins: the origin servers +// - domain: the specified domain +// - origins: the origin servers +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetDomainOrigin(domain string, origins []api.OriginPeer) error { return api.SetDomainOrigin(cli, domain, origins) } @@ -95,11 +199,12 @@ type DomainOriginOption func(interface{}) // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Gkbstcgaa // // PARAMS: -// - domain: the specified domain -// - origins: the origin servers -// - opts: optional configurations for origin, unused now!!! +// - domain: the specified domain +// - origins: the origin servers +// - opts: optional configurations for origin, unused now!!! +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetDomainOriginWithOptions(domain string, origins []api.OriginPeer, opts ...DomainOriginOption) error { return api.SetDomainOrigin(cli, domain, origins) } @@ -108,10 +213,11 @@ func (cli *Client) SetDomainOriginWithOptions(domain string, origins []api.Origi // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Zkbstm0vg // // PARAMS: -// - domain: the specified domain -// - cacheTTLs: the cache setting list +// - domain: the specified domain +// - cacheTTLs: the cache setting list +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetCacheTTL(domain string, cacheTTLs []api.CacheTTL) error { return api.SetCacheTTL(cli, domain, cacheTTLs) } @@ -121,10 +227,11 @@ func (cli *Client) SetCacheTTL(domain string, cacheTTLs []api.CacheTTL) error { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/nkbsxko6t // // PARAMS: -// - domain: the specified domain -// - cacheFullUrl: the query part in URL being added to the cache key or not +// - domain: the specified domain +// - cacheFullUrl: the query part in URL being added to the cache key or not +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetCacheFullUrl(domain string, cacheFullUrl bool) error { return api.SetCacheFullUrl(cli, domain, cacheFullUrl) } @@ -133,10 +240,11 @@ func (cli *Client) SetCacheFullUrl(domain string, cacheFullUrl bool) error { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Pkbsxw8xw // // PARAMS: -// - domain: the specified domain -// - originHost: specified HOST header for origin server +// - domain: the specified domain +// - originHost: specified HOST header for origin server +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetHostToOrigin(domain string, originHost string) error { return api.SetHostToOrigin(cli, domain, originHost) } @@ -145,10 +253,11 @@ func (cli *Client) SetHostToOrigin(domain string, originHost string) error { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ekbsxow69 // // PARAMS: -// - domain: the specified domain -// - refererACL: referer of whitelist or blacklist +// - domain: the specified domain +// - refererACL: referer of whitelist or blacklist +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetRefererACL(domain string, refererACL *api.RefererACL) error { return api.SetRefererACL(cli, domain, refererACL) } @@ -157,10 +266,11 @@ func (cli *Client) SetRefererACL(domain string, refererACL *api.RefererACL) erro // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/2kbsxt693 // // PARAMS: -// - domain: the specified domain -// - ipACL: IP whitelist or blacklist +// - domain: the specified domain +// - ipACL: IP whitelist or blacklist +// // RETURNS: -// - error: nil if success otherwise the specific error +// - error: nil if success otherwise the specific error func (cli *Client) SetIpACL(domain string, ipACL *api.IpACL) error { return api.SetIpACL(cli, domain, ipACL) } @@ -169,10 +279,11 @@ func (cli *Client) SetIpACL(domain string, ipACL *api.IpACL) error { // For more details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Zkbsy0k8j // // PARAMS: -// - tasks: the tasks about purging the files from the CDN nodes +// - tasks: the tasks about purging the files from the CDN nodes +// // RETURNS: -// - PurgedId: an ID representing a purged task, using it to search the task progress -// - error: nil if success otherwise the specific error +// - PurgedId: an ID representing a purged task, using it to search the task progress +// - error: nil if success otherwise the specific error func (cli *Client) Purge(tasks []api.PurgeTask) (api.PurgedId, error) { return api.Purge(cli, tasks) } @@ -181,10 +292,11 @@ func (cli *Client) Purge(tasks []api.PurgeTask) (api.PurgedId, error) { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ikbsy9cvb // // PARAMS: -// - queryData: querying conditions, it contains the time interval, the task ID and the specified url +// - queryData: querying conditions, it contains the time interval, the task ID and the specified url +// // RETURNS: -// - *PurgedStatus: the details about the purged -// - error: nil if success otherwise the specific error +// - *PurgedStatus: the details about the purged +// - error: nil if success otherwise the specific error func (cli *Client) GetPurgedStatus(queryData *api.CStatusQueryData) (*api.PurgedStatus, error) { return api.GetPurgedStatus(cli, queryData) } @@ -193,8 +305,8 @@ func (cli *Client) GetPurgedStatus(queryData *api.CStatusQueryData) (*api.Purged // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Dlj5ch09q // // PARAMS: -// - tasks: the tasks about prefetch the files from the CDN nodes -// - error: nil if success otherwise the specific error +// - tasks: the tasks about prefetch the files from the CDN nodes +// - error: nil if success otherwise the specific error func (cli *Client) Prefetch(tasks []api.PrefetchTask) (api.PrefetchId, error) { return api.Prefetch(cli, tasks) } @@ -203,10 +315,11 @@ func (cli *Client) Prefetch(tasks []api.PrefetchTask) (api.PrefetchId, error) { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Mlj5e9y0i // // PARAMS: -// - queryData: querying conditions, it contains the time interval, the task ID and the specified url +// - queryData: querying conditions, it contains the time interval, the task ID and the specified url +// // RETURNS: -// - *PrefetchStatus: the details about the prefetch -// - error: nil if success otherwise the specific error +// - *PrefetchStatus: the details about the prefetch +// - error: nil if success otherwise the specific error func (cli *Client) GetPrefetchStatus(queryData *api.CStatusQueryData) (*api.PrefetchStatus, error) { return api.GetPrefetchStatus(cli, queryData) } @@ -215,8 +328,8 @@ func (cli *Client) GetPrefetchStatus(queryData *api.CStatusQueryData) (*api.Pref // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/flnoakciq // // RETURNS: -// - QuotaDetail: the quota details about a specified user -// - error: nil if success otherwise the specific error +// - QuotaDetail: the quota details about a specified user +// - error: nil if success otherwise the specific error func (cli *Client) GetQuota() (*api.QuotaDetail, error) { return api.GetQuota(cli) } @@ -225,11 +338,12 @@ func (cli *Client) GetQuota() (*api.QuotaDetail, error) { // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/mjwvxj0ec // // PARAMS: -// - domain: the specified domain -// - timeInterval: the specified time interval +// - domain: the specified domain +// - timeInterval: the specified time interval +// // RETURNS: -// - []LogEntry: the log detail list -// - error: nil if success otherwise the specific error +// - []LogEntry: the log detail list +// - error: nil if success otherwise the specific error func (cli *Client) GetDomainLog(domain string, timeInterval api.TimeInterval) ([]api.LogEntry, error) { return api.GetDomainLog(cli, domain, timeInterval) } @@ -238,14 +352,15 @@ func (cli *Client) GetDomainLog(domain string, timeInterval api.TimeInterval) ([ // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/Bkbszintg // // PARAMS: -// - options: the querying conditions, valid options are: -// 1. QueryStatByTimeRange -// 2. QueryStatByPeriod -// 3. QueryStatByDomains -// 4. QueryStatByCountry +// - options: the querying conditions, valid options are: +// 1. QueryStatByTimeRange +// 2. QueryStatByPeriod +// 3. QueryStatByDomains +// 4. QueryStatByCountry +// // RETURNS: -// - []FlowDetail: the details about traffic -// - error: nil if success otherwise the specific error +// - []FlowDetail: the details about traffic +// - error: nil if success otherwise the specific error func (cli *Client) GetFlow(options ...api.QueryStatOption) ([]api.FlowDetail, error) { return api.GetFlow(cli, options...) } @@ -254,14 +369,15 @@ func (cli *Client) GetFlow(options ...api.QueryStatOption) ([]api.FlowDetail, er // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/dkbszg48s // // PARAMS: -// - options: the querying conditions, valid options are: -// 1. QueryStatByTimeRange -// 2. QueryStatByPeriod -// 3. QueryStatByDomains -// 4. QueryStatByCountry +// - options: the querying conditions, valid options are: +// 1. QueryStatByTimeRange +// 2. QueryStatByPeriod +// 3. QueryStatByDomains +// 4. QueryStatByCountry +// // RETURNS: -// - []PvDetail: the details about pv/qps -// - error: nil if success otherwise the specific error +// - []PvDetail: the details about pv/qps +// - error: nil if success otherwise the specific error func (cli *Client) GetPv(options ...api.QueryStatOption) ([]api.PvDetail, error) { return api.GetPv(cli, options...) } @@ -270,13 +386,14 @@ func (cli *Client) GetPv(options ...api.QueryStatOption) ([]api.PvDetail, error) // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/rkbsznt4v // // PARAMS: -// - options: the querying conditions, valid options are: -// 1. QueryStatByTimeRange -// 2. QueryStatByPeriod -// 3. QueryStatByDomains +// - options: the querying conditions, valid options are: +// 1. QueryStatByTimeRange +// 2. QueryStatByPeriod +// 3. QueryStatByDomains +// // RETURNS: -// - []FlowDetail: the details about traffic to your origin server. -// - error: nil if success otherwise the specific error +// - []FlowDetail: the details about traffic to your origin server. +// - error: nil if success otherwise the specific error func (cli *Client) GetSrcFlow(options ...api.QueryStatOption) ([]api.FlowDetail, error) { return api.GetSrcFlow(cli, options...) } @@ -285,13 +402,14 @@ func (cli *Client) GetSrcFlow(options ...api.QueryStatOption) ([]api.FlowDetail, // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ekbszvxv5 // // PARAMS: -// - options: the querying conditions, valid options are: -// 1. QueryStatByTimeRange -// 2. QueryStatByPeriod -// 3. QueryStatByDomains +// - options: the querying conditions, valid options are: +// 1. QueryStatByTimeRange +// 2. QueryStatByPeriod +// 3. QueryStatByDomains +// // RETURNS: -// - []HttpCodeDetail: the details about accessing HTTP codes. -// - error: nil if success otherwise the specific error +// - []HttpCodeDetail: the details about accessing HTTP codes. +// - error: nil if success otherwise the specific error func (cli *Client) GetHttpCode(options ...api.QueryStatOption) ([]api.HttpCodeDetail, error) { return api.GetHttpCode(cli, options...) } @@ -300,13 +418,44 @@ func (cli *Client) GetHttpCode(options ...api.QueryStatOption) ([]api.HttpCodeDe // For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ckbszuehh // // PARAMS: -// - options: the querying conditions, valid options are: -// 1. QueryStatByTimeRange -// 2. QueryStatByPeriod -// 3. QueryStatByDomains +// - options: the querying conditions, valid options are: +// 1. QueryStatByTimeRange +// 2. QueryStatByPeriod +// 3. QueryStatByDomains +// // RETURNS: -// - []HitDetail: the details about traffic hit rate. -// - error: nil if success otherwise the specific error +// - []HitDetail: the details about traffic hit rate. +// - error: nil if success otherwise the specific error func (cli *Client) GetRealHit(options ...api.QueryStatOption) ([]api.HitDetail, error) { return api.GetRealHit(cli, options...) } + +// SetHTTPSConfigWithOptions - enable or disable HTTPS. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ckb0fx9ea +// +// PARAMS: +// - domain: the specified domain +// - enabled: true means enable HTTPS, otherwise disable. +// - options: more operations to configure HTTPS, the valid options are: +// 1. HTTPSConfigCertID +// 2. HTTPSConfigRedirectWith301 +// 3. HTTPSConfigEnableH2 +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (cli *Client) SetHTTPSConfigWithOptions(domain string, enabled bool, options ...api.HTTPSConfigOption) error { + return api.SetHTTPSConfigWithOptions(cli, domain, enabled, options...) +} + +// SetHTTPSConfig - enable or disable HTTPS. +// For details, please refer https://cloud.baidu.com/doc/CDN-ABROAD/s/ckb0fx9ea +// +// PARAMS: +// - domain: the specified domain +// - httpsConfig: HTTPS configurations. +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (cli *Client) SetHTTPSConfig(domain string, httpsConfig *api.HTTPSConfig) error { + return api.SetHTTPSConfig(cli, domain, httpsConfig) +} diff --git a/services/cdn/abroad/client_test.go b/services/cdn/abroad/client_test.go index 6241ed3..8b421ab 100644 --- a/services/cdn/abroad/client_test.go +++ b/services/cdn/abroad/client_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/baidubce/bce-sdk-go/model" "github.com/baidubce/bce-sdk-go/services/cdn/abroad/api" "github.com/baidubce/bce-sdk-go/util" "github.com/baidubce/bce-sdk-go/util/log" @@ -321,3 +322,109 @@ func TestClient_GethitRate(t *testing.T) { } t.Logf("GetRealHit successfully: %+v", details) } + +func TestClient_SetHTTPSConfigWithOptions(t *testing.T) { + var err error + + // 开启 HTTPS + var certId = "cert-4xkhw3m73hxs" + err = testCli.SetHTTPSConfigWithOptions(testDomain, true, + api.HTTPSConfigCertID(certId), // 必选 + api.HTTPSConfigRedirectWith301(), // 可选 + api.HTTPSConfigEnableH2(), // 可选 + ) + if err != nil { + t.Fatalf("SetHTTPSConfigWithOptions enable HTTPS failed: %s", err) + } + t.Logf("SetHTTPSConfigWithOptions enable HTTPS successfully") + + // 关闭 HTTPS + err = testCli.SetHTTPSConfigWithOptions(testDomain, false) + if err != nil { + t.Fatalf("SetHTTPSConfigWithOptions disable HTTPS failed: %s", err) + } + t.Logf("SetHTTPSConfigWithOptions disable HTTPS successfully") +} + +func TestClient_SetHTTPSConfig(t *testing.T) { + var err error + + // 开启 HTTPS + var certId = "cert-4xkhw3m73hxs" + err = testCli.SetHTTPSConfig(testDomain, &api.HTTPSConfig{ + Enabled: true, + CertId: certId, + HttpRedirect: true, + Http2Enabled: true, + }) + if err != nil { + t.Fatalf("SetHTTPSConfig enable HTTPS failed: %s", err) + } + t.Logf("SetHTTPSConfig enable HTTPS successfully") + + // 关闭 HTTPS + err = testCli.SetHTTPSConfig(testDomain, &api.HTTPSConfig{ + Enabled: false, + }) + if err != nil { + t.Fatalf("SetHTTPSConfig disable HTTPS failed: %s", err) + } + t.Logf("SetHTTPSConfig disable HTTPS successfully") +} + +func TestClient_ListDomains(t *testing.T) { + domains, _, err := testCli.ListDomains("") + if err != nil { + t.Fatalf("ListDomains failed: %s", err) + } + t.Logf("ListDomains success: %v", domains) +} + +func TestClient_CreateDomainWithOptions(t *testing.T) { + info, err := testCli.CreateDomainWithOptions(testDomain, []api.OriginPeer{ + { + Type: "IP", + Backup: false, + Addr: "1.1.1.1", + }, + { + Type: "IP", + Backup: true, + Addr: "2.2.2.2", + }, + }, CreateDomainWithTags([]model.TagModel{ + { + TagKey: "abroad", + TagValue: "test", + }, + })) + if err != nil { + t.Fatalf("CreateDomainWithOptions for %s failed: %s", testDomain, err) + } + + t.Logf("CreateDomainWithOptions for %s success: %+v", testDomain, info) +} + +func TestClient_EnableDomain(t *testing.T) { + err := testCli.EnableDomain(testDomain) + if err != nil { + t.Fatalf("EnableDomain for %s failed: %s", testDomain, err) + } + t.Logf("EnableDomain for %s success", testDomain) +} + +func TestClient_DisableDomain(t *testing.T) { + err := testCli.DisableDomain(testDomain) + if err != nil { + t.Fatalf("DisableDomain for %s failed: %s", testDomain, err) + } + t.Logf("DisableDomain for %s success", testDomain) +} + +func TestClient_DeleteDomain(t *testing.T) { + err := testCli.DeleteDomain(testDomain) + if err != nil { + t.Fatalf("DeleteDomain for %s failed: %s", testDomain, err) + } + t.Logf("DeleteDomain for %s success", testDomain) +} diff --git a/services/localDns/client.go b/services/localDns/client.go index bf0de6b..8913829 100644 --- a/services/localDns/client.go +++ b/services/localDns/client.go @@ -178,11 +178,12 @@ func (c *Client) ListPrivateZone(request *ListPrivateZoneRequest) ( // // PARAMS: // - zoneId: Zone的ID +// - request: 获取解析记录列表的入参,包含分页数maxKeys和起始标记marker等 // RETURNS: // - *api.ListRecordResponse: // - error: the return error if any occurs -func (c *Client) ListRecord(zoneId string) (*ListRecordResponse, error) { - return ListRecord(c, zoneId) +func (c *Client) ListRecord(zoneId string, request *ListRecordRequest) (*ListRecordResponse, error) { + return ListRecord(c, zoneId, request.Marker, request.MaxKeys, request.SourceType) } // UnbindVpc - diff --git a/services/localDns/client_test.go b/services/localDns/client_test.go index 7e9029a..27f0abc 100644 --- a/services/localDns/client_test.go +++ b/services/localDns/client_test.go @@ -21,7 +21,7 @@ var ( RR = "rr" TYPE = "A" VALUE = "1.2.3.5" - ZONE_ID = "zone-mk2guy4qxd7c" + ZONE_ID = "zone-ky94ixins803" RECORD_ID = "rc-9mfacvjk6weq" ) @@ -149,7 +149,11 @@ func TestClient_DeleteRecord(t *testing.T) { } func TestClient_ListRecord(t *testing.T) { - res, err := LD_CLIENT.ListRecord(ZONE_ID) + listRecordRequest := &ListRecordRequest{ + Marker: "rc-14ifmguzv5j2", + MaxKeys: 1000, + } + res, err := LD_CLIENT.ListRecord(ZONE_ID, listRecordRequest) fmt.Print(res) ExpectEqual(t.Errorf, nil, err) } diff --git a/services/localDns/ld.go b/services/localDns/ld.go index 7ca91fe..265ef4a 100644 --- a/services/localDns/ld.go +++ b/services/localDns/ld.go @@ -320,16 +320,30 @@ func ListPrivateZone(cli bce.Client, marker string, maxKeys int) ( // PARAMS: // - cli: the client agent which can perform sending request // - zoneId: Zone的ID +// - marker: 批量获取列表的查询的起始位置,是一个由系统生成的字符串 +// - maxKeys: 每页包含的最大数量,最大数量通常不超过1000。缺省值为1000 +// - sourceType: 记录类型,可选值 // RETURNS: // - *api.ListRecordResponse: // - error: the return error if any occurs -func ListRecord(cli bce.Client, zoneId string) (*ListRecordResponse, error) { +func ListRecord(cli bce.Client, zoneId string, marker string, maxKeys int, + sourceType string) (*ListRecordResponse, error) { req := &bce.BceRequest{} req.SetMethod(http.GET) path := "/v1/privatezone/[zoneId]/record" path = strings.Replace(path, "[zoneId]", zoneId, -1) req.SetUri(path) + if "" != sourceType { + req.SetParam("sourceType", sourceType) + } + if "" != marker { + req.SetParam("marker", marker) + } + if 0 != maxKeys { + req.SetParam("maxKeys", strconv.Itoa(maxKeys)) + } + resp := &bce.BceResponse{} if err := cli.SendRequest(req, resp); err != nil { return nil, err diff --git a/services/localDns/model.go b/services/localDns/model.go index 380edfa..c78bf85 100644 --- a/services/localDns/model.go +++ b/services/localDns/model.go @@ -142,3 +142,9 @@ type Zone struct { CreateTime string `json:"createTime"` UpdateTime string `json:"updateTime"` } + +type ListRecordRequest struct { + SourceType string + Marker string + MaxKeys int +} diff --git a/services/mongodb/client.go b/services/mongodb/client.go new file mode 100644 index 0000000..21ecfee --- /dev/null +++ b/services/mongodb/client.go @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// client.go - define the client for MONGODB service + +// Package mongodb defines the MONGODB services of BCE. The supported APIs are all defined in sub-package +package mongodb + +import "github.com/baidubce/bce-sdk-go/bce" + +const ( + URI_PREFIX = bce.URI_PREFIX + "v1" + DEFAULT_ENDPOINT = "mongodb.bj.baidubce.com" + REQUEST_MONGODB_URL = "/instance" +) + +// Client of MONGODB service is a kind of BceClient, so derived from BceClient +type Client struct { + *bce.BceClient +} + +func NewClient(ak, sk, endPoint string) (*Client, error) { + if len(endPoint) == 0 { + endPoint = DEFAULT_ENDPOINT + } + client, err := bce.NewBceClientWithAkSk(ak, sk, endPoint) + if err != nil { + return nil, err + } + return &Client{client}, nil +} + +func getMongodbUri() string { + return URI_PREFIX + REQUEST_MONGODB_URL +} + +func getMongodbUriWithInstanceId(instanceId string) string { + return URI_PREFIX + REQUEST_MONGODB_URL + "/" + instanceId +} + +func getBackupUriWithInstanceId(instanceId string) string { + return URI_PREFIX + REQUEST_MONGODB_URL + "/" + instanceId + "/backup" +} + +func getBackupUriWithBackupId(instanceId string, backupId string) string { + return URI_PREFIX + REQUEST_MONGODB_URL + "/" + instanceId + "/backup/" + backupId +} + +func getNodeUriWithInstanceId(instanceId string) string { + return URI_PREFIX + REQUEST_MONGODB_URL + "/" + instanceId + "/node" +} + +func getNodeUriWithNodeId(instanceId string, nodeId string) string { + return URI_PREFIX + REQUEST_MONGODB_URL + "/" + instanceId + "/node/" + nodeId +} diff --git a/services/mongodb/client_test.go b/services/mongodb/client_test.go new file mode 100644 index 0000000..210b42c --- /dev/null +++ b/services/mongodb/client_test.go @@ -0,0 +1,578 @@ +package mongodb + +import ( + "encoding/json" + "os" + "path/filepath" + "reflect" + "runtime" + "testing" + "time" + + "github.com/baidubce/bce-sdk-go/util/log" +) + +var ( + CLIENT *Client + INSTANCEID = "m-oHGYu8" + ORDERID string + + // set this value before start test + ACCOUNT_NAME = "baidu" + PASSWORD = "xxxxxx" +) + +// For security reason, ak/sk should not hard write here. +type Conf struct { + AK string + SK string + Endpoint string +} + +func TestListMongodb(t *testing.T) { + dbInstanceType := "replica" + args := &ListMongodbArgs{ + DbInstanceType: dbInstanceType, + MaxKeys: 10, + } + result, err := CLIENT.ListMongodb(args) + ExpectEqual(t.Errorf, nil, err) + for _, instance := range result.DbInstances { + ExpectEqual(t.Errorf, dbInstanceType, instance.DbInstanceType) + } +} + +func TestGetInstanceDetail(t *testing.T) { + detail, err := CLIENT.GetInstanceDetail(INSTANCEID) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, INSTANCEID, detail.DbInstanceId) +} + +func TestCreateReplica(t *testing.T) { + vpcId := "vpc-e5kk1bvt1t11" + subnetId := "sbn-urdqd0y5sf11" + zoneName := "cn-gz-f" + resGroupId := "RESG-XiqksQtNE11" + args := &CreateReplicaArgs{ + StorageEngine: "WiredTiger", + DbInstanceType: "replica", + DbInstanceCpuCount: 1, + DbInstanceMemoryCapacity: 2, + ReadonlyNodeNum: 0, + DbInstanceStorage: 5, + VotingMemberNum: 1, + EngineVersion: "3.6", + DbInstanceName: "test_name", + ResGroupId: resGroupId, + VpcId: vpcId, + Subnets: []SubnetMap{ + { + ZoneName: zoneName, + SubnetId: subnetId, + }, + }, + Billing: BillingModel{ + Reservation: Reservation{ + ReservationLength: 1, + ReservationTimeUnit: "Month", + }, + PaymentTiming: "Postpaid", + }, + Tags: []TagModel{ + { + TagKey: "123", + TagValue: "13", + }, + { + TagKey: "test", + TagValue: "test", + }, + }, + } + result, err := CLIENT.CreateReplica(args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, true, len(result.DbInstanceSimpleModels) > 0) +} + +func TestReplicaResize(t *testing.T) { + instanceId := "m-cvbCWv" + args := ReplicaResizeArgs{ + DbInstanceStorage: 7, + DbInstanceCpuCount: 2, + DbInstanceMemoryCapacity: 4, + } + err := CLIENT.ReplicaResize(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestRestartMongodb(t *testing.T) { + instanceId := "m-cvbCWv" + err := CLIENT.RestartMongodb(instanceId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestRestartMongodbs(t *testing.T) { + instanceIds := []string{"m-ARidmu", "m-oHGYu8"} + err := CLIENT.RestartMongodbs(instanceIds) + ExpectEqual(t.Errorf, nil, err) +} + +func TestUpdateInstanceName(t *testing.T) { + args := UpdateInstanceNameArgs{ + DbInstanceName: "test", + } + instanceId := "m-oHGYu8" + err := CLIENT.UpdateInstanceName(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestUpdateAccountPassword(t *testing.T) { + args := UpdatePasswordArgs{ + AccountPassword: "LegalPassword", // LegalPassword + } + instanceId := "m-oHGYu8" + err := CLIENT.UpdateAccountPassword(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + + args = UpdatePasswordArgs{ + AccountPassword: "IllegalPassword", + } + err = CLIENT.UpdateAccountPassword(instanceId, &args) + ExpectEqual(t.Errorf, true, err != nil) +} + +func TestReplicaSwitch(t *testing.T) { + instanceId := "m-ARidmu" + err := CLIENT.ReplicaSwitch(instanceId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestGetReadonlyNodes(t *testing.T) { + instanceId := "m-ARidmu" + result, err := CLIENT.GetReadonlyNodes(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, 1, len(result.ReadOnlyList)) + ExpectEqual(t.Errorf, 0, len(result.ReadOnlyList[0].NodeIds)) +} + +func TestReplicaAddReadonlyNodes(t *testing.T) { + increment := 1 + instanceId := "m-ARidmu" + subnetId := "sbn-urdqd0y5sf11" + zoneName := "cn-gz-f" + + result, err := CLIENT.GetReadonlyNodes(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, 1, len(result.ReadOnlyList)) + existing_cnt := len(result.ReadOnlyList[0].NodeIds) + + args := ReplicaAddReadonlyNodesArgs{ + ReadonlyNodeNum: increment, + Subnet: SubnetMap{ + ZoneName: zoneName, + SubnetId: subnetId, + }, + } + add_result, err := CLIENT.ReplicaAddReadonlyNodes(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, increment, len(add_result.ReadonlyMemberIds)) + + time.Sleep(10 * time.Second) + result, err = CLIENT.GetReadonlyNodes(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, 1, len(result.ReadOnlyList)) + ExpectEqual(t.Errorf, existing_cnt+increment, len(result.ReadOnlyList[0].NodeIds)) +} + +func TestCreateSharding(t *testing.T) { + vpcId := "vpc-e5kk1bvt1t11" + subnetId := "sbn-urdqd0y5sf11" + zoneName := "cn-gz-f" + resGroupId := "RESG-XiqksQtNE11" + args := &CreateShardingArgs{ + StorageEngine: "WiredTiger", + DbInstanceType: "sharding", + MongosCpuCount: 1, + MongosMemoryCapacity: 2, + ShardCpuCount: 1, + ShardMemoryCapacity: 2, + ShardStorage: 5, + EngineVersion: "3.6", + DbInstanceName: "shard_test_name", + ResGroupId: resGroupId, + VpcId: vpcId, + Subnets: []SubnetMap{ + { + ZoneName: zoneName, + SubnetId: subnetId, + }, + }, + Billing: BillingModel{ + Reservation: Reservation{ + ReservationLength: 0, + ReservationTimeUnit: "Month", + }, + PaymentTiming: "Postpaid", + }, + Tags: []TagModel{ + { + TagKey: "123", + TagValue: "13", + }, + { + TagKey: "test", + TagValue: "test", + }, + }, + } + result, err := CLIENT.CreateSharding(args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, true, len(result.DbInstanceSimpleModels) > 0) +} + +func TestShardingComponentResize(t *testing.T) { + instanceId := "m-2ke5iF" + nodeId := "shd-dc2N9I" + args := ShardingComponentResizeArgs{ + NodeCpuCount: 1, + NodeMemoryCapacity: 2, + NodeStorage: 6, + } + err := CLIENT.ShardingComponentResize(instanceId, nodeId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestRestartShardingComponent(t *testing.T) { + instanceId := "m-2ke5iF" + nodeId := "shd-dc2N9I" + err := CLIENT.RestartShardingComponent(instanceId, nodeId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestUpdateShardingComponentName(t *testing.T) { + instanceId := "m-2ke5iF" + nodeId := "shd-dc2N9I" + args := UpdateComponentNameArgs{ + NodeName: "test_name", + } + err := CLIENT.UpdateShardingComponentName(instanceId, nodeId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestShardingComponentSwitch(t *testing.T) { + instanceId := "m-2ke5iF" + nodeId := "shd-dc2N9I" + err := CLIENT.ShardingComponentSwitch(instanceId, nodeId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestShardingAddComponent(t *testing.T) { + instanceId := "m-2ke5iF" + args := ShardingAddComponentArgs{ + NodeCpuCount: 1, + NodeMemoryCapacity: 2, + NodeStorage: 10, + NodeType: "mongos", + } + result, err := CLIENT.ShardingAddComponent(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, 1, len(result.NodeIds)) + ExpectEqual(t.Errorf, 10, len(result.NodeIds[0])) +} + +func TestMigrateAzone(t *testing.T) { + instanceId := "m-2ke5iF" + subnetId := "sbn-jxm38c1hjk11" + zoneName := "cn-gz-a" + args := MigrateAzoneArgs{ + Subnets: []SubnetMap{ + { + subnetId, + zoneName, + }, + }, + Members: []MemberRoleModel{ + { + subnetId, + "primary", + }, + { + subnetId, + "secondary", + }, + { + subnetId, + "hidden", + }, + }, + } + err := CLIENT.MigrateAzone(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestInstanceAssignTags(t *testing.T) { + instanceId := "m-oHGYu8" + tags := []TagModel{ + // { + // TagKey: "123", + // TagValue: "13", + // }, + { + TagKey: "test", + TagValue: "test", + }, + } + err := CLIENT.InstanceAssignTags(instanceId, tags) + ExpectEqual(t.Errorf, nil, err) +} + +func TestInstanceBindTags(t *testing.T) { + instanceId := "m-oHGYu8" + tags := []TagModel{ + { + TagKey: "123", + TagValue: "13", + }, + // { + // TagKey: "test", + // TagValue: "test", + // }, + } + err := CLIENT.InstanceBindTags(instanceId, tags) + ExpectEqual(t.Errorf, nil, err) +} + +func TestInstanceUnbindTags(t *testing.T) { + instanceId := "m-oHGYu8" + tags := []TagModel{ + // { + // TagKey: "123", + // TagValue: "13", + // }, + { + TagKey: "test", + TagValue: "test", + }, + } + err := CLIENT.InstanceUnbindTags(instanceId, tags) + ExpectEqual(t.Errorf, nil, err) +} + +func TestCreateBackup(t *testing.T) { + instanceId := "m-ARidmu" + backupMethod := "Physical" + backupDescription := "test" + result, err := CLIENT.CreateBackup(instanceId, backupMethod, backupDescription) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, 13, len(result.BackupId)) +} + +func TestListBackup(t *testing.T) { + instanceId := "m-ARidmu" + args := ListBackupArgs{} + result, err := CLIENT.ListBackup(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, true, len(result.Backups) > 0) +} + +func TestGetBackupDetail(t *testing.T) { + instanceId := "m-ARidmu" + backupId := "backup-BQTR77" + result, err := CLIENT.GetBackupDetail(instanceId, backupId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, backupId, result.BackupId) +} + +func TestModifyBackupDescription(t *testing.T) { + instanceId := "m-ARidmu" + backupId := "backup-BQTR77" + description1 := "Description1" + description2 := "Description2" + args1 := ModifyBackupDescriptionArgs{ + BackupDescription: description1, + } + args2 := ModifyBackupDescriptionArgs{ + BackupDescription: description2, + } + + err := CLIENT.ModifyBackupDescription(instanceId, backupId, &args1) + ExpectEqual(t.Errorf, nil, err) + detail, err := CLIENT.GetBackupDetail(instanceId, backupId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, description1, detail.BackupDescription) + + err = CLIENT.ModifyBackupDescription(instanceId, backupId, &args2) + ExpectEqual(t.Errorf, nil, err) + detail, err = CLIENT.GetBackupDetail(instanceId, backupId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, description2, detail.BackupDescription) +} + +func TestBackupPolicy(t *testing.T) { + instanceId := "m-ARidmu" + autoBackupEnableOFF := "OFF" + autoBackupEnableON := "ON" + + policy, err := CLIENT.GetBackupPolicy(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, autoBackupEnableOFF, policy.AutoBackupEnable) + + policy.AutoBackupEnable = autoBackupEnableON + policy.PreferredBackupPeriod = "Monday" + err = CLIENT.ModifyBackupPolicy(instanceId, policy) + ExpectEqual(t.Errorf, nil, err) + + policy, err = CLIENT.GetBackupPolicy(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, autoBackupEnableON, policy.AutoBackupEnable) + + policy.AutoBackupEnable = autoBackupEnableOFF + err = CLIENT.ModifyBackupPolicy(instanceId, policy) + ExpectEqual(t.Errorf, nil, err) +} + +func TestDeleteBackup(t *testing.T) { + instanceId := "m-ARidmu" + backupId := "backup-XE1CWC" + err := CLIENT.DeleteBackup(instanceId, backupId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestReleaseMongodb(t *testing.T) { + instanceId := "m-nsC80W" + err := CLIENT.ReleaseMongodb(instanceId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestRecoverMongodbs(t *testing.T) { + instanceIds := []string{"m-nsC80W"} + err := CLIENT.RecoverMongodbs(instanceIds) + ExpectEqual(t.Errorf, nil, err) +} + +func TestDeleteMongodb(t *testing.T) { + instanceId := "m-nsC80W" + err := CLIENT.DeleteMongodb(instanceId) + ExpectEqual(t.Errorf, nil, err) +} + +func TestStartLogging(t *testing.T) { + instanceId := "m-ARidmu" + args := StartLoggingArgs{ + // Type: "error", + Type: "slow", + } + err := CLIENT.StartLogging(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestListLogFilesArgs(t *testing.T) { + instanceId := "m-ARidmu" + args := ListLogFilesArgs{ + Type: "running", + MemberId: "node-gBvCGc", + } + result, err := CLIENT.ListLogFiles(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, true, len(result.Logs) > 0) +} + +func TestGetSecurityIps(t *testing.T) { + instanceId := "m-ARidmu" + result, err := CLIENT.GetSecurityIps(instanceId) + ExpectEqual(t.Errorf, nil, err) + ExpectEqual(t.Errorf, true, len(result.SecurityIps) > 0) +} + +func TestAddSecurityIps(t *testing.T) { + instanceId := "m-ARidmu" + args := SecurityIpModel{ + SecurityIps: []string{ + "192.168.0.1", + }, + } + err := CLIENT.AddSecurityIps(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) +} + +func TestDeleteSecurityIps(t *testing.T) { + instanceId := "m-ARidmu" + securityIp := "192.168.0.1" + result, err := CLIENT.GetSecurityIps(instanceId) + ExpectEqual(t.Errorf, nil, err) + cnt := 0 + for _, ip := range result.SecurityIps { + if ip == securityIp { + cnt++ + } + } + ExpectEqual(t.Errorf, 1, cnt) + args := SecurityIpModel{ + SecurityIps: []string{ + securityIp, + }, + } + err = CLIENT.DeleteSecurityIps(instanceId, &args) + ExpectEqual(t.Errorf, nil, err) + + time.Sleep(10 * time.Second) + result, err = CLIENT.GetSecurityIps(instanceId) + ExpectEqual(t.Errorf, nil, err) + cnt = 0 + for _, ip := range result.SecurityIps { + if ip == securityIp { + cnt++ + } + } + ExpectEqual(t.Errorf, 0, cnt) +} + +func init() { + _, f, _, _ := runtime.Caller(0) + for i := 0; i < 1; i++ { + f = filepath.Dir(f) + } + conf := filepath.Join(f, "config.json") + fp, err := os.Open(conf) + if err != nil { + log.Fatal("config json file of ak/sk not given:", conf) + os.Exit(1) + } + decoder := json.NewDecoder(fp) + confObj := &Conf{} + err = decoder.Decode(confObj) + if err != nil { + log.Fatal("error in Decode:", err) + os.Exit(1) + } + + CLIENT, _ = NewClient(confObj.AK, confObj.SK, confObj.Endpoint) + log.SetLogLevel(log.WARN) +} + +// ExpectEqual is the helper function for test each case +func ExpectEqual(alert func(format string, args ...interface{}), + expected interface{}, actual interface{}) bool { + expectedValue, actualValue := reflect.ValueOf(expected), reflect.ValueOf(actual) + equal := false + switch { + case expected == nil && actual == nil: + return true + case expected != nil && actual == nil: + equal = expectedValue.IsNil() + case expected == nil && actual != nil: + equal = actualValue.IsNil() + default: + if actualType := reflect.TypeOf(actual); actualType != nil { + if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { + equal = reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) + } + } + } + if !equal { + _, file, line, _ := runtime.Caller(1) + alert("%s:%d: missmatch, expect %v but %v", file, line, expected, actual) + return false + } + return true +} diff --git a/services/mongodb/config.json b/services/mongodb/config.json new file mode 100644 index 0000000..1957225 --- /dev/null +++ b/services/mongodb/config.json @@ -0,0 +1,5 @@ +{ + "AK":"ak", + "SK":"sk", + "Endpoint":"mongodb.gz.baidubce.com" +} \ No newline at end of file diff --git a/services/mongodb/model.go b/services/mongodb/model.go new file mode 100644 index 0000000..0b98081 --- /dev/null +++ b/services/mongodb/model.go @@ -0,0 +1,400 @@ +/* + * Copyright 2024 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// model.go - definitions of the request arguments and results data structure model + +package mongodb + +import "time" + +type MemberModel struct { + MemberId string `json:"memberId,omitempty"` // 节点IP + MongoStatus string `json:"mongoStatus,omitempty"` // 节点的mongo状态 + MongoType string `json:"mongoType,omitempty"` // 节点的mongo类型 + Readonly string `json:"readonly,omitempty"` // 节点是否是只读节点 + ZoneName string `json:"zoneName,omitempty"` // 子网所属可用区 + Ip string `json:"ip,omitempty"` // 节点内网IP + MongoHost string `json:"mongoHost,omitempty"` // 节点所绑定域名 + Eip string `json:"eip,omitempty"` // 节点公网IP +} + +type DbInstanceSimpleModel struct { + DbInstanceId string `json:"dbInstanceId,omitempty"` // 实例短ID + ConnectionString string `json:"connectionString,omitempty"` // 数据库链接字符串 + Port string `json:"port,omitempty"` // 数据库连接端口 +} + +type TagModel struct { + TagKey string `json:"tagKey,omitempty"` // 标签键 + TagValue string `json:"tagValue,omitempty"` // 标签值 +} + +type NodeModel struct { + NodeId string `json:"nodeId,omitempty"` // 组件ID + Name string `json:"name,omitempty"` // 组件名称 + Status string `json:"status,omitempty"` // 组件状态 + CpuCount int `json:"cpuCount,omitempty"` // 组件CPU规格 + MemoryCapacity int `json:"memoryCapacity,omitempty"` // 组件内存规格 + Storage int `json:"storage,omitempty"` // 组件存储规格 + ConnectString string `json:"connectString,omitempty"` // 组件链接字符串 + StorageType string `json:"storageType,omitempty"` // 组件存储类型 + Members []MemberModel `json:"members,omitempty"` // 组件内节点信息 +} + +type SubnetMap struct { + SubnetId string `json:"subnetId,omitempty"` // 子网短ID + ZoneName string `json:"zoneName,omitempty"` // 子网所属可用区 +} + +type LogServiceModel struct { + Type string `json:"type,omitempty"` // 日志类型 + Status string `json:"status,omitempty"` // 日志当前状态 +} + +type ResourceGroupModel struct { + AccountId string `json:"accountId,omitempty"` + BindTime string `json:"bindTime,omitempty"` + CreateTime string `json:"createTime,omitempty"` + DeleteTime string `json:"deleteTime,omitempty"` + Extra string `json:"extra,omitempty"` + GroupId string `json:"groupId,omitempty"` + Name string `json:"name,omitempty"` + ParentUuid string `json:"parentUuid,omitempty"` + UpdateTime string `json:"updateTime,omitempty"` + UserId string `json:"userId,omitempty"` +} + +type InstanceModel struct { + DbInstanceId string `json:"dbInstanceId,omitempty"` + DbInstanceName string `json:"dbInstanceName,omitempty"` + DbInstanceUUID string `json:"dbInstanceUUID,omitempty"` + ConnectionString string `json:"connectionString,omitempty"` + Port string `json:"port,omitempty"` + StorageEngine string `json:"storageEngine,omitempty"` + EngineVersion string `json:"engineVersion,omitempty"` + ResourceGroups []ResourceGroupModel `json:"resourceGroups,omitempty"` + ResourceUuid string `json:"resourceUuid,omitempty"` + DbInstanceType string `json:"dbInstanceType,omitempty"` + DbInstanceStatus string `json:"dbInstanceStatus,omitempty"` + DbInstanceCpuCount int `json:"dbInstanceCpuCount,omitempty"` + DbInstanceMemoryCapacity int `json:"dbInstanceMemoryCapacity,omitempty"` + DbInstanceStorage int `json:"dbInstanceStorage,omitempty"` + MongosCount int `json:"mongosCount,omitempty"` + ShardCount int `json:"shardCount,omitempty"` + CreateTime time.Time `json:"createTime,omitempty"` + VotingMemberNum int `json:"votingMemberNum,omitempty"` + ReadonlyNodeNum int `json:"readonlyNodeNum,omitempty"` + VpcId string `json:"vpcId,omitempty"` + PaymentTiming string `json:"paymentTiming,omitempty"` + Subnets []SubnetMap `json:"subnets,omitempty"` + Tags []TagModel `json:"tags,omitempty"` +} + +type ListMongodbArgs struct { + Marker string + MaxKeys int + EngineVersion string + StorageEngine string + DbInstanceType string +} + +type ListMongodbResult struct { + Marker string `json:"marker,omitempty"` + MaxKeys int `json:"maxKeys,omitempty"` + IsTruncated bool `json:"isTruncated,omitempty"` + NextMarker string `json:"nextMarker,omitempty"` + DbInstances []InstanceModel `json:"dbInstances,omitempty"` +} + +type InstanceDetail struct { + DbInstanceId string `json:"dbInstanceId,omitempty"` + DbInstanceName string `json:"dbInstanceName,omitempty"` + DbInstanceUUID string `json:"dbInstanceUUID,omitempty"` + ConnectionString string `json:"connectionString,omitempty"` + Port string `json:"port,omitempty"` + EngineVersion string `json:"engineVersion,omitempty"` + StorageEngine string `json:"storageEngine,omitempty"` + ResourceGroups []ResourceGroupModel `json:"resourceGroups,omitempty"` + ResourceUuid string `json:"resourceUuid,omitempty"` + DbInstanceCpuCount int `json:"dbInstanceCpuCount,omitempty"` + DbInstanceMemoryCapacity int `json:"dbInstanceMemoryCapacity,omitempty"` + DbInstanceStorage int `json:"dbInstanceStorage,omitempty"` + DbInstanceStorageType string `json:"dbInstanceStorageType,omitempty"` + DbInstanceType string `json:"dbInstanceType,omitempty"` + MongosCount int `json:"mongosCount,omitempty"` + ShardCount int `json:"shardCount,omitempty"` + MongosList []NodeModel `json:"mongosList,omitempty"` + ShardList []NodeModel `json:"shardList,omitempty"` + VotingMemberNum int `json:"votingMemberNum,omitempty"` + ReadonlyNodeNum int `json:"readonlyNodeNum,omitempty"` + DbInstanceStatus string `json:"dbInstanceStatus,omitempty"` + CreateTime time.Time `json:"createTime,omitempty"` + ExpireTime time.Time `json:"expireTime,omitempty"` + VpcId string `json:"vpcId,omitempty"` + PublicConnectionString string `json:"publicConnectionString,omitempty"` + PublicReadonlyConnectionString string `json:"publicReadonlyConnectionString,omitempty"` + ReadOnlyNodeConnectionString string `json:"readOnlyNodeConnectionString,omitempty"` + PaymentTiming string `json:"paymentTiming,omitempty"` + LogServiceStatus []LogServiceModel `json:"logServiceStatus,omitempty"` + Members []MemberModel `json:"members,omitempty"` + Subnets []SubnetMap `json:"subnets,omitempty"` + Tags []TagModel `json:"tags,omitempty"` +} + +type Reservation struct { + ReservationLength int `json:"reservationLength"` // 时长 + ReservationTimeUnit string `json:"reservationTimeUnit"` // 时间单位,Month +} + +type BillingModel struct { + PaymentTiming string `json:"paymentTiming"` // 付费方式 + Reservation Reservation `json:"reservation"` // 保留信息 +} + +type CreateReplicaArgs struct { + ClientToken string `json:"-"` + Billing BillingModel `json:"billing,omitempty"` + PurchaseCount int `json:"purchaseCount,omitempty"` // 批量创建实例个数 + DbInstanceName string `json:"dbInstanceName,omitempty"` // 用户自定义实例名 + StorageEngine string `json:"storageEngine,omitempty"` // 存储引擎 + EngineVersion string `json:"engineVersion,omitempty"` // 数据库版本 + DbInstanceType string `json:"dbInstanceType,omitempty"` // 实例类型 + DbInstanceCpuCount int `json:"dbInstanceCpuCount,omitempty"` // 副本集实例CPU规格 + DbInstanceMemoryCapacity int `json:"dbInstanceMemoryCapacity,omitempty"` // 副本集实例内存规格,单位GB + DbInstanceStorage int `json:"dbInstanceStorage,omitempty"` // 副本集实例存储规格,单位GB + AccountPassword string `json:"accountPassword,omitempty"` // root账号的密码 + DbInstanceStorageType string `json:"dbInstanceStorageType,omitempty"` // 实例存储类型 + VotingMemberNum int `json:"votingMemberNum,omitempty"` // 副本集实例投票节点数量 + ReadonlyNodeNum int `json:"readonlyNodeNum,omitempty"` // 副本集实例只读节点数量 + SrcDbInstanceId string `json:"srcDbInstanceId,omitempty"` // 源实例ID + BackupId string `json:"backupId,omitempty"` // 备份ID + VpcId string `json:"vpcId,omitempty"` // VPC ID + Subnets []SubnetMap `json:"subnets,omitempty"` // 子网列表 + RestoreTime string `json:"restoreTime,omitempty"` // 恢复时间点 + Tags []TagModel `json:"tags,omitempty"` // 标签列表 + ResGroupId string `json:"resGroupId,omitempty"` // 资源组ID +} + +type CreateShardingArgs struct { + ClientToken string `json:"-"` + Billing BillingModel `json:"billing,omitempty"` + PurchaseCount int `json:"purchaseCount,omitempty"` + DbInstanceName string `json:"dbInstanceName,omitempty"` + StorageEngine string `json:"storageEngine,omitempty"` + EngineVersion string `json:"engineVersion,omitempty"` + DbInstanceType string `json:"dbInstanceType,omitempty"` + MongosCount int `json:"mongosCount,omitempty"` + MongosCpuCount int `json:"mongosCpuCount,omitempty"` + MongosMemoryCapacity int `json:"mongosMemoryCapacity,omitempty"` + ShardCount int `json:"shardCount,omitempty"` + ShardCpuCount int `json:"shardCpuCount,omitempty"` + ShardMemoryCapacity int `json:"shardMemoryCapacity,omitempty"` + ShardStorage int `json:"shardStorage,omitempty"` + ShardStorageType string `json:"shardStorageType,omitempty"` + AccountPassword string `json:"accountPassword,omitempty"` + SrcDbInstanceId string `json:"srcDbInstanceId,omitempty"` + BackupId string `json:"backupId,omitempty"` + VpcId string `json:"vpcId,omitempty"` + Subnets []SubnetMap `json:"subnets,omitempty"` + RestoreTime string `json:"restoreTime,omitempty"` + Tags []TagModel `json:"tags,omitempty"` + ResGroupId string `json:"resGroupId,omitempty"` +} + +type CreateResult struct { + DbInstanceSimpleModels []DbInstanceSimpleModel `json:"dbInstanceSimpleModels"` +} + +type ShardingAddComponentArgs struct { + ClientToken string `json:"-"` + DbInstanceId string `json:"dbInstanceId,omitempty"` + NodeCpuCount int `json:"nodeCpuCount,omitempty"` + NodeMemoryCapacity int `json:"nodeMemoryCapacity,omitempty"` + NodeStorage int `json:"nodeStorage,omitempty"` + NodeType string `json:"nodeType,omitempty"` + PurchaseCount int `json:"purchaseCount,omitempty"` +} + +type ShardingAddComponentResult struct { + NodeIds []string `json:"nodeIds"` +} + +type ReplicaResizeArgs struct { + ClientToken string `json:"-"` + DbInstanceCpuCount int `json:"dbInstanceCpuCount,omitempty"` + DbInstanceMemoryCapacity int `json:"dbInstanceMemoryCapacity,omitempty"` + DbInstanceStorage int `json:"dbInstanceStorage,omitempty"` +} + +type ShardingComponentResizeArgs struct { + ClientToken string `json:"-"` + DbInstanceId string `json:"dbInstanceId,omitempty"` + NodeId string `json:"nodeId,omitempty"` + NodeCpuCount int `json:"nodeCpuCount,omitempty"` + NodeMemoryCapacity int `json:"nodeMemoryCapacity,omitempty"` + NodeStorage int `json:"nodeStorage,omitempty"` +} + +type RestartMongodbsArgs struct { + DbInstanceIds []string `json:"dbInstanceIds,omitempty"` +} + +type UpdateInstanceNameArgs struct { + DbInstanceName string `json:"dbInstanceName"` +} + +type UpdateComponentNameArgs struct { + NodeName string `json:"nodeName"` +} + +type MemberRoleModel struct { + SubnetId string `json:"subnetId,omitempty"` + Role string `json:"role,omitempty"` +} + +type MigrateAzoneArgs struct { + Subnets []SubnetMap `json:"subnets,omitempty"` + Members []MemberRoleModel `json:"members,omitempty"` +} + +type LogicAssignResource struct { + ResourceId string `json:"resourceId,omitempty"` // 资源短id + ServiceType string `json:"serviceType,omitempty"` // 资源类型 + Tags []TagModel `json:"tags,omitempty"` // 标签 +} + +type UpdateTagArgs struct { + DbInstanceId string `json:"dbInstanceId,omitempty"` + Tags []TagModel `json:"tags,omitempty"` // 标签 +} + +type AssignTagArgs struct { + Resources []LogicAssignResource `json:"resources,omitempty"` // 资源列表 +} + +type BackupModel struct { + BackupId string `json:"backupId,omitempty"` // 备份ID + BackupSize string `json:"backupSize,omitempty"` // 备份大小。单位Byte + BackupMethod string `json:"backupMethod,omitempty"` // 备份方式,取值参考 + BackupMode string `json:"backupMode,omitempty"` // 备份模式,取值参考 + BackupType string `json:"backupType,omitempty"` // 备份类型,取值参考 + BackupStatus string `json:"backupStatus,omitempty"` // 备份状态,取值参考 + BackupStartTime time.Time `json:"backupStartTime,omitempty"` // 备份开始时间 + BackupEndTime time.Time `json:"backupEndTime,omitempty"` // 备份结束时间 + BackupDescription string `json:"backupDescription,omitempty"` // 备份详情 +} + +type CreateBackupArgs struct { + BackupMethod string `json:"backupMethod,omitempty"` + BackupDescription string `json:"backupDescription,omitempty"` +} + +type CreateBackupResult struct { + BackupId string `json:"backupId,omitempty"` +} + +type ListBackupArgs struct { + Marker string `json:"marker,omitempty"` + MaxKeys int `json:"maxKeys,omitempty"` +} + +type ListBackupResult struct { + Marker string `json:"marker,omitempty"` + MaxKeys int `json:"maxKeys,omitempty"` + IsTruncated bool `json:"isTruncated,omitempty"` + NextMarker string `json:"nextMarker,omitempty"` + Backups []BackupModel `json:"backups,omitempty"` +} + +type BackupDetail struct { + BackupId string `json:"backupId,omitempty"` + BackupSize string `json:"backupSize,omitempty"` + BackupMethod string `json:"backupMethod,omitempty"` + BackupMode string `json:"backupMode,omitempty"` + BackupType string `json:"backupType,omitempty"` + BackupStatus string `json:"backupStatus,omitempty"` + BackupStartTime time.Time `json:"backupStartTime,omitempty"` + BackupEndTime time.Time `json:"backupEndTime,omitempty"` + DownloadURL string `json:"downloadUrl,omitempty"` + DownloadExpires string `json:"downloadExpires,omitempty"` + BackupDescription string `json:"backupDescription,omitempty"` +} + +type ModifyBackupDescriptionArgs struct { + BackupDescription string `json:"backupDescription,omitempty"` +} + +type BackupPolicy struct { + AutoBackupEnable string `json:"autoBackupEnable,omitempty"` + PreferredBackupPeriod string `json:"preferredBackupPeriod,omitempty"` + PreferredBackupTime string `json:"preferredBackupTime,omitempty"` + BackupRetentionPeriod int `json:"backupRetentionPeriod,omitempty"` + EnableIncrementBackup int `json:"enableIncrementBackup,omitempty"` + BackupMethod string `json:"backupMethod,omitempty"` + IncrBackupRetentionPeriod int `json:"incrBackupRetentionPeriod,omitempty"` +} + +type SecurityIpModel struct { + SecurityIps []string `json:"securityIps,omitempty"` +} + +type StartLoggingArgs struct { + Type string `json:"type,omitempty"` +} + +type ListLogFilesArgs struct { + MemberId string `json:"memberId,omitempty"` + Type string `json:"type,omitempty"` + StartTime string `json:"startTime,omitempty"` + EndTime string `json:"endTime,omitempty"` +} + +type ListLogFilesResult struct { + Logs []LogFile `json:"logs,omitempty"` +} + +type LogFile struct { + Name string `json:"name,omitempty"` + StartTime string `json:"startTime,omitempty"` + EndTime string `json:"endTime,omitempty"` + Size int `json:"size,omitempty"` + DownloadUrl string `json:"downloadUrl,omitempty"` + DownloadExpires int `json:"downloadExpires,omitempty"` + DownloadExpireTime string `json:"downloadExpireTime,omitempty"` +} + +type UpdatePasswordArgs struct { + AccountPassword string `json:"accountPassword"` +} + +type ReplicaAddReadonlyNodesArgs struct { + ClientToken string `json:"-"` + DbInstanceId string `json:"dbInstanceId,omitempty"` + ReadonlyNodeNum int `json:"readonlyNodeNum,omitempty"` + Subnet SubnetMap `json:"subnet,omitempty"` +} + +type ReplicaAddReadonlyNodesResult struct { + OrderId string `json:"orderId,omitempty"` + ReadonlyMemberIds []string `json:"readonlyMemberIds,omitempty"` +} + +type ReadonlyNodesList struct { + CompId string `json:"compId,omitempty"` + NodeIds []string `json:"nodeIds,omitempty"` +} + +type GetReadonlyNodesResult struct { + ReadOnlyList []ReadonlyNodesList `json:"readOnlyList,omitempty"` +} diff --git a/services/mongodb/mongodb.go b/services/mongodb/mongodb.go new file mode 100644 index 0000000..34b79a6 --- /dev/null +++ b/services/mongodb/mongodb.go @@ -0,0 +1,944 @@ +/* + * Copyright 2024 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// mongodb.go - the mongodb APIs definition supported by the MONGODB service +package mongodb + +import ( + "errors" + "strconv" + "strings" + + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/http" +) + +const ( + DEFAULT_PAGE_SIZE = 10 + DEFAULT_PAGE_NUM = 1 + S_SHARDING = "sharding" + S_REPLICA = "replica" + S_POSTPAID = "Postpaid" + S_PREPAID = "Prepaid" +) + +// ListMongodb - list MONGODB with the specific parameters +// +// PARAMS: +// - args: the arguments to list MONGODB +// +// RETURNS: +// - *ListMongodbResult: the result of list MONGODB, contains mongodb' meta +// - error: nil if success otherwise the specific error +func (c *Client) ListMongodb(args *ListMongodbArgs) (*ListMongodbResult, error) { + if args == nil { + args = &ListMongodbArgs{} + } + + if args.MaxKeys <= 0 || args.MaxKeys > 1000 { + args.MaxKeys = 1000 + } + + result := &ListMongodbResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getMongodbUri()). + WithQueryParamFilter("manner", "marker"). + WithQueryParamFilter("marker", args.Marker). + WithQueryParamFilter("maxKeys", strconv.Itoa(args.MaxKeys)). + WithQueryParamFilter("engineVersion", args.EngineVersion). + WithQueryParamFilter("storageEngine", args.StorageEngine). + WithQueryParamFilter("dbInstanceType", args.DbInstanceType). + WithResult(result). + Do() + + return result, err +} + +// GetInstanceDetail - get a specific mongodb Instance's detail +// +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// +// RETURNS: +// - *Instance: the specific mongodbInstance's detail +// - error: nil if success otherwise the specific error +func (c *Client) GetInstanceDetail(instanceId string) (*InstanceDetail, error) { + result := &InstanceDetail{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithResult(result). + Do() + return result, err +} + +// CreateReplica - create a Replica MONGODB with the specific parameters +// +// PARAMS: +// - args: the arguments to create a mongodb +// +// RETURNS: +// - *CreateResult: the result of create MONGODB +// - error: nil if success otherwise the specific error +func (c *Client) CreateReplica(args *CreateReplicaArgs) (*CreateResult, error) { + if args == nil { + return nil, errors.New("unset args") + } + + if args.StorageEngine == "" { + return nil, errors.New("unset StorageEngine") + } + + if args.EngineVersion == "" { + return nil, errors.New("unset EngineVersion") + } + + if args.DbInstanceCpuCount <= 0 { + return nil, errors.New("unset DbInstanceCpuCount") + } + + if args.DbInstanceMemoryCapacity <= 0 { + return nil, errors.New("unset DbInstanceMemoryCapacity") + } + + if args.DbInstanceStorage <= 0 { + return nil, errors.New("unset DbInstanceStorage") + } + + if args.VotingMemberNum <= 0 { + return nil, errors.New("unset VotingMemberNum") + } + + if args.Billing.PaymentTiming == "" { + return nil, errors.New("unset PaymentTiming") + } + + if args.Billing.PaymentTiming == S_POSTPAID { + args.Billing.Reservation.ReservationLength = 0 + args.Billing.Reservation.ReservationTimeUnit = "Month" + } + + if len(args.AccountPassword) > 0 { + cryptedPass, err := Aes128EncryptUseSecreteKey(c.Config.Credentials.SecretAccessKey, args.AccountPassword) + if err != nil { + return nil, err + } + args.AccountPassword = cryptedPass + } + + args.DbInstanceType = S_REPLICA + + result := &CreateResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getMongodbUri()). + WithQueryParamFilter("clientToken", args.ClientToken). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + WithResult(result). + Do() + + return result, err +} + +// CreateSharding - create a Sharding MONGODB with the specific parameters +// +// PARAMS: +// - args: the arguments to create a mongodb +// +// RETURNS: +// - *CreateResult: the result of create MONGODB +// - error: nil if success otherwise the specific error +func (c *Client) CreateSharding(args *CreateShardingArgs) (*CreateResult, error) { + if args == nil { + return nil, errors.New("unset args") + } + + if args.StorageEngine == "" { + return nil, errors.New("unset StorageEngine") + } + + if args.EngineVersion == "" { + return nil, errors.New("unset EngineVersion") + } + + if args.MongosCpuCount <= 0 { + return nil, errors.New("unset MongosCpuCount") + } + + if args.ShardCpuCount <= 0 { + return nil, errors.New("unset ShardCpuCount") + } + + if args.ShardMemoryCapacity <= 0 { + return nil, errors.New("unset ShardMemoryCapacity") + } + + if args.ShardStorage <= 0 { + return nil, errors.New("unset ShardStorage") + } + + if args.Billing.PaymentTiming == "" { + return nil, errors.New("unset PaymentTiming") + } + + if args.Billing.PaymentTiming == S_POSTPAID { + args.Billing.Reservation.ReservationLength = 0 + args.Billing.Reservation.ReservationTimeUnit = "Month" + } + + if len(args.AccountPassword) > 0 { + cryptedPass, err := Aes128EncryptUseSecreteKey(c.Config.Credentials.SecretAccessKey, args.AccountPassword) + if err != nil { + return nil, err + } + args.AccountPassword = cryptedPass + } + + args.DbInstanceType = S_SHARDING + + result := &CreateResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getMongodbUri()). + WithQueryParamFilter("clientToken", args.ClientToken). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + WithResult(result). + Do() + + return result, err +} + +// ReleaseMongodbs - release MONGODBs / 将若干个MONGODB实例放入回收站 +// +// PARAMS: +// - instanceIds: the specific instanceIds +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ReleaseMongodbs(instanceIds []string) error { + ids := strings.Join(instanceIds, ",") + return bce.NewRequestBuilder(c). + WithMethod(http.DELETE). + WithURL(getMongodbUri()). + WithQueryParamFilter("dbInstanceIds", ids). + Do() +} + +// ReleaseMongodb - release a MONGODB / 将一个MONGODB实例放入回收站 +// +// PARAMS: +// - instanceId: the specific instanceId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ReleaseMongodb(instanceId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.DELETE). + WithURL(getMongodbUriWithInstanceId(instanceId)). + Do() +} + +// DeleteMongodbs - delete MONGODBs / 从回收站删除若干个MONGODB实例 +// +// PARAMS: +// - instanceIds: the specific instanceIds +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteMongodbs(instanceIds []string) error { + ids := strings.Join(instanceIds, ",") + return bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getMongodbUri()+"/deletePermanent"). + WithQueryParamFilter("dbInstanceIds", ids). + Do() +} + +// DeleteMongodb - delete a MONGODB / 从回收站删除一个MONGODB实例 +// +// PARAMS: +// - instanceId: the specific instanceId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteMongodb(instanceId string) error { + ids := []string{instanceId} + return c.DeleteMongodbs(ids) +} + +// RecoverMongodbs - delete MONGODBs / 从回收站恢复若干个MONGODB实例 +// +// PARAMS: +// - instanceIds: the specific instanceIds +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RecoverMongodbs(instanceIds []string) error { + ids := strings.Join(instanceIds, ",") + return bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getMongodbUri()+"/recover"). + WithQueryParamFilter("dbInstanceIds", ids). + Do() +} + +// ShardingAddComponent - create a Component with the specific parameters / 分片集实例新增组件 +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to create a Component +// +// RETURNS: +// - *ShardingAddComponentResult: the result of Add Component +// - error: nil if success otherwise the specific error +func (c *Client) ShardingAddComponent(instanceId string, args *ShardingAddComponentArgs) (*ShardingAddComponentResult, error) { + if args == nil { + return nil, errors.New("unset args") + } + + if args.NodeType == "" { + return nil, errors.New("unset NodeType") + } + + if args.NodeCpuCount <= 0 { + return nil, errors.New("unset NodeCpuCount") + } + + if args.NodeMemoryCapacity <= 0 { + return nil, errors.New("unset NodeMemoryCapacity") + } + + if args.NodeStorage <= 0 && args.NodeType == S_SHARDING { + return nil, errors.New("unset NodeStorage for sharding") + } + + result := &ShardingAddComponentResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getNodeUriWithInstanceId(instanceId)). + WithQueryParamFilter("clientToken", args.ClientToken). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + WithResult(result). + Do() + + return result, err +} + +// ReplicaResize - Resize a Replica with the specific parameters / 副本集实例改配 +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to Resize a Replica +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ReplicaResize(instanceId string, args *ReplicaResizeArgs) error { + if args == nil { + return errors.New("unset args") + } + + if args.DbInstanceCpuCount <= 0 { + return errors.New("unset DbInstanceCpuCount") + } + + if args.DbInstanceMemoryCapacity <= 0 { + return errors.New("unset DbInstanceMemoryCapacity") + } + + if args.DbInstanceStorage <= 0 { + return errors.New("unset DbInstanceStorage") + } + + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParamFilter("clientToken", args.ClientToken). + WithQueryParam("resize", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// ShardingComponentResize - Resize a Sharding Component with the specific parameters / 分片集实例组件改配 +// +// PARAMS: +// - instanceId: the specific instanceId +// - nodeId: the specific nodeId +// - args: the arguments to Resize a Sharding Component +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ShardingComponentResize(instanceId string, nodeId string, args *ShardingComponentResizeArgs) error { + if args == nil { + return errors.New("unset args") + } + + if args.NodeCpuCount <= 0 { + return errors.New("unset NodeCpuCount") + } + + if args.NodeMemoryCapacity <= 0 { + return errors.New("unset NodeMemoryCapacity") + } + args.DbInstanceId = instanceId + args.NodeId = nodeId + + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getNodeUriWithNodeId(instanceId, nodeId)). + WithQueryParamFilter("clientToken", args.ClientToken). + WithQueryParam("resize", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// RestartMongodbs - Restart MONGODBs +// +// PARAMS: +// - instanceIds: the specific instanceIds +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RestartMongodbs(instanceIds []string) error { + args := &RestartMongodbsArgs{ + DbInstanceIds: instanceIds, + } + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUri()). + WithQueryParam("restart", ""). + WithBody(args). + Do() +} + +// RestartMongodb - Restart a MONGODB +// +// PARAMS: +// - instanceId: the specific instanceId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RestartMongodb(instanceId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("restart", ""). + Do() +} + +// RestartShardingComponent - Restart a Sharding Component +// +// PARAMS: +// - instanceId: the specific instanceId +// - nodeId: the specific nodeId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) RestartShardingComponent(instanceId string, nodeId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getNodeUriWithNodeId(instanceId, nodeId)). + WithQueryParam("restart", ""). + Do() +} + +// UpdateInstanceName - update name of a specified instance +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to update instanceName +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) UpdateInstanceName(instanceId string, args *UpdateInstanceNameArgs) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("modifyName", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// UpdateShardingComponentName - update name of a specified Component +// +// PARAMS: +// - instanceId: the specific instanceId +// - nodeId: the specific nodeId +// - args: the arguments to update Component Name +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) UpdateShardingComponentName(instanceId string, nodeId string, args *UpdateComponentNameArgs) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getNodeUriWithNodeId(instanceId, nodeId)). + WithQueryParam("modifyName", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// UpdateAccountPassword - update account's password +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to update account's password +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) UpdateAccountPassword(instanceId string, args *UpdatePasswordArgs) error { + if args == nil { + return errors.New("unset args") + } + + if args.AccountPassword == "" { + return errors.New("unset AccountPassword") + } + + cryptedPass, err := Aes128EncryptUseSecreteKey(c.Config.Credentials.SecretAccessKey, args.AccountPassword) + if err != nil { + return err + } + args.AccountPassword = cryptedPass + + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("resetPassword", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// ReplicaSwitch - Switch a Replica / 副本集实例主从切换 +// +// PARAMS: +// - instanceId: the specific instanceId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ReplicaSwitch(instanceId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("switchHA", ""). + Do() +} + +// ShardingComponentSwitch - Switch a Sharding / 分片集实例组件主从切换 +// +// PARAMS: +// - instanceId: the specific instanceId +// - nodeId: the specific nodeId +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ShardingComponentSwitch(instanceId string, nodeId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getNodeUriWithNodeId(instanceId, nodeId)). + WithQueryParam("switchHA", ""). + Do() +} + +// ReplicaAddReadonlyNodes - Replica Add some ReadonlyNodes with the specific parameters / 副本集实例添加只读节点 +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to Replica Add some ReadonlyNodes +// +// RETURNS: +// - *ReplicaAddReadonlyNodesResult: the result of Replica Add some ReadonlyNodes +// - error: nil if success otherwise the specific error +func (c *Client) ReplicaAddReadonlyNodes(instanceId string, args *ReplicaAddReadonlyNodesArgs) (*ReplicaAddReadonlyNodesResult, error) { + if args == nil { + return nil, errors.New("unset args") + } + + if args.ReadonlyNodeNum <= 0 { + return nil, errors.New("unset ReadonlyNodeNum") + } + + result := &ReplicaAddReadonlyNodesResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParamFilter("clientToken", args.ClientToken). + WithQueryParam("resize", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + WithResult(result). + Do() + return result, err +} + +// GetReadonlyNodes - get ReadonlyNodes list +// +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// +// RETURNS: +// - *GetReadonlyNodesResult: the specific ReadonlyNodes list +// - error: nil if success otherwise the specific error +func (c *Client) GetReadonlyNodes(instanceId string) (*GetReadonlyNodesResult, error) { + result := &GetReadonlyNodesResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getMongodbUriWithInstanceId(instanceId) + "/getReadonlyNodes"). + WithResult(result). + Do() + return result, err +} + +// MigrateAzone - Migrate Azone of MONGODB with the specific parameters / 迁移可用区 +// +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - args: the arguments to create a mongodb +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) MigrateAzone(instanceId string, args *MigrateAzoneArgs) error { + if args == nil { + return errors.New("unset args") + } + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("migrateAzone", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// InstanceAssignTags - update tags of instance / 全量更新实例绑定的标签,即覆盖更新 +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - tags: tag args +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) InstanceAssignTags(instanceId string, tags []TagModel) error { + args := &AssignTagArgs{ + Resources: []LogicAssignResource{ + { + ResourceId: instanceId, + ServiceType: "MONGODB", + Tags: tags, + }, + }, + } + err := bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithBody(args). + WithURL(getMongodbUri() + "/tag/assign"). + Do() + return err +} + +// InstanceBindTags - add tags of instance / 增加实例绑定的标签,即追加更新 +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - tags: tag args +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) InstanceBindTags(instanceId string, tags []TagModel) error { + args := &UpdateTagArgs{ + DbInstanceId: instanceId, + Tags: tags, + } + err := bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithBody(args). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("bindTag", ""). + Do() + return err +} + +// InstanceUnbindTags - unbind tags of instance / 减少实例绑定的标签 +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - tags: tag args +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) InstanceUnbindTags(instanceId string, tags []TagModel) error { + args := &UpdateTagArgs{ + DbInstanceId: instanceId, + Tags: tags, + } + err := bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithBody(args). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("unBindTag", ""). + Do() + return err +} + +// CreateBackup - Create a Backup of mongodb Instance +// +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - backupMethod: backup method +// - backupDescription: backup description +// +// RETURNS: +// - *CreateBackupResult: Backup Result +// - error: nil if success otherwise the specific error +func (c *Client) CreateBackup(instanceId string, backupMethod string, backupDescription string) (*CreateBackupResult, error) { + result := &CreateBackupResult{} + args := CreateBackupArgs{ + BackupMethod: backupMethod, + BackupDescription: backupDescription, + } + err := bce.NewRequestBuilder(c). + WithMethod(http.POST). + WithURL(getBackupUriWithInstanceId(instanceId)). + WithBody(args). + WithResult(result). + Do() + return result, err +} + +// ListBackup - list all Backup with the specific parameters +// +// PARAMS: +// - instanceId: the specific mongodb Instance's ID +// - args: the arguments to list all MONGODB backup +// +// RETURNS: +// - *ListBackupResult: the result of list all Backup +// - error: nil if success otherwise the specific error +func (c *Client) ListBackup(instanceId string, args *ListBackupArgs) (*ListBackupResult, error) { + if args == nil { + args = &ListBackupArgs{} + } + + if args.MaxKeys <= 0 || args.MaxKeys > 1000 { + args.MaxKeys = 1000 + } + + result := &ListBackupResult{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getBackupUriWithInstanceId(instanceId)). + WithQueryParamFilter("manner", "marker"). + WithQueryParamFilter("marker", args.Marker). + WithQueryParamFilter("maxKeys", strconv.Itoa(args.MaxKeys)). + WithResult(result). + Do() + + return result, err +} + +// GetBackupDetail - get backup detail of the instance's backup +// +// PARAMS: +// - instanceId: the specific instanceId +// - backupId: id of the backup +// +// RETURNS: +// - *BackupDetail: result of the backup detail +// - error: nil if success otherwise the specific error +func (c *Client) GetBackupDetail(instanceId string, backupId string) (*BackupDetail, error) { + result := &BackupDetail{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getBackupUriWithBackupId(instanceId, backupId)). + WithResult(result). + Do() + + return result, err +} + +// ModifyBackupDescription - modify backup description +// +// PARAMS: +// - instanceId: the specific instanceId +// - backupId: id of the backup +// - args: the arguments to modify backup description +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ModifyBackupDescription(instanceId string, backupId string, args *ModifyBackupDescriptionArgs) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getBackupUriWithBackupId(instanceId, backupId)). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// DeleteBackup - delete Backup +// +// PARAMS: +// - instanceId: the specific instanceId +// - backupId: id of the backup +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteBackup(instanceId string, backupId string) error { + return bce.NewRequestBuilder(c). + WithMethod(http.DELETE). + WithURL(getBackupUriWithBackupId(instanceId, backupId)). + Do() +} + +// GetBackupPolicy - get BackupPolicy of a specific mongodb Instance +// +// PARAMS: +// - instanceId: the specific instanceId +// +// RETURNS: +// - *BackupPolicy: the Backup Policy of the instance +// - error: nil if success otherwise the specific error +func (c *Client) GetBackupPolicy(instanceId string) (*BackupPolicy, error) { + result := &BackupPolicy{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getMongodbUriWithInstanceId(instanceId) + "/backupPolicy"). + WithResult(result). + Do() + return result, err +} + +// ModifyBackupPolicy - modify backup policy +// +// PARAMS: +// - instanceId: the specific instanceId +// - args: the arguments to modify backup policy +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) ModifyBackupPolicy(instanceId string, args *BackupPolicy) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)+"/backupPolicy"). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// GetSecurityIps - get all SecurityIps +// +// PARAMS: +// - instanceId: the specific Instance's ID +// +// RETURNS: +// - *SecurityIpModel: all security IP +// - error: nil if success otherwise the specific error +func (c *Client) GetSecurityIps(instanceId string) (*SecurityIpModel, error) { + result := &SecurityIpModel{} + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("describeSecurityIps", ""). + WithResult(result). + Do() + + return result, err +} + +// AddSecurityIps - add SecurityIps +// +// PARAMS: +// - instanceId: the specific Instance's ID +// - Args: SecurityIps +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) AddSecurityIps(instanceId string, args *SecurityIpModel) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("addSecurityIps", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// DeleteSecurityIps - delete SecurityIps +// +// PARAMS: +// - instanceId: the specific Instance's ID +// - args: the arguments to delete SecurityIps +// +// RETURNS: +// - *SecurityIpModel: security IP +// - error: nil if success otherwise the specific error +func (c *Client) DeleteSecurityIps(instanceId string, args *SecurityIpModel) error { + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("deleteSecurityIps", ""). + WithHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE). + WithBody(args). + Do() +} + +// StartLogging - start Logging +// PARAMS: +// - instanceId: the specific Instance's ID +// - args: the arguments to start Logging +// +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) StartLogging(instanceId string, args *StartLoggingArgs) error { + if args == nil { + return errors.New("unset args") + } + return bce.NewRequestBuilder(c). + WithMethod(http.PUT). + WithURL(getMongodbUriWithInstanceId(instanceId)). + WithQueryParam("startLogging", ""). + WithBody(args). + Do() +} + +// ListLogFiles - get log list +// PARAMS: +// - instanceId: the specific Instance's ID +// - args: the arguments to get log list +// +// RETURNS: +// - *ListLogFilesResult: the result of log list +// - error: nil if success otherwise the specific error +func (c *Client) ListLogFiles(instanceId string, args *ListLogFilesArgs) (*ListLogFilesResult, error) { + result := &ListLogFilesResult{} + if args == nil { + return result, errors.New("unset args") + } + err := bce.NewRequestBuilder(c). + WithMethod(http.GET). + WithBody(args). + WithURL(getMongodbUriWithInstanceId(instanceId)+"/log"). + WithQueryParam("listLogFiles", ""). + WithQueryParamFilter("memberId", args.MemberId). + WithQueryParamFilter("type", args.Type). + WithQueryParamFilter("startTime", args.StartTime). + WithQueryParamFilter("endTime", args.EndTime). + WithResult(result). + Do() + + return result, err +} diff --git a/services/mongodb/util.go b/services/mongodb/util.go new file mode 100644 index 0000000..7cc9697 --- /dev/null +++ b/services/mongodb/util.go @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// util.go - define the utilities for api package of MONGODB service +package mongodb + +import ( + "encoding/hex" + "errors" + + "github.com/baidubce/bce-sdk-go/util/crypto" +) + +func Aes128EncryptUseSecreteKey(sk string, data string) (string, error) { + if len(sk) < 16 { + return "", errors.New("error secrete key") + } + + crypted, err := crypto.EBCEncrypto([]byte(sk[:16]), []byte(data)) + if err != nil { + return "", err + } + + return hex.EncodeToString(crypted), nil +} diff --git a/services/resmanager/client_test.go b/services/resmanager/client_test.go index aa37baa..edaa93b 100644 --- a/services/resmanager/client_test.go +++ b/services/resmanager/client_test.go @@ -127,3 +127,63 @@ func TestGetResGroupBatch(t *testing.T) { jsonRes, _ := json.Marshal(res) t.Logf(string(jsonRes)) } + +func TestRemoveResourceFromGroup(t *testing.T) { + args := &BindResourceToGroupArgs{ + Bindings: []Binding{ + { + ResourceId: "weaxsey.org", + ResourceType: "CDN", + ResourceRegion: "global", + GroupId: "RESG-kvst7Bqqygx", + }, + }, + } + err := resClient.RemoveResourceFromGroup(args) + ExpectEqual(t.Errorf, err, nil) +} + +func TestBindResourceToGroup(t *testing.T) { + args := &BindResourceToGroupArgs{ + Bindings: []Binding{ + { + ResourceId: "weaxsey.org", + ResourceType: "CDN", + ResourceRegion: "global", + GroupId: "RESG-kvst7Bqqygx", + }, + }, + } + res, err := resClient.BindResourceToGroup(args) + ExpectEqual(t.Errorf, err, nil) + jsonRes, _ := json.Marshal(res) + t.Logf(string(jsonRes)) +} + +func TestChangeResourceGroup(t *testing.T) { + args := &ChangeResourceGroupArgs{ + MoveResModels: []MoveResModel{ + { + TargetGroupId: "RESG-a088c216", + OldGroupResInfo: OldGroupResInfo{ + ResourceId: "weaxsey.org", + ResourceType: "CDN", + ResourceRegion: "global", + GroupId: "RESG-kvst7Bqqygx", + }, + }, + }, + } + res, err := resClient.ChangeResourceGroup(args) + ExpectEqual(t.Errorf, err, nil) + jsonRes, _ := json.Marshal(res) + t.Logf(string(jsonRes)) +} + +func TestQueryGroupList(t *testing.T) { + var args = "test" + res, err := resClient.QueryGroupList(args) + ExpectEqual(t.Errorf, err, nil) + jsonRes, _ := json.Marshal(res) + t.Logf(string(jsonRes)) +} diff --git a/services/resmanager/model.go b/services/resmanager/model.go index 3d0b8f5..c20c85b 100644 --- a/services/resmanager/model.go +++ b/services/resmanager/model.go @@ -99,7 +99,7 @@ type MoveResModel struct { } type OldGroupResInfo struct { - ResourceId string `json:"reourceId"` + ResourceId string `json:"resourceId"` ResourceType string `json:"resourceType"` ResourceRegion string `json:"resourceRegion"` GroupId string `json:"groupId"`