@@ -11,15 +11,13 @@ import (
11
11
"fmt"
12
12
"log"
13
13
"net/http"
14
- "regexp"
15
14
"strings"
16
15
"time"
17
16
18
17
"github.com/hashicorp/go-multierror"
19
18
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
20
19
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
21
20
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
22
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
23
21
"github.com/jmespath/go-jmespath"
24
22
25
23
"github.com/chnsz/golangsdk"
@@ -70,21 +68,13 @@ func ResourceDdsBackup() *schema.Resource {
70
68
Required : true ,
71
69
ForceNew : true ,
72
70
Description : `Specifies the manual backup name.` ,
73
- ValidateFunc : validation .All (
74
- validation .StringMatch (regexp .MustCompile (`^[A-Za-z-_0-9]*$` ),
75
- "the value must be 4 to 64 characters in length and start with a letter" +
76
- "(from A to Z or from a to z). It is case-sensitive and can contain only letters," +
77
- "digits (from 0 to 9), hyphens (-), and underscores (_)" ),
78
- validation .StringLenBetween (4 , 64 ),
79
- ),
80
71
},
81
72
"description" : {
82
- Type : schema .TypeString ,
83
- Optional : true ,
84
- Computed : true ,
85
- ForceNew : true ,
86
- Description : `Specifies the manual backup description` ,
87
- ValidateFunc : validation .StringLenBetween (0 , 256 ),
73
+ Type : schema .TypeString ,
74
+ Optional : true ,
75
+ Computed : true ,
76
+ ForceNew : true ,
77
+ Description : `Specifies the manual backup description` ,
88
78
},
89
79
"instance_name" : {
90
80
Type : schema .TypeString ,
@@ -165,39 +155,29 @@ func resourceDdsBackupCreate(ctx context.Context, d *schema.ResourceData, meta i
165
155
166
156
createBackupOpt := golangsdk.RequestOpts {
167
157
KeepResponseBody : true ,
168
- OkCodes : []int {
169
- 200 ,
170
- },
171
158
}
172
159
createBackupOpt .JSONBody = utils .RemoveNil (buildCreateBackupBodyParams (d ))
173
160
174
- var createBackupResp * http.Response
175
161
instanceId := d .Get ("instance_id" ).(string )
176
- for {
177
- createBackupResp , err = createBackupClient .Request ("POST" , createBackupPath , & createBackupOpt )
178
- if err == nil {
179
- break
180
- }
181
- // if the HTTP response code is 403 and the error code is DBS.201015 or DBS.201014, then it indicates that other
182
- // operation is being executed and need to wait
183
- if errCode , ok := err .(golangsdk.ErrDefault403 ); ok {
184
- var backupErr backupError
185
- err = json .Unmarshal (errCode .Body , & backupErr )
186
- if err != nil {
187
- return diag .Errorf ("error creating DDS backup: error format error: %s" , err )
188
- }
189
- if backupErr .ErrorCode == "DBS.201014" || backupErr .ErrorCode == "DBS.201015" {
190
- err = waitForInstanceRunning (ctx , d , cfg , region , instanceId , schema .TimeoutCreate )
191
- if err != nil {
192
- return diag .FromErr (err )
193
- }
194
- continue
195
- }
196
- }
197
- return diag .Errorf ("error creating DDS Backup: %s" , err )
162
+ retryFunc := func () (interface {}, bool , error ) {
163
+ resp , err := createBackupClient .Request ("POST" , createBackupPath , & createBackupOpt )
164
+ retry , err := handleMultiOperationsError (err )
165
+ return resp , retry , err
166
+ }
167
+ r , err := common .RetryContextWithWaitForState (& common.RetryContextWithWaitForStateParam {
168
+ Ctx : ctx ,
169
+ RetryFunc : retryFunc ,
170
+ WaitFunc : ddsInstanceStateRefreshFunc (createBackupClient , instanceId ),
171
+ WaitTarget : []string {"normal" },
172
+ Timeout : d .Timeout (schema .TimeoutCreate ),
173
+ DelayTimeout : 10 * time .Second ,
174
+ PollInterval : 10 * time .Second ,
175
+ })
176
+ if err != nil {
177
+ return diag .Errorf ("error creating DDS backup: %s" , err )
198
178
}
199
179
200
- createBackupRespBody , err := utils .FlattenResponse (createBackupResp )
180
+ createBackupRespBody , err := utils .FlattenResponse (r .( * http. Response ) )
201
181
if err != nil {
202
182
return diag .FromErr (err )
203
183
}
@@ -219,7 +199,7 @@ func resourceDdsBackupCreate(ctx context.Context, d *schema.ResourceData, meta i
219
199
Target : []string {"Completed" },
220
200
Refresh : ddsJobStatusRefreshFunc (jobId .(string ), region , cfg ),
221
201
Timeout : d .Timeout (schema .TimeoutCreate ),
222
- Delay : 60 * time .Second ,
202
+ Delay : 10 * time .Second ,
223
203
PollInterval : 10 * time .Second ,
224
204
}
225
205
@@ -243,66 +223,6 @@ func buildCreateBackupBodyParams(d *schema.ResourceData) map[string]interface{}
243
223
return params
244
224
}
245
225
246
- func waitForInstanceRunning (ctx context.Context , d * schema.ResourceData , cfg * config.Config , region , instanceID ,
247
- timeout string ) error {
248
- stateConf := & resource.StateChangeConf {
249
- Pending : []string {"PENDING" },
250
- Target : []string {"RUNNING" },
251
- Refresh : ddsInstanceStatusRefreshFunc (instanceID , region , cfg ),
252
- Timeout : d .Timeout (timeout ),
253
- PollInterval : 5 * time .Second ,
254
- }
255
-
256
- _ , err := stateConf .WaitForStateContext (ctx )
257
- if err != nil {
258
- return fmt .Errorf ("error waiting for instance (%s) to running: %s" , instanceID , err )
259
- }
260
- return nil
261
- }
262
-
263
- func ddsInstanceStatusRefreshFunc (instanceId , region string , cfg * config.Config ) resource.StateRefreshFunc {
264
- return func () (interface {}, string , error ) {
265
- var (
266
- getInstanceHttpUrl = "v3/{project_id}/instances"
267
- getInstanceProduct = "dds"
268
- )
269
- getInstanceClient , err := cfg .NewServiceClient (getInstanceProduct , region )
270
- if err != nil {
271
- return nil , "" , fmt .Errorf ("error creating DDS client: %s" , err )
272
- }
273
-
274
- getInstancePath := getInstanceClient .Endpoint + getInstanceHttpUrl
275
- getInstancePath = strings .ReplaceAll (getInstancePath , "{project_id}" , getInstanceClient .ProjectID )
276
-
277
- getInstancePath += buildGetInstanceQueryParams (instanceId )
278
- getInstanceOpt := golangsdk.RequestOpts {
279
- KeepResponseBody : true ,
280
- OkCodes : []int {
281
- 200 ,
282
- },
283
- }
284
-
285
- getInstanceResp , err := getInstanceClient .Request ("GET" , getInstancePath , & getInstanceOpt )
286
- if err != nil {
287
- return nil , "" , err
288
- }
289
-
290
- getInstanceRespBody , err := utils .FlattenResponse (getInstanceResp )
291
- if err != nil {
292
- return nil , "" , err
293
- }
294
- instances := utils .PathSearch ("instances" , getInstanceRespBody , make ([]interface {}, 0 ))
295
- if len (instances .([]interface {})) == 0 {
296
- return nil , "" , fmt .Errorf ("can not get instance by instance ID %s" , instanceId )
297
- }
298
- actions := utils .PathSearch ("actions" , instances .([]interface {})[0 ], make ([]interface {}, 0 ))
299
- if len (actions .([]interface {})) == 0 {
300
- return getInstanceRespBody , "RUNNING" , nil
301
- }
302
- return getInstanceRespBody , "PENDING" , nil
303
- }
304
- }
305
-
306
226
func ddsJobStatusRefreshFunc (jobId , region string , cfg * config.Config ) resource.StateRefreshFunc {
307
227
return func () (interface {}, string , error ) {
308
228
var (
@@ -322,9 +242,6 @@ func ddsJobStatusRefreshFunc(jobId, region string, cfg *config.Config) resource.
322
242
323
243
getJobStatusOpt := golangsdk.RequestOpts {
324
244
KeepResponseBody : true ,
325
- OkCodes : []int {
326
- 200 ,
327
- },
328
245
}
329
246
getJobStatusResp , err := getJobStatusClient .Request ("GET" , getJobStatusPath , & getJobStatusOpt )
330
247
@@ -385,9 +302,6 @@ func resourceDdsBackupRead(_ context.Context, d *schema.ResourceData, meta inter
385
302
386
303
getBackupOpt := golangsdk.RequestOpts {
387
304
KeepResponseBody : true ,
388
- OkCodes : []int {
389
- 200 ,
390
- },
391
305
}
392
306
getBackupResp , err := getBackupClient .Request ("GET" , getBackupPath , & getBackupOpt )
393
307
@@ -481,38 +395,28 @@ func resourceDdsBackupDelete(ctx context.Context, d *schema.ResourceData, meta i
481
395
482
396
deleteBackupOpt := golangsdk.RequestOpts {
483
397
KeepResponseBody : true ,
484
- OkCodes : []int {
485
- 200 ,
486
- },
487
398
}
488
399
489
- var deleteBackupResp * http.Response
490
400
instanceId := d .Get ("instance_id" ).(string )
491
- for {
492
- deleteBackupResp , err = deleteBackupClient .Request ("DELETE" , deleteBackupPath , & deleteBackupOpt )
493
- if err == nil {
494
- break
495
- }
496
- // if the HTTP response code is 403 and the error code is DBS.201208, then it indicates the backup
497
- // is in the state of backup and need to wait
498
- if errCode , ok := err .(golangsdk.ErrDefault403 ); ok {
499
- var backupErr backupError
500
- err = json .Unmarshal (errCode .Body , & backupErr )
501
- if err != nil {
502
- return diag .Errorf ("error deleting DDS backup: error format error: %s" , err )
503
- }
504
- if backupErr .ErrorCode == "DBS.201208" {
505
- err = waitForInstanceRunning (ctx , d , cfg , region , instanceId , schema .TimeoutDelete )
506
- if err != nil {
507
- return diag .FromErr (err )
508
- }
509
- continue
510
- }
511
- }
401
+ retryFunc := func () (interface {}, bool , error ) {
402
+ resp , err := deleteBackupClient .Request ("DELETE" , deleteBackupPath , & deleteBackupOpt )
403
+ retry , err := handleMultiOperationsError (err )
404
+ return resp , retry , err
405
+ }
406
+ r , err := common .RetryContextWithWaitForState (& common.RetryContextWithWaitForStateParam {
407
+ Ctx : ctx ,
408
+ RetryFunc : retryFunc ,
409
+ WaitFunc : ddsInstanceStateRefreshFunc (deleteBackupClient , instanceId ),
410
+ WaitTarget : []string {"normal" },
411
+ Timeout : d .Timeout (schema .TimeoutCreate ),
412
+ DelayTimeout : 10 * time .Second ,
413
+ PollInterval : 10 * time .Second ,
414
+ })
415
+ if err != nil {
512
416
return diag .Errorf ("error deleting DDS Backup: %s" , err )
513
417
}
514
418
515
- deleteBackupRespBody , err := utils .FlattenResponse (deleteBackupResp )
419
+ deleteBackupRespBody , err := utils .FlattenResponse (r .( * http. Response ) )
516
420
if err != nil {
517
421
return diag .FromErr (err )
518
422
}
0 commit comments