Skip to content

Commit

Permalink
feat: 终止合约
Browse files Browse the repository at this point in the history
  • Loading branch information
tangx committed Dec 29, 2021
1 parent 1791d82 commit a3442e3
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 10 deletions.
74 changes: 67 additions & 7 deletions cmd/contract_terminate.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package cmd

import (
"encoding/json"
"fmt"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/tangx/qingclix/modules"
)

// contractCmdTerminate 取消合约
// contractCmdTerminate 终止合约
var contractCmdTerminate = &cobra.Command{
Use: "terminate",
Short: "释放合约",
Short: `终止合约。 如果合约中还有绑定的资源, 则失败。`,
Run: func(cmd *cobra.Command, args []string) {
if !isDissocateValidArgs(terminateContracts) {
_ = cmd.Help()
Expand All @@ -30,8 +33,9 @@ var (
func init() {
flag := contractCmdTerminate.Flags()

flag.StringVarP(&terminateContracts, "targets", "", "", "合约ID")
flag.BoolVarP(&terminateConfirm, "confirm", "", false, "确实释放")
flag.StringVarP(&terminateContracts, "targets", "", "", "合约ID,多个合约ID之间是用 , 进行分割")
flag.BoolVarP(&terminateConfirm, "confirm", "", false, `确实释放
必须指定 --confirm=true , 否则不执行。 故意的`)

}

Expand All @@ -41,14 +45,70 @@ func init() {

func terminateContract() {
if !terminateConfirm {
logrus.Infoln("显示指定 --confirm true 释放资源")
logrus.Error("指定 --confirm=true 开启释放开关")
return
}

for _, contract := range targetsFromString(terminateContracts) {
err := modules.TerminateContract(contract, true)
err := isEmptyContract(contract)
if err != nil {
logrus.Errorf("释放合约失败: %v", err)
logrus.Errorf("释放合约 (%s) 失败: %v", contract, err)
continue
}

// err = modules.TerminateContract(contract, true)
// if err != nil {
// logrus.Errorf("释放合约 (%s) 失败: %v", contract, err)
// continue
// }

logrus.Infof("释放合约 (%s) 成功", contract)
}
}

// isEmptyContract 检查合约是否解绑完成所有资源
func isEmptyContract(contract string) error {
resp := modules.DescContract(contract)
if resp.RetCode != 0 {
return fmt.Errorf("%s", resp.Message)
}

// 合约分两部分 rc 和 rce
// 1. 首先查询合约是否存在, 可以获取合约的基本信息, 如区域和类型
if len(resp.ReservedContractSet) > 0 {
c := resp.ReservedContractSet[0]
// output(c)
// 2. 查询合约内是否绑定有资源
if len(c.Entries) > 0 {

for _, entry := range c.Entries {
if err := isEmptyContractRCE(entry.EntryID); err != nil {
logrus.Errorf("合约还有资源没有取消绑定: https://console.qingcloud.com/%s/%ss/reserved_contracts/%s/%s", c.ZoneID, c.ResourceType, contract, entry.EntryID)
return fmt.Errorf("合约还有资源没有取消绑定")
}
}
}
}

return nil
}

func isEmptyContractRCE(rce_id string) error {
resp, err := modules.DescribeReservedResources(rce_id)
if err != nil {
return err
}

// resp.ReservedResourceSet
if len(resp.ReservedResourceSet) > 0 {

return fmt.Errorf("合约绑定资源, 数量 %d", resp.TotalCount)
}

return nil
}

func output(v interface{}) {
b, _ := json.Marshal(v)
logrus.Infof("output= %s", b)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/magefile/mage v1.11.0 // indirect
github.com/onsi/gomega v1.10.5
github.com/satori/go.uuid v1.2.0
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.8.0
github.com/spf13/cobra v1.1.1
github.com/tangx/go-querystring v1.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
Expand Down
20 changes: 20 additions & 0 deletions modules/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
func DescContract(id string) qingyun.DescribeReservedContractsResponse {
params := qingyun.DescribeReservedContractsRequest{
ReservedContracts: []string{id},
Verbose: 1,
}
resp, err := global.QingClix.DescribeReservedContracts(params)
if err != nil {
Expand Down Expand Up @@ -132,3 +133,22 @@ func TerminateContract(contract string, confirm bool) error {

return nil
}

func DescribeReservedResources(rce_id string) (*qingyun.DescribeReservedResourcesResponse, error) {
params := qingyun.DescribeReservedResourcesRequest{
Entry: rce_id,
Verbose: 1,
SortKey: "create_time",
Reverse: 1,
Offset: 0,
Limit: 10,
// Action: "DescribeReservedResources",
}

resp, err := global.QingClix.DescribeReservedResources(params)
if err != nil {
return nil, err
}

return &resp, nil
}
54 changes: 52 additions & 2 deletions sdk-go/qingyun/contract.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package qingyun

import "github.com/shopspring/decimal"

type ApplyReservedContractWithResourcesRequest struct {
Zone string `yaml:"zone,omitempty" json:"zone,omitempty" url:"zone,omitempty"`
Resources []string `yaml:"resources,omitempty" json:"resources,omitempty" url:"resources,omitempty,dotnumbered,numbered1"`
Expand Down Expand Up @@ -67,13 +69,15 @@ type DescribeReservedContractsRequest struct {
Offset int `yaml:"offset,omitempty" json:"offset,omitempty" url:"offset,omitempty"`
ReservedContracts []string `yaml:"reserved_contracts,omitempty" json:"reserved_contracts,omitempty" url:"reserved_contracts,omitempty,dotnumbered,numbered1"`
ResourceType []string `yaml:"resource_type,omitempty" json:"resource_type,omitempty" url:"resource_type,omitempty,dotnumbered,numbered1"`
Verbose int `yaml:"verbose,omitempty" json:"verbose,omitempty" url:"verbose,omitempty"`
}

type DescribeReservedContractsResponse struct {
Action string `json:"action"`
TotalCount int `json:"total_count"`
ReservedContractSet []ReservedContractSet `json:"reserved_contract_set"`
RetCode int `json:"ret_code"`
Message string `json:"message"`
}

type ReservedContractSet struct {
Expand All @@ -93,14 +97,23 @@ type ReservedContractSet struct {
Description string `json:"description"`
TransitionStatus string `json:"transition_status"`
LastApplymentType string `json:"last_applyment_type"`
Entries []interface{} `json:"entries"`
Entries []Entry `json:"entries"`
ExpireTime string `json:"expire_time"`
ZoneID string `json:"zone_id"`
Months int `json:"months"`
RootUserID string `json:"root_user_id"`
ResourceType string `json:"resource_type"`
}

type Entry struct {
Count int64 `json:"count"`
ProductID interface{} `json:"product_id"`
Price decimal.Decimal `json:"price"`
ApplymentID string `json:"applyment_id"`
EntryID string `json:"entry_id"`
ResourceInfo interface{} `json:"resource_info"`
}

type LastApplyment struct {
Status string `json:"status"`
ApplymentType string `json:"applyment_type"`
Expand Down Expand Up @@ -164,4 +177,41 @@ type TerminateReservedContractResponse struct {
RetCode int `json:"ret_code,omitempty"`
}

// url:"server_certificates"
// DescribeReservedResources 查询 rce 订单绑定的资源情况
func (cli *Client) DescribeReservedResources(params DescribeReservedResourcesRequest) (resp DescribeReservedResourcesResponse, err error) {
params.Action = "DescribeReservedResources"
err = cli.MethodGET("DescribeReservedResources", params, &resp)
return
}

type DescribeReservedResourcesRequest struct {
Owner string `json:"owner,omitempty" url:"owner,omitempty"`
Zone string `json:"zone,omitempty" url:"zone,omitempty"`
Action string `json:"action,omitempty" url:"action,omitempty"`
Offset int `json:"offset,omitempty" url:"offset,omitempty"`
Limit int `json:"limit,omitempty" url:"limit,omitempty"`
Verbose int `json:"verbose,omitempty" url:"verbose,omitempty"`
SortKey string `json:"sort_key,omitempty" url:"sort_key,omitempty"`
Reverse int `json:"reverse,omitempty" url:"reverse,omitempty"`
Entry string `json:"entry,omitempty" url:"entry,omitempty"`
}

type DescribeReservedResourcesResponse struct {
Action string `json:"action"`
TotalCount int `json:"total_count"`
ReservedResourceSet []ReservedResourceSet `json:"reserved_resource_set"`
ZoneID string `json:"zone_id"`
RetCode int `json:"ret_code"`
}

type ReservedResourceSet struct {
ResourceName string `json:"resource_name"`
UserID string `json:"user_id"`
ZoneID string `json:"zone_id"`
ResourceID string `json:"resource_id"`
ResourceStatus string `json:"resource_status"`
RootUserID string `json:"root_user_id"`
CreateTime string `json:"create_time"`
EntryID string `json:"entry_id"`
ContractID string `json:"contract_id"`
}
2 changes: 1 addition & 1 deletion sdk-go/qingyun/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (cli *Client) MethodGET(action string, params interface{}, ptrResp interfac
}

data, err := cli.requestGET(action, urlValues, ptrResp)
// logrus.Debugf("%s", data)
logrus.Debugf("%s", data)

// http request error
if err != nil {
Expand Down

0 comments on commit a3442e3

Please sign in to comment.