Skip to content

Commit

Permalink
resource/alicloud_kvstore_backup_policy: Added retry strategy for err…
Browse files Browse the repository at this point in the history
…or code IncorrectDBInstanceState, LockTimeout
  • Loading branch information
MrWolong committed Dec 16, 2024
1 parent 31c36a2 commit c8f3f96
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 252 deletions.
2 changes: 1 addition & 1 deletion alicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ func Provider() terraform.ResourceProvider {
"alicloud_cen_transit_router_vbr_attachment": resourceAliCloudCenTransitRouterVbrAttachment(),
"alicloud_cen_transit_router_vpc_attachment": resourceAliCloudCenTransitRouterVpcAttachment(),
"alicloud_kvstore_instance": resourceAliCloudKvstoreInstance(),
"alicloud_kvstore_backup_policy": resourceAlicloudKVStoreBackupPolicy(),
"alicloud_kvstore_backup_policy": resourceAliCloudKvStoreBackupPolicy(),
"alicloud_kvstore_account": resourceAlicloudKvstoreAccount(),
"alicloud_datahub_project": resourceAlicloudDatahubProject(),
"alicloud_datahub_subscription": resourceAlicloudDatahubSubscription(),
Expand Down
87 changes: 59 additions & 28 deletions alicloud/resource_alicloud_kvstore_backup_policy.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package alicloud

import (
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/validation"

r_kvstore "github.com/aliyun/alibaba-cloud-sdk-go/services/r-kvstore"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAlicloudKVStoreBackupPolicy() *schema.Resource {
func resourceAliCloudKvStoreBackupPolicy() *schema.Resource {
return &schema.Resource{
Create: resourceAlicloudKVStoreBackupPolicyCreate,
Read: resourceAlicloudKVStoreBackupPolicyRead,
Update: resourceAlicloudKVStoreBackupPolicyUpdate,
Delete: resourceAlicloudKVStoreBackupPolicyDelete,
Create: resourceAliCloudKvStoreBackupPolicyCreate,
Read: resourceAliCloudKvStoreBackupPolicyRead,
Update: resourceAliCloudKvStoreBackupPolicyUpdate,
Delete: resourceAliCloudKvStoreBackupPolicyDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Expand All @@ -31,36 +30,36 @@ func resourceAlicloudKVStoreBackupPolicy() *schema.Resource {
},
"backup_time": {
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(BACKUP_TIME, false),
Optional: true,
Default: "02:00Z-03:00Z",
ValidateFunc: StringInSlice(BACKUP_TIME, false),
},
"backup_period": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
// terraform does not support ValidateFunc of TypeList attr
// ValidateFunc: validateAllowedStringValue([]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}),
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func resourceAlicloudKVStoreBackupPolicyCreate(d *schema.ResourceData, meta interface{}) error {
func resourceAliCloudKvStoreBackupPolicyCreate(d *schema.ResourceData, meta interface{}) error {

d.SetId(d.Get("instance_id").(string))

return resourceAlicloudKVStoreBackupPolicyUpdate(d, meta)
return resourceAliCloudKvStoreBackupPolicyUpdate(d, meta)
}

func resourceAlicloudKVStoreBackupPolicyRead(d *schema.ResourceData, meta interface{}) error {
func resourceAliCloudKvStoreBackupPolicyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
kvstoreService := KvstoreService{client}

object, err := kvstoreService.DescribeKVstoreBackupPolicy(d.Id())
if err != nil {
if NotFoundError(err) {
if !d.IsNewResource() && NotFoundError(err) {
d.SetId("")
return nil
}
Expand All @@ -74,62 +73,94 @@ func resourceAlicloudKVStoreBackupPolicyRead(d *schema.ResourceData, meta interf
return nil
}

func resourceAlicloudKVStoreBackupPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
func resourceAliCloudKvStoreBackupPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
r_kvstoreService := R_kvstoreService{client}
if d.HasChange("backup_time") || d.HasChange("backup_period") {
client := meta.(*connectivity.AliyunClient)
kvstoreService := KvstoreService{client}
kvstoreService := KvstoreService{client}

if d.HasChange("backup_time") || d.HasChange("backup_period") {
request := r_kvstore.CreateModifyBackupPolicyRequest()
request.RegionId = client.RegionId
request.InstanceId = d.Id()
request.PreferredBackupTime = d.Get("backup_time").(string)
periodList := expandStringList(d.Get("backup_period").(*schema.Set).List())
request.PreferredBackupPeriod = strings.Join(periodList, COMMA_SEPARATED)

raw, err := client.WithRKvstoreClient(func(rkvClient *r_kvstore.Client) (interface{}, error) {
return rkvClient.ModifyBackupPolicy(request)
request.PreferredBackupTime = d.Get("backup_time").(string)
request.PreferredBackupPeriod = convertListToCommaSeparate(d.Get("backup_period").(*schema.Set).List())

var raw interface{}
var err error
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError {
raw, err = client.WithRKvstoreClient(func(rkvClient *r_kvstore.Client) (interface{}, error) {
return rkvClient.ModifyBackupPolicy(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"IncorrectDBInstanceState"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(request.GetActionName(), raw, request.RpcRequest, request)

if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)

stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}

// There is a random error and need waiting some seconds to ensure the update is success
_, err = kvstoreService.DescribeKVstoreBackupPolicy(d.Id())
if err != nil {
return WrapError(err)
}
}

return resourceAlicloudKVStoreBackupPolicyRead(d, meta)
return resourceAliCloudKvStoreBackupPolicyRead(d, meta)
}

func resourceAlicloudKVStoreBackupPolicyDelete(d *schema.ResourceData, meta interface{}) error {
func resourceAliCloudKvStoreBackupPolicyDelete(d *schema.ResourceData, meta interface{}) error {
// In case of a delete we are resetting to default values which is Monday - Sunday each 3am-4am
client := meta.(*connectivity.AliyunClient)
r_kvstoreService := R_kvstoreService{client}

request := r_kvstore.CreateModifyBackupPolicyRequest()
request.RegionId = client.RegionId
request.InstanceId = d.Id()

request.PreferredBackupTime = "01:00Z-02:00Z"
request.PreferredBackupPeriod = "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"

raw, err := client.WithRKvstoreClient(func(rkvClient *r_kvstore.Client) (interface{}, error) {
return rkvClient.ModifyBackupPolicy(request)
var raw interface{}
var err error
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError {
raw, err = client.WithRKvstoreClient(func(rkvClient *r_kvstore.Client) (interface{}, error) {
return rkvClient.ModifyBackupPolicy(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"IncorrectDBInstanceState"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(request.GetActionName(), raw, request.RpcRequest, request)

if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)

stateConf := BuildStateConf([]string{}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, r_kvstoreService.KvstoreInstanceStateRefreshFunc(d.Id(), []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}

return nil
}
Loading

0 comments on commit c8f3f96

Please sign in to comment.