diff --git a/.changelog/3281.txt b/.changelog/3281.txt new file mode 100644 index 0000000000..d4a7ff89ec --- /dev/null +++ b/.changelog/3281.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_postgresql_instance: support `monthly_backup_retention_period`, `monthly_backup_period` and `monthly_plan_id` +``` \ No newline at end of file diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go index 6de9d2bd4d..b42d84249c 100644 --- a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go @@ -259,6 +259,22 @@ func ResourceTencentCloudPostgresqlInstance() *schema.Resource { Description: "List of backup period per week, available values: `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`. NOTE: At least specify two days.", Elem: &schema.Schema{Type: schema.TypeString}, }, + "monthly_backup_retention_period": { + Type: schema.TypeInt, + Optional: true, + Description: "Specify days of the retention.", + }, + "monthly_backup_period": { + Type: schema.TypeList, + Optional: true, + Description: "If it is in monthly dimension, the format is numeric characters, such as [\"1\",\"2\"].", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "monthly_plan_id": { + Type: schema.TypeString, + Computed: true, + Description: "Monthly plan id.", + }, }, }, }, @@ -685,6 +701,37 @@ func resourceTencentCloudPostgresqlInstanceCreate(d *schema.ResourceData, meta i // set backup plan if plan, ok := helper.InterfacesHeadMap(d, "backup_plan"); ok { + if v, ok := plan["monthly_backup_period"].([]interface{}); ok && len(v) > 0 { + request0 := postgresql.NewCreateBackupPlanRequest() + request0.DBInstanceId = &instanceId + request0.BackupPeriodType = helper.String("month") + request0.PlanName = helper.String("custom_month") + request0.BackupPeriod = helper.InterfacesStringsPoint(v) + + if v, ok := plan["min_backup_start_time"].(string); ok && v != "" { + request0.MinBackupStartTime = &v + } + + if v, ok := plan["max_backup_start_time"].(string); ok && v != "" { + request0.MaxBackupStartTime = &v + } + + if v, ok := plan["monthly_backup_retention_period"].(int); ok && v != 0 { + request0.BaseBackupRetentionPeriod = helper.IntUint64(v) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + _, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresqlClient().CreateBackupPlan(request0) + if e != nil { + return tccommon.RetryError(err, postgresql.OPERATIONDENIED_INSTANCESTATUSLIMITOPERROR) + } + return nil + }) + + if err != nil { + return err + } + } request := postgresql.NewModifyBackupPlanRequest() request.DBInstanceId = &instanceId if v, ok := plan["min_backup_start_time"].(string); ok && v != "" { @@ -923,9 +970,19 @@ func resourceTencentCloudPostgresqlInstanceRead(d *schema.ResourceData, meta int return err } - var backupPlan *postgresql.BackupPlan + var backupPlan, monthlyBackupPlan *postgresql.BackupPlan if len(bkpResponse) > 0 { backupPlan = bkpResponse[0] + for _, plan := range bkpResponse { + if plan != nil && plan.BackupPeriodType != nil { + if *plan.BackupPeriodType == "month" { + monthlyBackupPlan = plan + } + if *plan.BackupPeriodType == "week" { + backupPlan = plan + } + } + } } if backupPlan != nil { @@ -953,6 +1010,22 @@ func resourceTencentCloudPostgresqlInstanceRead(d *schema.ResourceData, meta int planMap["backup_period"] = strSlice } + if monthlyBackupPlan != nil && monthlyBackupPlan.PlanId != nil { + planMap["monthly_plan_id"] = monthlyBackupPlan.PlanId + } + if monthlyBackupPlan != nil && monthlyBackupPlan.BackupPeriod != nil { + strSlice := []string{} + err := json.Unmarshal([]byte(*monthlyBackupPlan.BackupPeriod), &strSlice) + if err != nil { + return fmt.Errorf("BackupPeriod:[%s] has invalid format,Unmarshal failed! error: %v", *backupPlan.BackupPeriod, err.Error()) + } + + planMap["monthly_backup_period"] = strSlice + } + if monthlyBackupPlan != nil && monthlyBackupPlan.BaseBackupRetentionPeriod != nil { + planMap["monthly_backup_retention_period"] = monthlyBackupPlan.BaseBackupRetentionPeriod + } + _ = d.Set("backup_plan", []interface{}{planMap}) } @@ -1411,6 +1484,86 @@ func resourceTencentCloudPostgresqlInstanceUpdate(d *schema.ResourceData, meta i if err != nil { return err } + + request1 := postgresql.NewModifyBackupPlanRequest() + request1.DBInstanceId = &instanceId + var hasMonthlybackupPeriod bool + if v, ok := plan["min_backup_start_time"].(string); ok && v != "" { + request1.MinBackupStartTime = &v + } + + if v, ok := plan["max_backup_start_time"].(string); ok && v != "" { + request1.MaxBackupStartTime = &v + } + + if v, ok := plan["monthly_backup_retention_period"].(int); ok && v != 0 { + request1.BaseBackupRetentionPeriod = helper.IntUint64(v) + } + + if v, ok := plan["monthly_backup_period"].([]interface{}); ok && len(v) > 0 { + request1.BackupPeriod = helper.InterfacesStringsPoint(v) + hasMonthlybackupPeriod = true + } + + var monthlyPlanId string + if v, ok := plan["monthly_plan_id"].(string); ok && v != "" { + request1.PlanId = helper.String(v) + monthlyPlanId = v + } + if !hasMonthlybackupPeriod && monthlyPlanId != "" { + request0 := postgresql.NewDeleteBackupPlanRequest() + request0.DBInstanceId = &instanceId + request0.PlanId = &monthlyPlanId + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + _, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresqlClient().DeleteBackupPlan(request0) + if e != nil { + return tccommon.RetryError(e) + } + return nil + }) + + if err != nil { + return err + } + } else if hasMonthlybackupPeriod && monthlyPlanId == "" { + request00 := postgresql.NewCreateBackupPlanRequest() + request00.DBInstanceId = &instanceId + request00.BackupPeriodType = helper.String("month") + request00.PlanName = helper.String("custom_month") + if v, ok := plan["monthly_backup_period"].([]interface{}); ok && len(v) > 0 { + request00.BackupPeriod = helper.InterfacesStringsPoint(v) + } + + if v, ok := plan["min_backup_start_time"].(string); ok && v != "" { + request00.MinBackupStartTime = &v + } + + if v, ok := plan["max_backup_start_time"].(string); ok && v != "" { + request00.MaxBackupStartTime = &v + } + + if v, ok := plan["monthly_backup_retention_period"].(int); ok && v != 0 { + request00.BaseBackupRetentionPeriod = helper.IntUint64(v) + } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + _, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresqlClient().CreateBackupPlan(request00) + if e != nil { + return tccommon.RetryError(e) + } + return nil + }) + + if err != nil { + return err + } + } else { + request1.PlanId = helper.String(monthlyPlanId) + err = postgresqlService.ModifyBackupPlan(ctx, request1) + if err != nil { + return err + } + } + } } diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go b/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go index e84657deb7..7ba44747a4 100644 --- a/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go @@ -234,6 +234,39 @@ func TestAccTencentCloudPostgresqlInstanceResource_basic(t *testing.T) { }) } +func TestAccTencentCloudPostgresqlInstanceResource_backupPlan(t *testing.T) { + // t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + tcacctest.AccStepSetRegion(t, "ap-guangzhou") + }, + Providers: tcacctest.AccProviders, + CheckDestroy: testAccCheckPostgresqlInstanceDestroy, + Steps: []resource.TestStep{ + { + PreConfig: func() { tcacctest.AccPreCheck(t) }, + Config: testAccPostgresqlInstanceBackupPlan, + Check: resource.ComposeTestCheckFunc( + testAccCheckPostgresqlInstanceExists(testPostgresqlInstanceResourceKey), + resource.TestCheckResourceAttrSet(testPostgresqlInstanceResourceKey, "id"), + resource.TestCheckResourceAttrSet(testPostgresqlInstanceResourceKey, "backup_plan.0.min_backup_start_time"), + resource.TestCheckResourceAttrSet(testPostgresqlInstanceResourceKey, "backup_plan.0.max_backup_start_time"), + resource.TestCheckResourceAttrSet(testPostgresqlInstanceResourceKey, "backup_plan.0.base_backup_retention_period"), + resource.TestCheckResourceAttr(testPostgresqlInstanceResourceKey, "backup_plan.0.backup_period.#", "2"), + resource.TestCheckResourceAttr(testPostgresqlInstanceResourceKey, "backup_plan.0.monthly_backup_period.#", "1"), + resource.TestCheckResourceAttr(testPostgresqlInstanceResourceKey, "backup_plan.0.monthly_backup_retention_period", "8"), + ), + }, + { + ResourceName: testPostgresqlInstanceResourceKey, + ImportState: true, + ImportStateVerifyIgnore: []string{"root_password", "spec_code", "public_access_switch", "charset", "backup_plan"}, + }, + }, + }) +} + func TestAccTencentCloudPostgresqlInstanceResource_prepaid(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { tcacctest.AccPreCheckCommon(t, tcacctest.ACCOUNT_TYPE_PREPAY) }, @@ -460,6 +493,34 @@ resource "tencentcloud_postgresql_instance" "test" { } } ` + +const testAccPostgresqlInstanceBackupPlan string = testAccPostgresqlInstanceBasic + tcacctest.DefaultVpcSubnets + ` +resource "tencentcloud_postgresql_instance" "test" { + name = "tf_postsql_instance" + availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[5].name + charge_type = "POSTPAID_BY_HOUR" + vpc_id = local.vpc_id + subnet_id = local.subnet_id + db_major_version = "17" + engine_version = "17.0" + root_password = "t1qaA2k1wgvfa3?ZZZ" + security_groups = ["sg-5275dorp"] + charset = "LATIN1" + project_id = 0 + memory = 4 + storage = 100 + + backup_plan { + min_backup_start_time = "00:10:11" + max_backup_start_time = "01:10:11" + base_backup_retention_period = 7 + backup_period = ["monday", "wednesday"] + monthly_backup_period = ["1"] + monthly_backup_retention_period = 8 + } +} +` + const testAccPostgresqlInstancePostpaid = tcacctest.DefaultVpcSubnets + ` data "tencentcloud_availability_zones_by_product" "zone" { product = "postgres" diff --git a/website/docs/r/postgresql_instance.html.markdown b/website/docs/r/postgresql_instance.html.markdown index 4d2934d1ad..bf694dafc5 100644 --- a/website/docs/r/postgresql_instance.html.markdown +++ b/website/docs/r/postgresql_instance.html.markdown @@ -342,6 +342,8 @@ The `backup_plan` object supports the following: * `base_backup_retention_period` - (Optional, Int) Specify days of the retention. * `max_backup_start_time` - (Optional, String) Specify latest backup start time, format `hh:mm:ss`. * `min_backup_start_time` - (Optional, String) Specify earliest backup start time, format `hh:mm:ss`. +* `monthly_backup_period` - (Optional, List) If it is in monthly dimension, the format is numeric characters, such as ["1","2"]. +* `monthly_backup_retention_period` - (Optional, Int) Specify days of the retention. The `db_node_set` object supports the following: