/
common.go
109 lines (95 loc) · 3.65 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package dds
import (
"encoding/json"
"fmt"
"github.com/jmespath/go-jmespath"
"github.com/chnsz/golangsdk"
)
var (
// Some error codes that need to be retried coming from https://console-intl.huaweicloud.com/apiexplorer/#/errorcenter/DDS.
retryErrCodes = map[string]struct{}{
"DBS.200019": {}, // An operation that conflicts with the current operation is in progress.
"DBS.239037": {},
"DBS.201000": {}, // ssl
"DBS.00010009": {}, // Instance's status is not available for this operation.
}
)
// The DDS instance is limited to only one operation at a time.
// In addition to locking and waiting between multiple operations, a retry method is required to ensure that the
// request can be executed correctly.
func handleMultiOperationsError(err error) (bool, error) {
if err == nil {
// The operation was executed successfully and does not need to be executed again.
return false, nil
}
if errCode, ok := err.(golangsdk.ErrDefault400); ok {
var apiError interface{}
if jsonErr := json.Unmarshal(errCode.Body, &apiError); jsonErr != nil {
return false, fmt.Errorf("unmarshal the response body failed: %s", jsonErr)
}
errorCode, errorCodeErr := jmespath.Search("error_code", apiError)
if errorCodeErr != nil {
return false, fmt.Errorf("error parse errorCode from response body: %s", errorCodeErr)
}
if _, ok = retryErrCodes[errorCode.(string)]; ok {
// The operation failed to execute and needs to be executed again, because other operations are
// currently in progress.
return true, err
}
}
if errCode, ok := err.(golangsdk.ErrDefault403); ok {
var apiError interface{}
if jsonErr := json.Unmarshal(errCode.Body, &apiError); jsonErr != nil {
return false, fmt.Errorf("unmarshal the response body failed: %s", jsonErr)
}
errorCode, errorCodeErr := jmespath.Search("error_code", apiError)
if errorCodeErr != nil {
return false, fmt.Errorf("error parse errorCode from response body: %s", errorCodeErr)
}
if _, ok = retryErrCodes[errorCode.(string)]; ok {
// The operation failed to execute and needs to be executed again, because other operations are
// currently in progress.
return true, err
}
}
// Operation execution failed due to some resource or server issues, no need to try again.
return false, err
}
func handleDeletionError(err error) (bool, error) {
if err == nil {
// The operation was executed successfully and does not need to be executed again.
return false, nil
}
// unsubscribe fail
if errCode, ok := err.(golangsdk.ErrDefault400); ok {
var apiError interface{}
if jsonErr := json.Unmarshal(errCode.Body, &apiError); jsonErr != nil {
return false, fmt.Errorf("unmarshal the response body failed: %s", jsonErr)
}
errorCode, errorCodeErr := jmespath.Search("error_code", apiError)
if errorCodeErr != nil {
return false, fmt.Errorf("error parse errorCode from response body: %s", errorCodeErr)
}
// CBC.99003651: Another operation is being performed.
if errorCode == "CBC.99003651" {
return true, err
}
}
// delete fail
if errCode, ok := err.(golangsdk.ErrDefault403); ok {
var apiError interface{}
if jsonErr := json.Unmarshal(errCode.Body, &apiError); jsonErr != nil {
return false, fmt.Errorf("unmarshal the response body failed: %s", jsonErr)
}
errorCode, errorCodeErr := jmespath.Search("error_code", apiError)
if errorCodeErr != nil {
return false, fmt.Errorf("error parse errorCode from response body: %s", errorCodeErr)
}
if _, ok = retryErrCodes[errorCode.(string)]; ok {
// The operation failed to execute and needs to be executed again, because other operations are
// currently in progress.
return true, err
}
}
return false, err
}