diff --git a/.changelog/3146.txt b/.changelog/3146.txt new file mode 100644 index 0000000000..45a22e6bfc --- /dev/null +++ b/.changelog/3146.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_postgresql_parameters +``` \ No newline at end of file diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 1e65c97cb1..7526d09c5a 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -1555,6 +1555,7 @@ func Provider() *schema.Provider { "tencentcloud_postgresql_apply_parameter_template_operation": postgresql.ResourceTencentCloudPostgresqlApplyParameterTemplateOperation(), "tencentcloud_postgresql_clone_db_instance": postgresql.ResourceTencentCloudPostgresqlCloneDbInstance(), "tencentcloud_postgresql_instance_network_access": postgresql.ResourceTencentCloudPostgresqlInstanceNetworkAccess(), + "tencentcloud_postgresql_parameters": postgresql.ResourceTencentCloudPostgresqlParameters(), "tencentcloud_sqlserver_instance": sqlserver.ResourceTencentCloudSqlserverInstance(), "tencentcloud_sqlserver_db": sqlserver.ResourceTencentCloudSqlserverDB(), "tencentcloud_sqlserver_account": sqlserver.ResourceTencentCloudSqlserverAccount(), diff --git a/tencentcloud/provider.md b/tencentcloud/provider.md index 847e2774e3..e5657f5581 100644 --- a/tencentcloud/provider.md +++ b/tencentcloud/provider.md @@ -913,6 +913,7 @@ TencentDB for PostgreSQL(PostgreSQL) tencentcloud_postgresql_apply_parameter_template_operation tencentcloud_postgresql_clone_db_instance tencentcloud_postgresql_instance_network_access + tencentcloud_postgresql_parameters TencentDB for Redis(crs) Data Source diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.go b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.go new file mode 100644 index 0000000000..78f2a7775b --- /dev/null +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.go @@ -0,0 +1,217 @@ +// Code generated by iacg; DO NOT EDIT. +package postgresql + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + postgresv20170312 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudPostgresqlParameters() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudPostgresqlParametersCreate, + Read: resourceTencentCloudPostgresqlParametersRead, + Update: resourceTencentCloudPostgresqlParametersUpdate, + Delete: resourceTencentCloudPostgresqlParametersDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "db_instance_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Instance ID.", + }, + + "param_list": { + Type: schema.TypeList, + Required: true, + Description: "Parameters to be modified and expected values.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Parameter name.", + }, + "expected_value": { + Type: schema.TypeString, + Required: true, + Description: "The new value to which the parameter will be modified. When this parameter is used as an input parameter, its value must be a string, such as `0.1` (decimal), `1000` (integer), and `replica` (enum).", + }, + "default_value": { + Type: schema.TypeString, + Computed: true, + Description: "The default value of the parameter. Returned as a string.", + }, + "param_description_ch": { + Type: schema.TypeString, + Computed: true, + Description: "Parameter Chinese Description.", + }, + "param_description_en": { + Type: schema.TypeString, + Computed: true, + Description: "Parameter English Description.", + }, + }, + }, + }, + }, + } +} + +func resourceTencentCloudPostgresqlParametersCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_postgresql_parameters.create")() + defer tccommon.InconsistentCheck(d, meta)() + + var ( + dBInstanceId string + ) + if v, ok := d.GetOk("db_instance_id"); ok { + dBInstanceId = v.(string) + } + + d.SetId(dBInstanceId) + + return resourceTencentCloudPostgresqlParametersUpdate(d, meta) +} + +func resourceTencentCloudPostgresqlParametersRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_postgresql_parameters.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := PostgresqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + dBInstanceId := d.Id() + + _ = d.Set("db_instance_id", dBInstanceId) + + respData, err := service.DescribePostgresqlParametersById(ctx, dBInstanceId) + if err != nil { + return err + } + + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `postgresql_parameters` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + if err := resourceTencentCloudPostgresqlParametersReadPreHandleResponse0(ctx, respData); err != nil { + return err + } + + detailList := make([]map[string]interface{}, 0, len(respData.Detail)) + if respData.Detail != nil { + for _, detail := range respData.Detail { + detailMap := map[string]interface{}{} + + if detail.Name != nil { + detailMap["name"] = detail.Name + } + + if detail.DefaultValue != nil { + detailMap["default_value"] = detail.DefaultValue + } + + if detail.CurrentValue != nil { + detailMap["expected_value"] = detail.CurrentValue + } + + if detail.ParamDescriptionCH != nil { + detailMap["param_description_ch"] = detail.ParamDescriptionCH + } + + if detail.ParamDescriptionEN != nil { + detailMap["param_description_en"] = detail.ParamDescriptionEN + } + + detailList = append(detailList, detailMap) + } + + _ = d.Set("param_list", detailList) + } + + return nil +} + +func resourceTencentCloudPostgresqlParametersUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_postgresql_parameters.update")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + dBInstanceId := d.Id() + + needChange := false + mutableArgs := []string{"param_list"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := postgresv20170312.NewModifyDBInstanceParametersRequest() + response := postgresv20170312.NewModifyDBInstanceParametersResponse() + + if v, ok := d.GetOk("db_instance_id"); ok { + request.DBInstanceId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("param_list"); ok { + for _, item := range v.([]interface{}) { + paramListMap := item.(map[string]interface{}) + paramEntry := postgresv20170312.ParamEntry{} + if v, ok := paramListMap["name"].(string); ok && v != "" { + paramEntry.Name = helper.String(v) + } + if v, ok := paramListMap["expected_value"].(string); ok && v != "" { + paramEntry.ExpectedValue = helper.String(v) + } + request.ParamList = append(request.ParamList, ¶mEntry) + } + } + + reqErr := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresV20170312Client().ModifyDBInstanceParametersWithContext(ctx, request) + if e != nil { + return resourceTencentCloudPostgresqlParametersUpdateRequestOnError0(ctx, request, e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if reqErr != nil { + log.Printf("[CRITAL]%s update postgresql parameters failed, reason:%+v", logId, reqErr) + return reqErr + } + if err := resourceTencentCloudPostgresqlParametersUpdatePreHandleResponse0(ctx, response); err != nil { + return err + } + } + + _ = dBInstanceId + return resourceTencentCloudPostgresqlParametersRead(d, meta) +} + +func resourceTencentCloudPostgresqlParametersDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_postgresql_parameters.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + return nil +} diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.md b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.md new file mode 100644 index 0000000000..7bc856b005 --- /dev/null +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters.md @@ -0,0 +1,54 @@ +Use this resource to create postgresql parameter. + +Example Usage + +```hcl +variable "default_az" { + default = "ap-guangzhou-3" +} + +data "tencentcloud_vpc_subnets" "gz3" { + availability_zone = var.default_az + is_default = true +} + +locals { + vpc_id = data.tencentcloud_vpc_subnets.gz3.instance_list.0.vpc_id + subnet_id = data.tencentcloud_vpc_subnets.gz3.instance_list.0.subnet_id +} + +data "tencentcloud_availability_zones_by_product" "zone" { + product = "postgres" +} + +resource "tencentcloud_postgresql_instance" "test" { + name = "tf_postsql_postpaid" + availability_zone = var.default_az + charge_type = "POSTPAID_BY_HOUR" + period = 1 + vpc_id = local.vpc_id + subnet_id = local.subnet_id + engine_version = "13.3" + root_password = "t1qaA2k1wgvfa3?ZZZ" + security_groups = ["sg-5275dorp"] + charset = "LATIN1" + project_id = 0 + memory = 2 + storage = 20 +} +resource "tencentcloud_postgresql_parameters" "postgresql_parameters" { + db_instance_id = tencentcloud_postgresql_instance.test.id + param_list { + expected_value = "off" + name = "check_function_bodies" + } +} +``` + +Import + +postgresql parameters can be imported, e.g. + +``` +$ terraform import tencentcloud_postgresql_parameters.example pgrogrp-lckioi2a +``` diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_extension.go b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_extension.go new file mode 100644 index 0000000000..83f9ff838c --- /dev/null +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_extension.go @@ -0,0 +1,139 @@ +package postgresql + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + postgresv20170312 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func resourceTencentCloudPostgresqlParametersReadPreHandleResponse0(ctx context.Context, resp *postgresv20170312.DescribeDBInstanceParametersResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + + if v, ok := d.GetOk("param_list"); ok { + paramList := []*postgresv20170312.ParamInfo{} + for _, item := range v.([]interface{}) { + paramListMap := item.(map[string]interface{}) + if name, ok := paramListMap["name"].(string); ok && v != "" { + if resp.Detail != nil { + details := resp.Detail + for _, detail := range details { + if *detail.Name == name { + paramList = append(paramList, detail) + } + } + } + } + } + resp.Detail = paramList + } + + return nil +} + +func resourceTencentCloudPostgresqlParametersUpdateRequestOnError0(ctx context.Context, req *postgresv20170312.ModifyDBInstanceParametersRequest, e error) *resource.RetryError { + if e, ok := e.(*errors.TencentCloudSDKError); ok { + if e.GetCode() == "FailedOperation.FailedOperationError" { + change, err := resourceTencentCloudParamChange(ctx) + if err != nil || change { + return resource.NonRetryableError(err) + } + return nil + } + } + if e != nil { + return resource.RetryableError(e) + } + return nil +} + +func resourceTencentCloudParamChange(ctx context.Context) (bool, error) { + d := tccommon.ResourceDataFromContext(ctx) + if d == nil { + return false, fmt.Errorf("resource data can not be nil") + } + meta := tccommon.ProviderMetaFromContext(ctx) + if meta == nil { + return false, fmt.Errorf("provider meta can not be nil") + } + + service := PostgresqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + respData, err := service.DescribePostgresqlParametersById(ctx, d.Id()) + if err != nil { + return false, err + } + + if respData == nil || respData.Detail == nil { + return false, fmt.Errorf("respData or respData.Detail be nil") + } + + change := false + for _, v := range respData.Detail { + for _, param := range d.Get("param_list").([]interface{}) { + paramMap := param.(map[string]interface{}) + if paramMap["name"].(string) == *v.Name { + if paramMap["expected_value"].(string) != *v.CurrentValue { + change = true + break + } + } + } + } + return change, nil +} + +func resourceTencentCloudPostgresqlParametersUpdatePreHandleResponse0(ctx context.Context, resp *postgresv20170312.ModifyDBInstanceParametersResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + if _, err := (&resource.StateChangeConf{ + Delay: 2 * time.Second, + MinTimeout: 3 * time.Second, + Pending: []string{}, + Refresh: resourcePostgresqlParametersUpdateStateRefreshFunc_0_0(ctx, d.Id()), + Target: []string{"Success"}, + Timeout: 300 * time.Second, + }).WaitForStateContext(ctx); err != nil { + return err + } + return nil +} + +func resourcePostgresqlParametersUpdateStateRefreshFunc_0_0(ctx context.Context, dBInstanceId string) resource.StateRefreshFunc { + var req *postgresv20170312.DescribeTasksRequest + return func() (interface{}, string, error) { + meta := tccommon.ProviderMetaFromContext(ctx) + if meta == nil { + return nil, "", fmt.Errorf("resource data can not be nil") + } + if req == nil { + d := tccommon.ResourceDataFromContext(ctx) + if d == nil { + return nil, "", fmt.Errorf("resource data can not be nil") + } + _ = d + req = postgresv20170312.NewDescribeTasksRequest() + req.DBInstanceId = helper.String(dBInstanceId) + + } + resp, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresV20170312Client().DescribeTasksWithContext(ctx, req) + if err != nil { + return nil, "", err + } + if resp == nil || resp.Response == nil { + return nil, "", nil + } + for _, task := range resp.Response.TaskSet { + if *task.TaskType == "ModifyInstanceParams" { + if *task.Status != "Success" { + return resp.Response, fmt.Sprintf("%v", *task.Status), nil + } + } + } + + return resp.Response, "Success", nil + } +} diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_test.go b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_test.go new file mode 100644 index 0000000000..8e1719d50b --- /dev/null +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_parameters_test.go @@ -0,0 +1,62 @@ +package postgresql_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" +) + +func TestAccTencentCloudPostgresqlParametersResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccPostgresqlParameters, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_postgresql_parameters.postgresql_parameters", "id"), + resource.TestCheckResourceAttr("tencentcloud_postgresql_parameters.postgresql_parameters", "param_list.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_postgresql_parameters.postgresql_parameters", "param_list.0.expected_value", "on"), + ), + }, + { + ResourceName: "tencentcloud_postgresql_parameters.postgresql_parameters", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccPostgresqlParametersUp, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("tencentcloud_postgresql_parameters.postgresql_parameters", "param_list.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_postgresql_parameters.postgresql_parameters", "param_list.0.expected_value", "off"), + ), + }, + }, + }) +} + +const testAccPostgresqlParameters = testAccPostgresqlInstancePostpaid + ` + +resource "tencentcloud_postgresql_parameters" "postgresql_parameters" { + db_instance_id = tencentcloud_postgresql_instance.test.id + param_list { + expected_value = "on" + name = "check_function_bodies" + } +} +` + +const testAccPostgresqlParametersUp = testAccPostgresqlInstancePostpaid + ` + +resource "tencentcloud_postgresql_parameters" "postgresql_parameters" { + db_instance_id = tencentcloud_postgresql_instance.test.id + param_list { + expected_value = "off" + name = "check_function_bodies" + } +} +` diff --git a/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go b/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go index dd00c69332..7231643c11 100644 --- a/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go +++ b/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" postgresql "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312" + postgresv20170312 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -2260,3 +2261,28 @@ func (me *PostgresqlService) DescribePostgresqlInstanceNetworkAccessById(ctx con ret = response.Response.DBInstance return } + +func (me *PostgresqlService) DescribePostgresqlParametersById(ctx context.Context, dBInstanceId string) (ret *postgresv20170312.DescribeDBInstanceParametersResponseParams, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := postgresv20170312.NewDescribeDBInstanceParametersRequest() + request.DBInstanceId = helper.String(dBInstanceId) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UsePostgresV20170312Client().DescribeDBInstanceParameters(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + ret = response.Response + return +} diff --git a/website/docs/r/postgresql_parameters.html.markdown b/website/docs/r/postgresql_parameters.html.markdown new file mode 100644 index 0000000000..43d396222a --- /dev/null +++ b/website/docs/r/postgresql_parameters.html.markdown @@ -0,0 +1,86 @@ +--- +subcategory: "TencentDB for PostgreSQL(PostgreSQL)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_postgresql_parameters" +sidebar_current: "docs-tencentcloud-resource-postgresql_parameters" +description: |- + Use this resource to create postgresql parameter. +--- + +# tencentcloud_postgresql_parameters + +Use this resource to create postgresql parameter. + +## Example Usage + +```hcl +variable "default_az" { + default = "ap-guangzhou-3" +} + +data "tencentcloud_vpc_subnets" "gz3" { + availability_zone = var.default_az + is_default = true +} + +locals { + vpc_id = data.tencentcloud_vpc_subnets.gz3.instance_list.0.vpc_id + subnet_id = data.tencentcloud_vpc_subnets.gz3.instance_list.0.subnet_id +} + +data "tencentcloud_availability_zones_by_product" "zone" { + product = "postgres" +} + +resource "tencentcloud_postgresql_instance" "test" { + name = "tf_postsql_postpaid" + availability_zone = var.default_az + charge_type = "POSTPAID_BY_HOUR" + period = 1 + vpc_id = local.vpc_id + subnet_id = local.subnet_id + engine_version = "13.3" + root_password = "t1qaA2k1wgvfa3?ZZZ" + security_groups = ["sg-5275dorp"] + charset = "LATIN1" + project_id = 0 + memory = 2 + storage = 20 +} +resource "tencentcloud_postgresql_parameters" "postgresql_parameters" { + db_instance_id = tencentcloud_postgresql_instance.test.id + param_list { + expected_value = "off" + name = "check_function_bodies" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `db_instance_id` - (Required, String, ForceNew) Instance ID. +* `param_list` - (Required, List) Parameters to be modified and expected values. + +The `param_list` object supports the following: + +* `expected_value` - (Required, String) The new value to which the parameter will be modified. When this parameter is used as an input parameter, its value must be a string, such as `0.1` (decimal), `1000` (integer), and `replica` (enum). +* `name` - (Required, String) Parameter name. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +postgresql parameters can be imported, e.g. + +``` +$ terraform import tencentcloud_postgresql_parameters.example pgrogrp-lckioi2a +``` + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index b21f7994d0..07d6713c2a 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -6051,6 +6051,9 @@