From 69d3f45968059638a4ce0aa104c106e582e686da Mon Sep 17 00:00:00 2001 From: arunma Date: Tue, 23 Apr 2024 10:03:40 +0800 Subject: [PATCH 1/3] feat(cdb): [117110222]support cdb dr --- tencentcloud/provider.go | 1 + tencentcloud/provider.md | 1 + .../cdb/resource_tc_mysql_dr_instance.go | 776 ++++++++++++++++++ .../cdb/resource_tc_mysql_dr_instance.md | 77 ++ .../cdb/resource_tc_mysql_dr_instance_test.go | 125 +++ .../cdb/resource_tc_mysql_instance_test.go | 6 +- .../docs/r/mysql_dr_instance.html.markdown | 127 +++ website/tencentcloud.erb | 3 + 8 files changed, 1113 insertions(+), 3 deletions(-) create mode 100644 tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go create mode 100644 tencentcloud/services/cdb/resource_tc_mysql_dr_instance.md create mode 100644 tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go create mode 100644 website/docs/r/mysql_dr_instance.html.markdown diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 0fe00be2c6..30a35eba3c 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -1130,6 +1130,7 @@ func Provider() *schema.Provider { "tencentcloud_mysql_instance": cdb.ResourceTencentCloudMysqlInstance(), "tencentcloud_mysql_database": cdb.ResourceTencentCloudMysqlDatabase(), "tencentcloud_mysql_readonly_instance": cdb.ResourceTencentCloudMysqlReadonlyInstance(), + "tencentcloud_mysql_dr_instance": cdb.ResourceTencentCloudMysqlDrInstance(), "tencentcloud_mysql_time_window": cdb.ResourceTencentCloudMysqlTimeWindow(), "tencentcloud_mysql_param_template": cdb.ResourceTencentCloudMysqlParamTemplate(), "tencentcloud_mysql_security_groups_attachment": cdb.ResourceTencentCloudMysqlSecurityGroupsAttachment(), diff --git a/tencentcloud/provider.md b/tencentcloud/provider.md index dc3f36b513..783feadc18 100644 --- a/tencentcloud/provider.md +++ b/tencentcloud/provider.md @@ -770,6 +770,7 @@ TencentDB for MySQL(cdb) tencentcloud_mysql_ro_start_replication tencentcloud_mysql_ro_stop_replication tencentcloud_mysql_isolate_instance + tencentcloud_mysql_dr_instance Cloud Monitor(Monitor) Data Source diff --git a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go new file mode 100644 index 0000000000..e816e414a8 --- /dev/null +++ b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go @@ -0,0 +1,776 @@ +package cdb + +import ( + "context" + "fmt" + "log" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + cdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb/v20170320" + sdkError "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudMysqlDrInstance() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudMysqlDrInstanceCreate, + Read: resourceTencentCloudMysqlDrInstanceRead, + Update: resourceTencentCloudMysqlDrInstanceUpdate, + Delete: resourceTencentCloudMysqlDrInstanceDelete, + Importer: &schema.ResourceImporter{ + State: helper.ImportWithDefaultValue(map[string]interface{}{ + "prepaid_period": 1, + "force_delete": false, + }), + }, + Schema: map[string]*schema.Schema{ + "master_instance_id": { + Type: schema.TypeString, + Required: true, + Description: "Indicates the master instance ID of recovery instances.", + }, + "master_region": { + Type: schema.TypeString, + Required: true, + Description: "The zone information of the primary instance is required when you purchase a disaster recovery instance.", + }, + "instance_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: tccommon.ValidateStringLengthInRange(1, 100), + Description: "The name of a mysql instance.", + }, + "pay_type": { + Type: schema.TypeInt, + Deprecated: "It has been deprecated from version 1.36.0. Please use `charge_type` instead.", + Optional: true, + ValidateFunc: tccommon.ValidateAllowedIntValue([]int{MysqlPayByMonth, MysqlPayByUse}), + ConflictsWith: []string{"charge_type", "prepaid_period"}, + DiffSuppressFunc: func(k, olds, news string, d *schema.ResourceData) bool { + return true + }, + Default: -1, + Description: "Pay type of instance. Valid values: `0`, `1`. `0`: prepaid, `1`: postpaid.", + }, + "charge_type": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + ValidateFunc: tccommon.ValidateAllowedStringValue([]string{MYSQL_CHARGE_TYPE_PREPAID, MYSQL_CHARGE_TYPE_POSTPAID}), + ConflictsWith: []string{"pay_type", "period"}, + Default: MYSQL_CHARGE_TYPE_POSTPAID, + DiffSuppressFunc: func(k, olds, news string, d *schema.ResourceData) bool { + if (olds == "" && news == MYSQL_CHARGE_TYPE_POSTPAID) || + (olds == MYSQL_CHARGE_TYPE_POSTPAID && news == "") { + if v, ok := d.GetOkExists("pay_type"); ok && v.(int) == MysqlPayByUse { + return true + } + } else if (olds == "" && news == MYSQL_CHARGE_TYPE_PREPAID) || + (olds == MYSQL_CHARGE_TYPE_PREPAID && news == "") { + if v, ok := d.GetOkExists("pay_type"); ok && v.(int) == MysqlPayByMonth { + return true + } + } + return olds == news + }, + Description: "Pay type of instance. Valid values:`PREPAID`, `POSTPAID`. Default is `POSTPAID`.", + }, + "period": { + Type: schema.TypeInt, + Deprecated: "It has been deprecated from version 1.36.0. Please use `prepaid_period` instead.", + Optional: true, + Default: -1, + ConflictsWith: []string{"charge_type", "prepaid_period"}, + ValidateFunc: tccommon.ValidateAllowedIntValue(MYSQL_AVAILABLE_PERIOD), + DiffSuppressFunc: func(k, olds, news string, d *schema.ResourceData) bool { + return true + }, + Description: "Period of instance. NOTES: Only supported prepaid instance.", + }, + "prepaid_period": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + ConflictsWith: []string{"pay_type", "period"}, + ValidateFunc: tccommon.ValidateAllowedIntValue(MYSQL_AVAILABLE_PERIOD), + Description: "Period of instance. NOTES: Only supported prepaid instance.", + }, + "auto_renew_flag": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: tccommon.ValidateAllowedIntValue([]int{0, 1}), + Default: 0, + Description: "Auto renew flag. NOTES: Only supported prepaid instance.", + }, + "intranet_port": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: tccommon.ValidateIntegerInRange(1024, 65535), + Default: 3306, + Description: "Public access port. Valid value ranges: [1024~65535]. The default value is `3306`.", + }, + "mem_size": { + Type: schema.TypeInt, + Required: true, + Description: "Memory size (in MB).", + }, + "cpu": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "CPU cores.", + }, + "volume_size": { + Type: schema.TypeInt, + Required: true, + Description: "Disk size (in GB).", + }, + "vpc_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: tccommon.ValidateStringLengthInRange(1, 100), + Description: "ID of VPC, which can be modified once every 24 hours and can't be removed.", + }, + "subnet_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: tccommon.ValidateStringLengthInRange(1, 100), + Description: "Private network ID. If `vpc_id` is set, this value is required.", + }, + + "security_groups": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: func(v interface{}) int { + return helper.HashString(v.(string)) + }, + Description: "Security groups to use.", + }, + "device_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specify device type, available values: `UNIVERSAL` (default), `EXCLUSIVE`, `BASIC`.", + }, + "slave_deploy_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: tccommon.ValidateAllowedIntValue([]int{0, 1}), + Default: 0, + Description: "Availability zone deployment method. Available values: 0 - Single availability zone; 1 - Multiple availability zones.", + }, + "availability_zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Indicates which availability zone will be used.", + }, + "first_slave_zone": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Zone information about first slave instance.", + }, + "second_slave_zone": { + Type: schema.TypeString, + Optional: true, + Description: "Zone information about second slave instance.", + }, + "project_id": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "Project ID, default value is 0.", + }, + "slave_sync_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: tccommon.ValidateAllowedIntValue([]int{0, 1, 2}), + Default: 0, + Description: "Data replication mode. 0 - Async replication; 1 - Semisync replication; 2 - Strongsync replication.", + }, + "force_delete": { + Type: schema.TypeBool, + Optional: true, + Default: false, + 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.", + }, + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "Instance tags.", + }, + + // Computed values + "intranet_ip": { + Type: schema.TypeString, + Computed: true, + Description: "instance intranet IP.", + }, + }, + } +} + +func resourceTencentCloudMysqlDrInstanceCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_mysql_dr_instance.create")() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + mysqlService := MysqlService{client: client} + masterClient := *client + if v, ok := d.GetOk("master_region"); ok { + masterClient.Region = v.(string) + } + + masterInstanceId := d.Get("master_instance_id").(string) + var masterinstace *cdb.InstanceInfo + err := resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { + masterService := MysqlService{client: &masterClient} + instace, err := masterService.DescribeDBInstanceById(context.TODO(), masterInstanceId) + if err != nil { + return resource.NonRetryableError(err) + } + if instace == nil { + return resource.NonRetryableError(fmt.Errorf("Master instance does not exist, %s", masterInstanceId)) + } + masterinstace = instace + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create mysql task fail, reason:%s\n ", logId, err.Error()) + return err + } + + if *masterinstace.InstanceId != masterInstanceId { + return fmt.Errorf("Master instance is not mastert, %s", masterInstanceId) + } + + payType := getPayType(d).(int) + if payType == MysqlPayByMonth { + request := cdb.NewCreateDBInstanceRequest() + if err := mysqlDrInstanceSet(ctx, request, d, meta, *masterinstace); err != nil { + return err + } + + response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseMysqlClient().CreateDBInstance(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + if len(response.Response.InstanceIds) != 1 { + return fmt.Errorf("mysql CreateDBInstance return len(InstanceIds) is not 1,but %d", len(response.Response.InstanceIds)) + } + d.SetId(*response.Response.InstanceIds[0]) + } else if payType == MysqlPayByUse { + request := cdb.NewCreateDBInstanceHourRequest() + if err := mysqlDrInstanceSet(ctx, request, d, meta, *masterinstace); err != nil { + return err + } + + response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseMysqlClient().CreateDBInstanceHour(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + if len(response.Response.InstanceIds) != 1 { + return fmt.Errorf("mysql CreateDBInstanceHour return len(InstanceIds) is not 1,but %d", len(response.Response.InstanceIds)) + } + d.SetId(*response.Response.InstanceIds[0]) + } else { + return fmt.Errorf("mysql not support this pay type yet.") + } + + mysqlID := d.Id() + + err = resource.Retry(4*tccommon.ReadRetryTimeout, func() *resource.RetryError { + mysqlInfo, err := mysqlService.DescribeDBInstanceById(ctx, mysqlID) + if err != nil { + return resource.NonRetryableError(err) + } + if mysqlInfo == nil { + err = fmt.Errorf("mysqlid %s instance not exists", mysqlID) + return resource.NonRetryableError(err) + } + if *mysqlInfo.Status == MYSQL_STATUS_DELIVING { + return resource.RetryableError(fmt.Errorf("create mysql task status is MYSQL_STATUS_DELIVING(%d)", MYSQL_STATUS_DELIVING)) + } + if *mysqlInfo.Status == MYSQL_STATUS_RUNNING { + return nil + } + err = fmt.Errorf("create mysql task status is %d,we won't wait for it finish", *mysqlInfo.Status) + return resource.NonRetryableError(err) + }) + + if err != nil { + log.Printf("[CRITAL]%s create mysql task fail, reason:%s\n ", logId, err.Error()) + return err + } + + if tags := helper.GetTags(d, "tags"); len(tags) > 0 { + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + resourceName := tccommon.BuildTagResourceName("cdb", "instanceId", tcClient.Region, d.Id()) + log.Printf("[DEBUG]Mysql instance create, resourceName:%s\n", resourceName) + if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { + return err + } + } + + return resourceTencentCloudMysqlDrInstanceRead(d, meta) +} + +func resourceTencentCloudMysqlDrInstanceRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_mysql_dr_instance.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + mysqlService := MysqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + mysqlInfo, errRet := mysqlService.DescribeDBInstanceById(ctx, d.Id()) + if errRet != nil { + return fmt.Errorf("Describe mysql instance fails, reaseon %v", errRet.Error()) + } + if mysqlInfo == nil { + d.SetId("") + return nil + } + if MysqlDelStates[*mysqlInfo.Status] { + mysqlInfo = nil + d.SetId("") + return nil + } + + _ = d.Set("master_instance_id", *mysqlInfo.MasterInfo.InstanceId) + _ = d.Set("master_region", *mysqlInfo.MasterInfo.Region) + + _ = d.Set("instance_name", *mysqlInfo.InstanceName) + + _ = d.Set("charge_type", MYSQL_CHARGE_TYPE[int(*mysqlInfo.PayType)]) + _ = d.Set("pay_type", -1) + _ = d.Set("period", -1) + if int(*mysqlInfo.PayType) == MysqlPayByMonth { + tempInt, _ := d.Get("prepaid_period").(int) + if tempInt == 0 { + _ = d.Set("prepaid_period", 1) + } + } + + if *mysqlInfo.AutoRenew == MYSQL_RENEW_CLOSE { + *mysqlInfo.AutoRenew = MYSQL_RENEW_NOUSE + } + _ = d.Set("auto_renew_flag", int(*mysqlInfo.AutoRenew)) + _ = d.Set("mem_size", mysqlInfo.Memory) + _ = d.Set("cpu", mysqlInfo.Cpu) + _ = d.Set("volume_size", mysqlInfo.Volume) + _ = d.Set("vpc_id", mysqlInfo.UniqVpcId) + _ = d.Set("subnet_id", mysqlInfo.UniqSubnetId) + _ = d.Set("device_type", mysqlInfo.DeviceType) + _ = d.Set("availability_zone", mysqlInfo.Zone) + _ = d.Set("slave_deploy_mode", mysqlInfo.DeployMode) + _ = d.Set("slave_sync_mode", mysqlInfo.ProtectMode) + _ = d.Set("project_id", mysqlInfo.ProjectId) + + if mysqlInfo.SlaveInfo != nil && mysqlInfo.SlaveInfo.First != nil { + _ = d.Set("first_slave_zone", mysqlInfo.SlaveInfo.First.Zone) + } + + if mysqlInfo.SlaveInfo != nil && mysqlInfo.SlaveInfo.First != nil { + _ = d.Set("first_slave_zone", mysqlInfo.SlaveInfo.First.Zone) + } + + securityGroups, err := mysqlService.DescribeDBSecurityGroups(ctx, d.Id()) + if err != nil { + sdkErr, ok := err.(*sdkError.TencentCloudSDKError) + if ok { + if sdkErr.Code == MysqlInstanceIdNotFound3 { + mysqlInfo = nil + d.SetId("") + return nil + } + } + return err + } + _ = d.Set("security_groups", securityGroups) + + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + tags, err := tagService.DescribeResourceTags(ctx, "cdb", "instanceId", tcClient.Region, d.Id()) + if err != nil { + return err + } + + if err := d.Set("tags", tags); err != nil { + log.Printf("[CRITAL]%s provider set tags fail, reason:%s\n ", logId, err.Error()) + return nil + } + + _ = d.Set("intranet_ip", mysqlInfo.Vip) + _ = d.Set("intranet_port", int(*mysqlInfo.Vport)) + + return nil +} + +func resourceTencentCloudMysqlDrInstanceUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_mysql_dr_instance.update")() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + payType := getPayType(d).(int) + + d.Partial(true) + + if payType == MysqlPayByMonth { + if d.HasChange("auto_renew_flag") { + renewFlag := int64(d.Get("auto_renew_flag").(int)) + mysqlService := MysqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + if err := mysqlService.ModifyAutoRenewFlag(ctx, d.Id(), renewFlag); err != nil { + return err + } + + } + } + err := mysqlAllInstanceRoleUpdate(ctx, d, meta, true) + if err != nil { + return err + } + + immutableFields := []string{ + "master_instance_id", + "zone", + "master_region", + } + + for _, f := range immutableFields { + if d.HasChange(f) { + return fmt.Errorf("argument `%s` cannot be modified for now", f) + } + } + + d.Partial(false) + + return resourceTencentCloudMysqlDrInstanceRead(d, meta) +} + +func resourceTencentCloudMysqlDrInstanceDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_mysql_dr_instance.delete")() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + mysqlService := MysqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + _, err := mysqlService.IsolateDBInstance(ctx, d.Id()) + if err != nil { + //for the pay order wait + return tccommon.RetryError(err, tccommon.InternalError) + } + return nil + }) + + if err != nil { + return err + } + + var hasDeleted = false + payType := getPayType(d).(int) + forceDelete := d.Get("force_delete").(bool) + + err = resource.Retry(7*tccommon.ReadRetryTimeout, func() *resource.RetryError { + mysqlInfo, err := mysqlService.DescribeDBInstanceById(ctx, d.Id()) + + if err != nil { + if _, ok := err.(*sdkError.TencentCloudSDKError); !ok { + return resource.RetryableError(err) + } else { + return resource.NonRetryableError(err) + } + } + + if mysqlInfo == nil { + hasDeleted = true + return nil + } + if *mysqlInfo.Status == MYSQL_STATUS_ISOLATING || *mysqlInfo.Status == MYSQL_STATUS_RUNNING { + return resource.RetryableError(fmt.Errorf("mysql isolating.")) + } + if *mysqlInfo.Status == MYSQL_STATUS_ISOLATED { + return nil + } + return resource.NonRetryableError(fmt.Errorf("after IsolateDBInstance mysql Status is %d", *mysqlInfo.Status)) + }) + + if hasDeleted { + return nil + } + if err != nil { + return err + } + if payType == MysqlPayByMonth && !forceDelete { + return nil + } + + err = mysqlService.OfflineIsolatedInstances(ctx, d.Id()) + if err == nil { + log.Printf("[WARN]this mysql is dr instance, it is released asynchronously, and the bound resource is not now fully released now\n") + } + return err +} + +func mysqlDrInstanceSet(ctx context.Context, requestInter interface{}, d *schema.ResourceData, meta interface{}, instance cdb.InstanceInfo) error { + requestByMonth, okByMonth := requestInter.(*cdb.CreateDBInstanceRequest) + requestByUse, _ := requestInter.(*cdb.CreateDBInstanceHourRequest) + + instanceRole := "dr" + if okByMonth { + requestByMonth.InstanceRole = &instanceRole + } else { + requestByUse.InstanceRole = &instanceRole + } + + var goodsNum int64 = 1 + if okByMonth { + requestByMonth.GoodsNum = &goodsNum + } else { + requestByUse.GoodsNum = &goodsNum + } + + if instanceNameInterface, ok := d.GetOk("instance_name"); ok { + instanceName := instanceNameInterface.(string) + if okByMonth { + requestByMonth.InstanceName = &instanceName + } else { + requestByUse.InstanceName = &instanceName + } + } + + if payType, ok := d.GetOk("pay_type"); ok && okByMonth { + var period int + if !ok || payType == -1 { + period = d.Get("prepaid_period").(int) + } else { + period = d.Get("period").(int) + } + requestByMonth.Period = helper.IntInt64(period) + } + + intranetPort := int64(d.Get("intranet_port").(int)) + if okByMonth { + requestByMonth.Port = &intranetPort + } else { + requestByUse.Port = &intranetPort + } + + memSize := int64(d.Get("mem_size").(int)) + if okByMonth { + requestByMonth.Memory = &memSize + } else { + requestByUse.Memory = &memSize + } + + cpu := int64(d.Get("cpu").(int)) + if okByMonth { + requestByMonth.Cpu = &cpu + } else { + requestByUse.Cpu = &cpu + } + + volumeSize := int64(d.Get("volume_size").(int)) + if okByMonth { + requestByMonth.Volume = &volumeSize + } else { + requestByUse.Volume = &volumeSize + } + + if strInterface, ok := d.GetOk("vpc_id"); ok { + str := strInterface.(string) + if okByMonth { + requestByMonth.UniqVpcId = &str + } else { + requestByUse.UniqVpcId = &str + } + + } + if strInterface, ok := d.GetOk("subnet_id"); ok { + str := strInterface.(string) + if okByMonth { + requestByMonth.UniqSubnetId = &str + } else { + requestByUse.UniqSubnetId = &str + } + } + err := fmt.Errorf("You have to set both vpc_id and subnet_id") + if okByMonth { + if requestByMonth.UniqVpcId != nil && requestByMonth.UniqSubnetId == nil { + return err + } + if requestByMonth.UniqVpcId == nil && requestByMonth.UniqSubnetId != nil { + return err + } + } else { + if requestByUse.UniqVpcId != nil && requestByUse.UniqSubnetId == nil { + return err + } + if requestByUse.UniqVpcId == nil && requestByUse.UniqSubnetId != nil { + return err + } + } + + if temp, ok := d.GetOkExists("security_groups"); ok { + securityGroups := temp.(*schema.Set).List() + requestSecurityGroup := make([]*string, 0, len(securityGroups)) + for _, v := range securityGroups { + str := v.(string) + requestSecurityGroup = append(requestSecurityGroup, &str) + } + if okByMonth { + requestByMonth.SecurityGroup = requestSecurityGroup + } else { + requestByUse.SecurityGroup = requestSecurityGroup + } + } + + if v, ok := d.GetOk("param_template_id"); ok { + paramTemplateId := helper.IntInt64(v.(int)) + if okByMonth { + requestByMonth.ParamTemplateId = paramTemplateId + } else { + requestByUse.ParamTemplateId = paramTemplateId + } + } + + if v, ok := d.GetOk("device_type"); ok { + deviceType := helper.String(v.(string)) + if okByMonth { + requestByMonth.DeviceType = deviceType + } else { + requestByUse.DeviceType = deviceType + } + } + + if v, ok := d.GetOk("master_region"); ok { + masterRegion := helper.String(v.(string)) + if okByMonth { + requestByMonth.MasterRegion = masterRegion + } else { + requestByUse.MasterRegion = masterRegion + } + } + + if v, ok := d.GetOk("auto_renew_flag"); ok { + autoRenewFlag := helper.IntInt64(v.(int)) + if okByMonth { + requestByMonth.AutoRenewFlag = autoRenewFlag + } else { + requestByUse.AutoRenewFlag = autoRenewFlag + } + } + + if v, ok := d.GetOk("master_instance_id"); ok { + masterInstanceId := helper.String(v.(string)) + if okByMonth { + requestByMonth.MasterInstanceId = masterInstanceId + } else { + requestByUse.MasterInstanceId = masterInstanceId + } + } + + if v, ok := d.GetOk("slave_deploy_mode"); ok { + deployMode := helper.IntInt64(v.(int)) + if okByMonth { + requestByMonth.DeployMode = deployMode + } else { + requestByUse.DeployMode = deployMode + } + } + + if v, ok := d.GetOk("availability_zone"); ok { + zone := helper.String(v.(string)) + if okByMonth { + requestByMonth.Zone = zone + } else { + requestByUse.Zone = zone + } + } + + if v, ok := d.GetOk("first_slave_zone"); ok { + slaveZone := helper.String(v.(string)) + if okByMonth { + requestByMonth.SlaveZone = slaveZone + } else { + requestByUse.SlaveZone = slaveZone + } + } + + if v, ok := d.GetOk("second_slave_zone"); ok { + backupZone := helper.String(v.(string)) + if okByMonth { + requestByMonth.BackupZone = backupZone + } else { + requestByUse.BackupZone = backupZone + } + } + + if v, ok := d.GetOk("project_id"); ok { + projectId := helper.IntInt64(v.(int)) + if okByMonth { + requestByMonth.ProjectId = projectId + } else { + requestByUse.ProjectId = projectId + } + } + + if v, ok := d.GetOk("slave_sync_mode"); ok { + slaveSyncMode := helper.IntInt64(v.(int)) + if okByMonth { + requestByMonth.ProtectMode = slaveSyncMode + } else { + requestByUse.ProtectMode = slaveSyncMode + } + } + + if engineType := instance.EngineType; engineType != nil { + if okByMonth { + requestByMonth.EngineType = engineType + } else { + requestByUse.EngineType = engineType + } + } + + if engineVersion := instance.EngineVersion; engineVersion != nil { + if okByMonth { + requestByMonth.EngineVersion = engineVersion + } else { + requestByUse.EngineVersion = engineVersion + } + } + + autoSyncFlag := helper.IntInt64(1) + if okByMonth { + requestByMonth.AutoSyncFlag = autoSyncFlag + } else { + requestByUse.AutoSyncFlag = autoSyncFlag + } + + return nil + +} diff --git a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.md b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.md new file mode 100644 index 0000000000..42e59fd14f --- /dev/null +++ b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.md @@ -0,0 +1,77 @@ +Provides a mysql instance resource to create read-only database instances. + +~> **NOTE:** Read-only instances can be purchased only for two-node or three-node source instances on MySQL 5.6 or above with the InnoDB engine at a specification of 1 GB memory and 50 GB disk capacity or above. +~> **NOTE:** The terminate operation of read only mysql does NOT take effect immediately, maybe takes for several hours. so during that time, VPCs associated with that mysql instance can't be terminated also. + +Example Usage + +```hcl +data "tencentcloud_availability_zones_by_product" "zones" { + product = "cdb" +} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-mysql" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name + name = "subnet-mysql" + vpc_id = tencentcloud_vpc.vpc.id + cidr_block = "10.0.0.0/16" + is_multicast = false +} + +resource "tencentcloud_security_group" "security_group" { + name = "sg-mysql" + description = "mysql test" +} + +resource "tencentcloud_mysql_instance" "example" { + internet_service = 1 + engine_version = "5.7" + charge_type = "POSTPAID" + root_password = "PassWord123" + slave_deploy_mode = 0 + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name + slave_sync_mode = 1 + instance_name = "tf-example-mysql" + mem_size = 4000 + volume_size = 200 + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + intranet_port = 3306 + security_groups = [tencentcloud_security_group.security_group.id] + + tags = { + name = "test" + } + + parameters = { + character_set_server = "UTF8" + max_connections = "1000" + } +} + +resource "tencentcloud_mysql_readonly_instance" "example" { + master_instance_id = tencentcloud_mysql_instance.example.id + instance_name = "tf-example" + mem_size = 128000 + volume_size = 255 + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + intranet_port = 3306 + security_groups = [tencentcloud_security_group.security_group.id] + + tags = { + createBy = "terraform" + } +} +``` +Import + +mysql read-only database instances can be imported using the id, e.g. +``` +terraform import tencentcloud_mysql_readonly_instance.default cdb-dnqksd9f +``` \ No newline at end of file diff --git a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go new file mode 100644 index 0000000000..49408b155f --- /dev/null +++ b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go @@ -0,0 +1,125 @@ +package cdb_test + +import ( + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + localcdb "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/cdb" + + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" +) + +// go test -test.run TestAccTencentCloudMysqlDrInstanceResource_basic -v +func TestAccTencentCloudMysqlDrInstanceResource_basic(t *testing.T) { + // t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccStepSetRegion(t, "ap-shanghai") + tcacctest.AccPreCheck(t) + }, + Providers: tcacctest.AccProviders, + CheckDestroy: testAccCheckMysqlDrInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccMysqlDrInstance, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckMysqlDrInstanceExists("tencentcloud_mysql_dr_instance.mysql_dr"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "instance_name", "mysql-dr-test"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "mem_size", "8000"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "volume_size", "100"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "intranet_port", "3360"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "tags.test", "test-tf"), + ), + }, + { + ResourceName: "tencentcloud_mysql_dr_instance.mysql_dr", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckMysqlDrInstanceDestroy(s *terraform.State) error { + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + mysqlService := localcdb.NewMysqlService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_mysql_dr_instance" { + continue + } + instance, err := mysqlService.DescribeRunningDBInstanceById(ctx, rs.Primary.ID) + if instance != nil { + return fmt.Errorf("mysql instance still exist") + } + if err != nil { + sdkErr, ok := err.(*errors.TencentCloudSDKError) + if ok && sdkErr.Code == localcdb.MysqlInstanceIdNotFound { + continue + } + return err + } + } + return nil +} + +func testAccCheckMysqlDrInstanceExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("mysql instance %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("mysql instance id is not set") + } + + mysqlService := localcdb.NewMysqlService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) + instance, err := mysqlService.DescribeDBInstanceById(ctx, rs.Primary.ID) + if instance == nil { + return fmt.Errorf("mysql instance %s is not found", rs.Primary.ID) + } + if err != nil { + return err + } + return nil + } +} + +const testAccMysqlDrInstance = ` +resource "tencentcloud_mysql_dr_instance" "mysql_dr" { + master_instance_id = "cdb-adjdu3t5" + master_region = "ap-guangzhou" + auto_renew_flag = 0 + availability_zone = "ap-shanghai-3" + charge_type = "POSTPAID" + cpu = 4 + device_type = "UNIVERSAL" + first_slave_zone = "ap-shanghai-4" + instance_name = "mysql-dr-test" + mem_size = 8000 + prepaid_period = 1 + project_id = 0 + security_groups = [ + "sg-q4d821qk", + ] + slave_deploy_mode = 1 + slave_sync_mode = 0 + subnet_id = "subnet-5vfntba5" + volume_size = 100 + vpc_id = "vpc-h6s1s3aa" + intranet_port = 3360 + tags = { + test = "test-tf" + } +} + +` \ No newline at end of file diff --git a/tencentcloud/services/cdb/resource_tc_mysql_instance_test.go b/tencentcloud/services/cdb/resource_tc_mysql_instance_test.go index dae3005d50..ff4488774e 100644 --- a/tencentcloud/services/cdb/resource_tc_mysql_instance_test.go +++ b/tencentcloud/services/cdb/resource_tc_mysql_instance_test.go @@ -347,7 +347,7 @@ func TestAccTencentCloudMysqlInstanceResource_mysql8(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "availability_zone", "ap-guangzhou-4"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "instance_name", "myTestMysql"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "mem_size", "1000"), - resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "volume_size", "25"), + resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "volume_size", "100"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "intranet_port", "3306"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "tags.createdBy", "terraform"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "parameters.character_set_server", "utf8"), @@ -370,7 +370,7 @@ func TestAccTencentCloudMysqlInstanceResource_mysql8(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "availability_zone", "ap-guangzhou-4"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "instance_name", "myTestMysql"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "mem_size", "1000"), - resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "volume_size", "25"), + resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "volume_size", "100"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "intranet_port", "3306"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "tags.createdBy", "terraform"), resource.TestCheckResourceAttr("tencentcloud_mysql_instance.mysql8", "parameters.character_set_server", "gbk"), @@ -640,7 +640,7 @@ resource "tencentcloud_mysql_instance" "mysql8" { project_id = 0 instance_name = "myTestMysql" mem_size = 1000 - volume_size = 25 + volume_size = 100 intranet_port = 3306 security_groups = ["sg-05f7wnhn"] diff --git a/website/docs/r/mysql_dr_instance.html.markdown b/website/docs/r/mysql_dr_instance.html.markdown new file mode 100644 index 0000000000..0fc9a40051 --- /dev/null +++ b/website/docs/r/mysql_dr_instance.html.markdown @@ -0,0 +1,127 @@ +--- +subcategory: "TencentDB for MySQL(cdb)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_mysql_dr_instance" +sidebar_current: "docs-tencentcloud-resource-mysql_dr_instance" +description: |- + Provides a mysql instance resource to create read-only database instances. +--- + +# tencentcloud_mysql_dr_instance + +Provides a mysql instance resource to create read-only database instances. + +~> **NOTE:** Read-only instances can be purchased only for two-node or three-node source instances on MySQL 5.6 or above with the InnoDB engine at a specification of 1 GB memory and 50 GB disk capacity or above. +~> **NOTE:** The terminate operation of read only mysql does NOT take effect immediately, maybe takes for several hours. so during that time, VPCs associated with that mysql instance can't be terminated also. + +## Example Usage + +```hcl +data "tencentcloud_availability_zones_by_product" "zones" { + product = "cdb" +} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-mysql" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name + name = "subnet-mysql" + vpc_id = tencentcloud_vpc.vpc.id + cidr_block = "10.0.0.0/16" + is_multicast = false +} + +resource "tencentcloud_security_group" "security_group" { + name = "sg-mysql" + description = "mysql test" +} + +resource "tencentcloud_mysql_instance" "example" { + internet_service = 1 + engine_version = "5.7" + charge_type = "POSTPAID" + root_password = "PassWord123" + slave_deploy_mode = 0 + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name + slave_sync_mode = 1 + instance_name = "tf-example-mysql" + mem_size = 4000 + volume_size = 200 + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + intranet_port = 3306 + security_groups = [tencentcloud_security_group.security_group.id] + + tags = { + name = "test" + } + + parameters = { + character_set_server = "UTF8" + max_connections = "1000" + } +} + +resource "tencentcloud_mysql_readonly_instance" "example" { + master_instance_id = tencentcloud_mysql_instance.example.id + instance_name = "tf-example" + mem_size = 128000 + volume_size = 255 + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + intranet_port = 3306 + security_groups = [tencentcloud_security_group.security_group.id] + + tags = { + createBy = "terraform" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `instance_name` - (Required, String) The name of a mysql instance. +* `master_instance_id` - (Required, String) Indicates the master instance ID of recovery instances. +* `master_region` - (Required, String) The zone information of the primary instance is required when you purchase a disaster recovery instance. +* `mem_size` - (Required, Int) Memory size (in MB). +* `volume_size` - (Required, Int) Disk size (in GB). +* `auto_renew_flag` - (Optional, Int) Auto renew flag. NOTES: Only supported prepaid instance. +* `availability_zone` - (Optional, String) Indicates which availability zone will be used. +* `charge_type` - (Optional, String, ForceNew) Pay type of instance. Valid values:`PREPAID`, `POSTPAID`. Default is `POSTPAID`. +* `cpu` - (Optional, Int) CPU cores. +* `device_type` - (Optional, String) Specify device type, available values: `UNIVERSAL` (default), `EXCLUSIVE`, `BASIC`. +* `first_slave_zone` - (Optional, String) Zone information about first slave instance. +* `force_delete` - (Optional, Bool) 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. +* `intranet_port` - (Optional, Int) Public access port. Valid value ranges: [1024~65535]. The default value is `3306`. +* `pay_type` - (Optional, Int, **Deprecated**) It has been deprecated from version 1.36.0. Please use `charge_type` instead. Pay type of instance. Valid values: `0`, `1`. `0`: prepaid, `1`: postpaid. +* `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. +* `prepaid_period` - (Optional, Int) Period of instance. NOTES: Only supported prepaid instance. +* `project_id` - (Optional, Int) Project ID, default value is 0. +* `second_slave_zone` - (Optional, String) Zone information about second slave instance. +* `security_groups` - (Optional, Set: [`String`]) Security groups to use. +* `slave_deploy_mode` - (Optional, Int) Availability zone deployment method. Available values: 0 - Single availability zone; 1 - Multiple availability zones. +* `slave_sync_mode` - (Optional, Int) Data replication mode. 0 - Async replication; 1 - Semisync replication; 2 - Strongsync replication. +* `subnet_id` - (Optional, String) Private network ID. If `vpc_id` is set, this value is required. +* `tags` - (Optional, Map) Instance tags. +* `vpc_id` - (Optional, String) ID of VPC, which can be modified once every 24 hours and can't be removed. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. +* `intranet_ip` - instance intranet IP. + + +## Import + +mysql read-only database instances can be imported using the id, e.g. +``` +terraform import tencentcloud_mysql_readonly_instance.default cdb-dnqksd9f +``` + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index 9544693b76..004cede11a 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -5476,6 +5476,9 @@
  • tencentcloud_mysql_deploy_group
  • +
  • + tencentcloud_mysql_dr_instance +
  • tencentcloud_mysql_dr_instance_to_mater
  • From 8f9e3aba2cecf6429cd84fe5482db71f7ec6e242 Mon Sep 17 00:00:00 2001 From: arunma Date: Tue, 23 Apr 2024 10:05:05 +0800 Subject: [PATCH 2/3] feat: add changelog --- .changelog/2596.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/2596.txt diff --git a/.changelog/2596.txt b/.changelog/2596.txt new file mode 100644 index 0000000000..9090858b3f --- /dev/null +++ b/.changelog/2596.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_mysql_dr_instance +``` \ No newline at end of file From 358da1de4704154b7ccce114ce3ac0388106b46e Mon Sep 17 00:00:00 2001 From: arunma Date: Tue, 23 Apr 2024 10:06:50 +0800 Subject: [PATCH 3/3] fix: modify test --- .../cdb/resource_tc_mysql_dr_instance.go | 2 +- .../cdb/resource_tc_mysql_dr_instance_test.go | 51 +++++++++++++++++-- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go index e816e414a8..3daae18244 100644 --- a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go +++ b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance.go @@ -144,7 +144,7 @@ func ResourceTencentCloudMysqlDrInstance() *schema.Resource { ValidateFunc: tccommon.ValidateStringLengthInRange(1, 100), Description: "Private network ID. If `vpc_id` is set, this value is required.", }, - + "security_groups": { Type: schema.TypeSet, Optional: true, diff --git a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go index 49408b155f..161e406537 100644 --- a/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go +++ b/tencentcloud/services/cdb/resource_tc_mysql_dr_instance_test.go @@ -14,13 +14,13 @@ import ( "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" ) -// go test -test.run TestAccTencentCloudMysqlDrInstanceResource_basic -v -func TestAccTencentCloudMysqlDrInstanceResource_basic(t *testing.T) { +// go test -test.run TestAccTencentNeedFixCloudMysqlDrInstanceResource_basic -v +func TestAccTencentNeedFixCloudMysqlDrInstanceResource_basic(t *testing.T) { // t.Parallel() resource.Test(t, resource.TestCase{ - PreCheck: func() { + PreCheck: func() { tcacctest.AccStepSetRegion(t, "ap-shanghai") - tcacctest.AccPreCheck(t) + tcacctest.AccPreCheck(t) }, Providers: tcacctest.AccProviders, CheckDestroy: testAccCheckMysqlDrInstanceDestroy, @@ -41,6 +41,17 @@ func TestAccTencentCloudMysqlDrInstanceResource_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccMysqlDrInstanceUp, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckMysqlDrInstanceExists("tencentcloud_mysql_dr_instance.mysql_dr"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "instance_name", "mysql-dr-test-up"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "mem_size", "8000"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "volume_size", "100"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "intranet_port", "3360"), + resource.TestCheckResourceAttr("tencentcloud_mysql_dr_instance.mysql_dr", "tags.test", "test-tf"), + ), + }, }, }) } @@ -122,4 +133,34 @@ resource "tencentcloud_mysql_dr_instance" "mysql_dr" { } } -` \ No newline at end of file +` + +const testAccMysqlDrInstanceUp = ` +resource "tencentcloud_mysql_dr_instance" "mysql_dr" { + master_instance_id = "cdb-adjdu3t5" + master_region = "ap-guangzhou" + auto_renew_flag = 0 + availability_zone = "ap-shanghai-3" + charge_type = "POSTPAID" + cpu = 4 + device_type = "UNIVERSAL" + first_slave_zone = "ap-shanghai-4" + instance_name = "mysql-dr-test-up" + mem_size = 8000 + prepaid_period = 1 + project_id = 0 + security_groups = [ + "sg-q4d821qk", + ] + slave_deploy_mode = 1 + slave_sync_mode = 0 + subnet_id = "subnet-5vfntba5" + volume_size = 100 + vpc_id = "vpc-h6s1s3aa" + intranet_port = 3360 + tags = { + test = "test-tf" + } +} + +`