Skip to content

Commit 0087d44

Browse files
authored
fix: support window switch (#2429)
* fix: support window seitch * support wait switch * feat: add 2429 changelog * fix: modify switch
1 parent 9c97289 commit 0087d44

File tree

8 files changed

+160
-48
lines changed

8 files changed

+160
-48
lines changed

.changelog/2429.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```release-note:enhancement
2+
tencentcloud_mysql_instance: Support upgrade switching during window period
3+
```
4+
5+
```release-note:enhancement
6+
tencentcloud_redis_instance: Support upgrade switching during window period
7+
```
8+
9+
```release-note:enhancement
10+
tencentcloud_mysql_readonly_instance: Fix read-only instance `slave_deploy_mode` problem
11+
```

tencentcloud/services/cdb/resource_tc_mysql_instance.go

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222

2323
var importMysqlFlag = false
2424

25+
const InWindow = 1
26+
2527
func TencentMsyqlBasicInfo() map[string]*schema.Schema {
2628
return map[string]*schema.Schema{
2729
"instance_name": {
@@ -166,6 +168,11 @@ func TencentMsyqlBasicInfo() map[string]*schema.Schema {
166168
Default: false,
167169
Description: "Indicate whether to delete instance directly or not. Default is `false`. If set true, the instance will be deleted instead of staying recycle bin. Note: only works for `PREPAID` instance. When the main mysql instance set true, this para of the readonly mysql instance will not take effect.",
168170
},
171+
"wait_switch": {
172+
Type: schema.TypeInt,
173+
Optional: true,
174+
Description: "Switch the method of accessing new instances, default is `0`. Supported values include: `0` - switch immediately, `1` - switch in time window.",
175+
},
169176
// Computed values
170177
"intranet_ip": {
171178
Type: schema.TypeString,
@@ -1149,6 +1156,7 @@ func mysqlAllInstanceRoleUpdate(ctx context.Context, d *schema.ResourceData, met
11491156
engineVersion := ""
11501157
var upgradeSubversion int64
11511158
var maxDelayTime int64
1159+
var waitSwitch int64 = 0
11521160
if v, ok := d.GetOk("engine_version"); ok {
11531161
engineVersion = v.(string)
11541162
}
@@ -1158,37 +1166,65 @@ func mysqlAllInstanceRoleUpdate(ctx context.Context, d *schema.ResourceData, met
11581166
if v, ok := d.GetOk("max_deay_time"); ok {
11591167
maxDelayTime = int64(v.(int))
11601168
}
1169+
if v, ok := d.GetOkExists("wait_switch"); ok {
1170+
waitSwitch = int64(v.(int))
1171+
}
11611172

1162-
asyncRequestId, err := mysqlService.UpgradeDBInstanceEngineVersion(ctx, d.Id(), engineVersion, upgradeSubversion, maxDelayTime)
1173+
asyncRequestId, err := mysqlService.UpgradeDBInstanceEngineVersion(ctx, d.Id(), engineVersion, upgradeSubversion, maxDelayTime, waitSwitch)
11631174
if err != nil {
11641175
return err
11651176
}
11661177

1167-
err = resource.Retry(6*time.Hour, func() *resource.RetryError {
1168-
taskStatus, message, err := mysqlService.DescribeAsyncRequestInfo(ctx, asyncRequestId)
1178+
if waitSwitch != InWindow {
1179+
err = resource.Retry(6*time.Hour, func() *resource.RetryError {
1180+
taskStatus, message, err := mysqlService.DescribeAsyncRequestInfo(ctx, asyncRequestId)
11691181

1170-
if err != nil {
1171-
if _, ok := err.(*errors.TencentCloudSDKError); !ok {
1172-
return resource.RetryableError(err)
1173-
} else {
1174-
return resource.NonRetryableError(err)
1182+
if err != nil {
1183+
if _, ok := err.(*errors.TencentCloudSDKError); !ok {
1184+
return resource.RetryableError(err)
1185+
} else {
1186+
return resource.NonRetryableError(err)
1187+
}
11751188
}
1176-
}
11771189

1178-
if taskStatus == MYSQL_TASK_STATUS_SUCCESS {
1179-
return nil
1190+
if taskStatus == MYSQL_TASK_STATUS_SUCCESS {
1191+
return nil
1192+
}
1193+
if taskStatus == MYSQL_TASK_STATUS_INITIAL || taskStatus == MYSQL_TASK_STATUS_RUNNING {
1194+
return resource.RetryableError(fmt.Errorf("update mysql engineVersion status is %s", taskStatus))
1195+
}
1196+
err = fmt.Errorf("update mysql engineVersion task status is %s,we won't wait for it finish ,it show message:%s",
1197+
",", message)
1198+
return resource.NonRetryableError(err)
1199+
})
1200+
1201+
if err != nil {
1202+
log.Printf("[CRITAL]%s update mysql engineVersion fail, reason:%s\n ", logId, err.Error())
1203+
return err
11801204
}
1181-
if taskStatus == MYSQL_TASK_STATUS_INITIAL || taskStatus == MYSQL_TASK_STATUS_RUNNING {
1182-
return resource.RetryableError(fmt.Errorf("update mysql engineVersion status is %s", taskStatus))
1205+
} else {
1206+
err = resource.Retry(6*time.Hour, func() *resource.RetryError {
1207+
mysqlInfo, err := mysqlService.DescribeDBInstanceById(ctx, d.Id())
1208+
1209+
if err != nil {
1210+
if _, ok := err.(*errors.TencentCloudSDKError); !ok {
1211+
return resource.RetryableError(err)
1212+
} else {
1213+
return resource.NonRetryableError(err)
1214+
}
1215+
}
1216+
1217+
if *mysqlInfo.TaskStatus == 15 {
1218+
return nil
1219+
}
1220+
return resource.RetryableError(fmt.Errorf("update mysql engineVersion task status is %v", mysqlInfo.TaskStatus))
1221+
})
1222+
1223+
if err != nil {
1224+
log.Printf("[CRITAL]%s update mysql engineVersion fail, reason:%s\n ", logId, err.Error())
1225+
return err
11831226
}
1184-
err = fmt.Errorf("update mysql engineVersion task status is %s,we won't wait for it finish ,it show message:%s",
1185-
",", message)
1186-
return resource.NonRetryableError(err)
1187-
})
11881227

1189-
if err != nil {
1190-
log.Printf("[CRITAL]%s update mysql engineVersion fail, reason:%s\n ", logId, err.Error())
1191-
return err
11921228
}
11931229
}
11941230

tencentcloud/services/cdb/resource_tc_mysql_readonly_instance.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ func ResourceTencentCloudMysqlReadonlyInstance() *schema.Resource {
3535
Optional: true,
3636
Description: "The zone information of the primary instance is required when you purchase a disaster recovery instance.",
3737
},
38+
"slave_deploy_mode": {
39+
Type: schema.TypeInt,
40+
Optional: true,
41+
ValidateFunc: tccommon.ValidateAllowedIntValue([]int{0, 1}),
42+
Default: 0,
43+
Description: "Availability zone deployment method. Available values: 0 - Single availability zone; 1 - Multiple availability zones.",
44+
},
3845
}
3946

4047
basic := TencentMsyqlBasicInfo()

tencentcloud/services/cdb/service_tencentcloud_mysql.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,15 @@ func (me *MysqlService) ModifyAccountMaxUserConnections(ctx context.Context, mys
411411
return
412412
}
413413

414-
func (me *MysqlService) UpgradeDBInstanceEngineVersion(ctx context.Context, mysqlId, engineVersion string, upgradeSubversion, maxDelayTime int64) (asyncRequestId string, errRet error) {
414+
func (me *MysqlService) UpgradeDBInstanceEngineVersion(ctx context.Context, mysqlId, engineVersion string, upgradeSubversion, maxDelayTime, waitSwitch int64) (asyncRequestId string, errRet error) {
415415

416416
logId := tccommon.GetLogId(ctx)
417417

418418
request := cdb.NewUpgradeDBInstanceEngineVersionRequest()
419419

420-
var waitSwitch int64 = 0 // 0- switch immediately, 1- time window switch
421-
422420
request.InstanceId = &mysqlId
423421
request.EngineVersion = &engineVersion
422+
// 0- switch immediately, 1- time window switch
424423
request.WaitSwitch = &waitSwitch
425424
request.UpgradeSubversion = &upgradeSubversion
426425
request.MaxDelayTime = &maxDelayTime

tencentcloud/services/crs/resource_tc_redis_instance.go

Lines changed: 80 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sort"
88
"strconv"
99
"strings"
10+
"time"
1011

1112
tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common"
1213
svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag"
@@ -182,6 +183,12 @@ func ResourceTencentCloudRedisInstance() *schema.Resource {
182183
Description: "IP address of an instance. When the `operation_network` is `changeVip`, this parameter needs to be configured.",
183184
},
184185

186+
"wait_switch": {
187+
Type: schema.TypeInt,
188+
Optional: true,
189+
Description: "Switching mode: `1`-maintenance time window switching, `2`-immediate switching, default value `2`.",
190+
},
191+
185192
"tags": {
186193
Type: schema.TypeMap,
187194
Optional: true,
@@ -500,37 +507,45 @@ func resourceTencentCloudRedisInstanceRead(d *schema.ResourceData, meta interfac
500507
info *redis.InstanceSet
501508
e error
502509
)
503-
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
504-
has, _, info, e = service.CheckRedisOnlineOk(ctx, d.Id(), tccommon.ReadRetryTimeout*20)
505-
if info != nil {
506-
if *info.Status == REDIS_STATUS_ISOLATE || *info.Status == REDIS_STATUS_TODELETE {
510+
511+
if v, ok := d.GetOkExists("wait_switch"); ok && v.(int) == 1 {
512+
info, e = service.DescribeRedisInstanceById(ctx, d.Id())
513+
if e != nil {
514+
return e
515+
}
516+
} else {
517+
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
518+
has, _, info, e = service.CheckRedisOnlineOk(ctx, d.Id(), tccommon.ReadRetryTimeout*20)
519+
if info != nil {
520+
if *info.Status == REDIS_STATUS_ISOLATE || *info.Status == REDIS_STATUS_TODELETE {
521+
d.SetId("")
522+
onlineHas = false
523+
return nil
524+
}
525+
}
526+
if e != nil {
527+
return resource.NonRetryableError(e)
528+
}
529+
if !has {
507530
d.SetId("")
508531
onlineHas = false
509532
return nil
510533
}
534+
return nil
535+
})
536+
if err != nil {
537+
//internal version: replace redisFail begin, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation.
538+
return fmt.Errorf("Fail to get info from redis, reaseon %s", err.Error())
539+
//internal version: replace redisFail end, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation.
511540
}
512-
if e != nil {
513-
return resource.NonRetryableError(e)
514-
}
515-
if !has {
516-
d.SetId("")
517-
onlineHas = false
541+
if !onlineHas {
518542
return nil
519543
}
520-
return nil
521-
})
522-
if err != nil {
523-
//internal version: replace redisFail begin, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation.
524-
return fmt.Errorf("Fail to get info from redis, reaseon %s", err.Error())
525-
//internal version: replace redisFail end, please do not modify this annotation and refrain from inserting any code between the beginning and end lines of the annotation.
526-
}
527-
if !onlineHas {
528-
return nil
529544
}
530545

531546
statusName := REDIS_STATUS[*info.Status]
532547
if statusName == "" {
533-
err = fmt.Errorf("redis read unkwnow status %d", *info.Status)
548+
err := fmt.Errorf("redis read unkwnow status %d", *info.Status)
534549
log.Printf("[CRITAL]%s redis read status name error, reason:%s\n", logId, err.Error())
535550
return err
536551
}
@@ -829,7 +844,13 @@ func resourceTencentCloudRedisInstanceUpdate(d *schema.ResourceData, meta interf
829844
typeId := d.Get("type_id").(int)
830845
request.InstanceId = &id
831846
request.TargetInstanceType = helper.String(strconv.Itoa(typeId))
832-
request.SwitchOption = helper.IntInt64(2)
847+
waitSwitch := 2
848+
if v, ok := d.GetOkExists("wait_switch"); ok {
849+
waitSwitch = v.(int)
850+
}
851+
852+
request.SwitchOption = helper.IntInt64(waitSwitch)
853+
startTime := time.Now().Format("2006-01-02 15:04:05")
833854
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
834855
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseRedisClient().UpgradeInstanceVersion(request)
835856
if e != nil {
@@ -845,11 +866,45 @@ func resourceTencentCloudRedisInstanceUpdate(d *schema.ResourceData, meta interf
845866
}
846867

847868
service := RedisService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
848-
_, _, _, err = service.CheckRedisOnlineOk(ctx, id, 20*tccommon.ReadRetryTimeout)
849-
if err != nil {
850-
log.Printf("[CRITAL]%s redis upgradeVersionOperation fail, reason:%s\n", logId, err.Error())
851-
return err
869+
if waitSwitch == 2 {
870+
_, _, _, err = service.CheckRedisOnlineOk(ctx, id, 20*tccommon.ReadRetryTimeout)
871+
if err != nil {
872+
log.Printf("[CRITAL]%s redis upgradeVersionOperation fail, reason:%s\n", logId, err.Error())
873+
return err
874+
}
875+
} else {
876+
time.Sleep(10 * time.Second)
877+
paramMap := make(map[string]interface{})
878+
paramMap["InstanceId"] = &id
879+
paramMap["BeginTime"] = &startTime
880+
paramMap["TaskTypes"] = helper.StringsStringsPoint([]string{"043"})
881+
err := resource.Retry(5*tccommon.WriteRetryTimeout, func() *resource.RetryError {
882+
result, e := service.DescribeRedisInstanceTaskListByFilter(ctx, paramMap)
883+
if e != nil {
884+
return tccommon.RetryError(e)
885+
}
886+
if result == nil || len(result) < 1 {
887+
return resource.RetryableError(fmt.Errorf("redis upgradeVersion fail, result is nil"))
888+
}
889+
for _, v := range result {
890+
if *v.Result == 0 || *v.Result == 1 {
891+
return resource.RetryableError(fmt.Errorf("redis upgradeVersion state is %v, retry...", *v.Result))
892+
}
893+
if *v.Result == 4 {
894+
return resource.NonRetryableError(fmt.Errorf("redis upgradeVersion fail, task status is %v", *v.Result))
895+
}
896+
if *v.Result == 2 {
897+
return nil
898+
}
899+
}
900+
return resource.RetryableError(fmt.Errorf("redis upgradeVersion fail, retry..."))
901+
})
902+
if err != nil {
903+
log.Printf("[CRITAL]%s redis upgradeVersion failed, reason:%+v", logId, err)
904+
return err
905+
}
852906
}
907+
853908
}
854909

855910
if d.HasChange("vpc_id") || d.HasChange("subnet_id") || d.HasChange("port") || d.HasChange("recycle") || d.HasChange("ip") {

website/docs/r/mysql_instance.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ The following arguments are supported:
166166
* `tags` - (Optional, Map) Instance tags.
167167
* `upgrade_subversion` - (Optional, Int) Whether it is a kernel subversion upgrade, supported values: 1 - upgrade the kernel subversion; 0 - upgrade the database engine version. Only need to fill in when upgrading kernel subversion and engine version.
168168
* `vpc_id` - (Optional, String) ID of VPC, which can be modified once every 24 hours and can't be removed.
169+
* `wait_switch` - (Optional, Int) Switch the method of accessing new instances, default is `0`. Supported values include: `0` - switch immediately, `1` - switch in time window.
169170

170171
## Attributes Reference
171172

website/docs/r/mysql_readonly_instance.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ The following arguments are supported:
102102
* `period` - (Optional, Int, **Deprecated**) It has been deprecated from version 1.36.0. Please use `prepaid_period` instead. Period of instance. NOTES: Only supported prepaid instance.
103103
* `prepaid_period` - (Optional, Int) Period of instance. NOTES: Only supported prepaid instance.
104104
* `security_groups` - (Optional, Set: [`String`]) Security groups to use.
105+
* `slave_deploy_mode` - (Optional, Int) Availability zone deployment method. Available values: 0 - Single availability zone; 1 - Multiple availability zones.
105106
* `subnet_id` - (Optional, String) Private network ID. If `vpc_id` is set, this value is required.
106107
* `tags` - (Optional, Map) Instance tags.
107108
* `vpc_id` - (Optional, String) ID of VPC, which can be modified once every 24 hours and can't be removed.
109+
* `wait_switch` - (Optional, Int) Switch the method of accessing new instances, default is `0`. Supported values include: `0` - switch immediately, `1` - switch in time window.
108110
* `zone` - (Optional, String) Zone information, this parameter defaults to, the system automatically selects an Availability Zone.
109111

110112
## Attributes Reference

website/docs/r/redis_instance.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ The following arguments are supported:
263263
* `type_id` - (Optional, Int) Instance type. Available values reference data source `tencentcloud_redis_zone_config` or [document](https://intl.cloud.tencent.com/document/product/239/32069), toggle immediately when modified.
264264
* `type` - (Optional, String, ForceNew, **Deprecated**) It has been deprecated from version 1.33.1. Please use 'type_id' instead. Instance type. Available values: `cluster_ckv`,`cluster_redis5.0`,`cluster_redis`,`master_slave_ckv`,`master_slave_redis4.0`,`master_slave_redis5.0`,`master_slave_redis`,`standalone_redis`, specific region support specific types, need to refer data `tencentcloud_redis_zone_config`.
265265
* `vpc_id` - (Optional, String) ID of the vpc with which the instance is to be associated. When the `operation_network` is `changeVpc` or `changeBaseToVpc`, this parameter needs to be configured.
266+
* `wait_switch` - (Optional, Int) Switching mode: `1`-maintenance time window switching, `2`-immediate switching, default value `2`.
266267

267268
## Attributes Reference
268269

0 commit comments

Comments
 (0)