From fe524794fabec9150db9017a99df2a54b0170198 Mon Sep 17 00:00:00 2001 From: houpeng80 <114376095+houpeng80@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:52:38 +0800 Subject: [PATCH] feat(GaussDB): add gaussdb opengauss instance restart resource (#6044) --- .../gaussdb_opengauss_instance_restart.md | 43 +++++++ huaweicloud/provider.go | 1 + ...gaussdb_opengauss_instance_restart_test.go | 115 +++++++++++++++++ ...loud_gaussdb_opengauss_instance_restart.go | 121 ++++++++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 docs/resources/gaussdb_opengauss_instance_restart.md create mode 100644 huaweicloud/services/acceptance/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart_test.go create mode 100644 huaweicloud/services/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart.go diff --git a/docs/resources/gaussdb_opengauss_instance_restart.md b/docs/resources/gaussdb_opengauss_instance_restart.md new file mode 100644 index 0000000000..330971dff0 --- /dev/null +++ b/docs/resources/gaussdb_opengauss_instance_restart.md @@ -0,0 +1,43 @@ +--- +subcategory: "GaussDB" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_gaussdb_opengauss_instance_restart" +description: |- + Manages a GaussDB OpenGauss instance restart resource within HuaweiCloud. +--- + +# huaweicloud_gaussdb_opengauss_instance_restart + +Manages a GaussDB OpenGauss instance restart resource within HuaweiCloud. + +## Example Usage + +```hcl +variable "instance_id" {} + +resource "huaweicloud_gaussdb_opengauss_instance_restart" "test" { + instance_id = var.instance_id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource. + If omitted, the provider-level region will be used. Changing this parameter will create a new resource. + +* `instance_id` - (Required, String, ForceNew) Specifies the ID of the GaussDB OpenGauss instance. Changing this parameter + will create a new resource. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The resource ID which equals to the `instance_id`. + +## Timeouts + +This resource provides the following timeouts configuration options: + +* `create` - Default is 30 minutes. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 761e5a5374..31d9a82485 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -1745,6 +1745,7 @@ func Provider() *schema.Provider { "huaweicloud_gaussdb_mysql_instant_task_delete": taurusdb.ResourceGaussDBInstantTaskDelete(), "huaweicloud_gaussdb_opengauss_instance": gaussdb.ResourceOpenGaussInstance(), + "huaweicloud_gaussdb_opengauss_instance_restart": gaussdb.ResourceOpenGaussInstanceRestart(), "huaweicloud_gaussdb_opengauss_database": gaussdb.ResourceOpenGaussDatabase(), "huaweicloud_gaussdb_opengauss_backup": gaussdb.ResourceGaussDBOpenGaussBackup(), "huaweicloud_gaussdb_opengauss_backup_stop": gaussdb.ResourceOpenGaussBackupStop(), diff --git a/huaweicloud/services/acceptance/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart_test.go b/huaweicloud/services/acceptance/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart_test.go new file mode 100644 index 0000000000..96e9a20f51 --- /dev/null +++ b/huaweicloud/services/acceptance/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart_test.go @@ -0,0 +1,115 @@ +package gaussdb + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance/common" +) + +func TestAccOpenGaussInstanceRestart_basic(t *testing.T) { + var obj interface{} + rName := acceptance.RandomAccResourceNameWithDash() + resourceName := "huaweicloud_gaussdb_opengauss_instance_restart.test" + + rc := acceptance.InitResourceCheck( + resourceName, + &obj, + getOpenGaussInstanceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.TestAccPreCheck(t) }, + ProviderFactories: acceptance.TestAccProviderFactories, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccOpenGaussInstanceRestart_basic(rName), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + ), + }, + }, + }) +} + +func testAccOpenGaussInstanceRestart_base(rName string) string { + return fmt.Sprintf(` +%[1]s + +data "huaweicloud_availability_zones" "test" {} + +resource "huaweicloud_networking_secgroup_rule" "in_v4_tcp_opengauss" { + security_group_id = huaweicloud_networking_secgroup.test.id + ethertype = "IPv4" + direction = "ingress" + protocol = "tcp" + remote_ip_prefix = "0.0.0.0/0" +} + +resource "huaweicloud_networking_secgroup_rule" "in_v4_tcp_opengauss_egress" { + security_group_id = huaweicloud_networking_secgroup.test.id + ethertype = "IPv4" + direction = "egress" + protocol = "tcp" + remote_ip_prefix = "0.0.0.0/0" +} + +resource "huaweicloud_gaussdb_opengauss_instance" "test" { + depends_on = [ + huaweicloud_networking_secgroup_rule.in_v4_tcp_opengauss, + huaweicloud_networking_secgroup_rule.in_v4_tcp_opengauss_egress + ] + + vpc_id = huaweicloud_vpc.test.id + subnet_id = huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + + flavor = "gaussdb.bs.s6.xlarge.x864.ha" + name = "%[2]s" + password = "Huangwei!120521" + replica_num = 3 + availability_zone = join(",", [data.huaweicloud_availability_zones.test.names[0], + data.huaweicloud_availability_zones.test.names[1], + data.huaweicloud_availability_zones.test.names[2]]) + + enterprise_project_id = "%[3]s" + + ha { + mode = "centralization_standard" + replication_mode = "sync" + consistency = "eventual" + instance_mode = "basic" + } + + volume { + type = "ULTRAHIGH" + size = 40 + } +} + +resource "huaweicloud_vpc_eip" "test" { + publicip { + type = "5_bgp" + } + bandwidth { + name = "%[2]s" + size = 8 + share_type = "PER" + charge_mode = "traffic" + } +} +`, common.TestBaseNetwork(rName), rName, acceptance.HW_ENTERPRISE_PROJECT_ID_TEST) +} + +func testAccOpenGaussInstanceRestart_basic(rName string) string { + return fmt.Sprintf(` +%[1]s + +resource "huaweicloud_gaussdb_opengauss_instance_restart" "test" { + instance_id = huaweicloud_gaussdb_opengauss_instance.test.id +}`, testAccOpenGaussInstanceRestart_base(rName)) +} diff --git a/huaweicloud/services/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart.go b/huaweicloud/services/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart.go new file mode 100644 index 0000000000..1cb9a00f65 --- /dev/null +++ b/huaweicloud/services/gaussdb/resource_huaweicloud_gaussdb_opengauss_instance_restart.go @@ -0,0 +1,121 @@ +package gaussdb + +import ( + "context" + "net/http" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/chnsz/golangsdk" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/common" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// @API GaussDB POST /v3/{project_id}/instances/{instance_id}/restart +// @API GaussDB POST /v3/{project_id}/instances/{instance_id}/nodes/{node_id}/restart +// @API GaussDB GET /v3/{project_id}/jobs +func ResourceOpenGaussInstanceRestart() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceOpenGaussInstanceRestartCreate, + ReadContext: resourceOpenGaussInstanceRestartRead, + DeleteContext: resourceOpenGaussInstanceRestartDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "instance_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceOpenGaussInstanceRestartCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + cfg := meta.(*config.Config) + region := cfg.GetRegion(d) + + var ( + httpUrl = "v3/{project_id}/instances/{instance_id}/restart" + product = "opengauss" + ) + client, err := cfg.NewServiceClient(product, region) + if err != nil { + return diag.Errorf("error creating GaussDB client: %s", err) + } + + instanceId := d.Get("instance_id").(string) + createPath := client.Endpoint + httpUrl + createPath = strings.ReplaceAll(createPath, "{project_id}", client.ProjectID) + createPath = strings.ReplaceAll(createPath, "{instance_id}", instanceId) + + createOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + } + + retryFunc := func() (interface{}, bool, error) { + res, err := client.Request("POST", createPath, &createOpt) + retry, err := handleMultiOperationsError(err) + return res, retry, err + } + r, err := common.RetryContextWithWaitForState(&common.RetryContextWithWaitForStateParam{ + Ctx: ctx, + RetryFunc: retryFunc, + WaitFunc: instanceStateRefreshFunc(client, instanceId), + WaitTarget: []string{"ACTIVE"}, + Timeout: d.Timeout(schema.TimeoutCreate), + DelayTimeout: 10 * time.Second, + PollInterval: 10 * time.Second, + }) + if err != nil { + return diag.Errorf("error restarting GaussDB OpenGauss instance(%s): %s", instanceId, err) + } + + d.SetId(instanceId) + + createRespBody, err := utils.FlattenResponse(r.(*http.Response)) + if err != nil { + return diag.FromErr(err) + } + + jobId := utils.PathSearch("job_id", createRespBody, nil) + if jobId == nil { + return diag.Errorf("error restarting GaussDB OpenGauss instance(%s), job_id is not found in the response", + instanceId) + } + err = checkGaussDBOpenGaussJobFinish(ctx, client, jobId.(string), 2, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceOpenGaussInstanceRestartRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { + return nil +} + +func resourceOpenGaussInstanceRestartDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { + errorMsg := "Deleting GaussDB OpenGauss restart resource is not supported. The restart resource is only removed " + + "from the state, the GaussDB OpenGauss instance remains in the cloud." + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: errorMsg, + }, + } +}