Skip to content

Commit

Permalink
feat(mongodb): [115436303]support mongodb update node number (#2531)
Browse files Browse the repository at this point in the history
* support mongodb update node number

* add changelog

---------

Co-authored-by: mikatong <[email protected]>
  • Loading branch information
tongyiming and mikatong authored Feb 20, 2024
1 parent 2a86e77 commit 9c1b568
Show file tree
Hide file tree
Showing 15 changed files with 1,251 additions and 876 deletions.
3 changes: 3 additions & 0 deletions .changelog/2531.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/tencentcloud_mongodb_instance: support params `add_node_list` and `remove_node_list`
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/lighthouse v1.0.729
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.777
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mariadb v1.0.672
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mongodb v1.0.651
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mongodb v1.0.828
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/monitor v1.0.844
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/organization v1.0.856
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mps v1.0.853
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/monitor v1.0.839 h1:eRI
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/monitor v1.0.839/go.mod h1:4OoBA087NHVdyeRJFy/SML7kIJmt54DtNkNlJWZp8oE=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/monitor v1.0.844 h1:ZR7FSnv4k1j0BpJHg6JDbJ6YJ2YfLhX2xVIUcuweKm4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/monitor v1.0.844/go.mod h1:a7PfDWl0B3QV+g99asQHumDNScEEMl+7lkXP0KXt8Xg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mongodb v1.0.828 h1:ck4fIo8e7HlMQmIh77r8rbUjZCiCuO4DJ7KYAjHQ/Ws=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mongodb v1.0.828/go.mod h1:pnGYJR0EUzVMjcGdecYwsU+UUKrrHBM8kDgJHAwCOK4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mps v1.0.777 h1:SoH/KkqkEUw8iDmQDZCw5Saf319Ceyt3v8Vqodo8DiY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mps v1.0.777/go.mod h1:sBmwqD3GkczHFiArdYpHPp9QriIbzNtO99DueYVyGwE=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mps v1.0.853 h1:abGpWsAtEuF2QIYKm2m9/hv9OqyHwWNLsd5+67z86BE=
Expand Down
16 changes: 8 additions & 8 deletions tencentcloud/acctest/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,17 +818,17 @@ locals {

// MongoDB
const (
DefaultMongoDBVPCId = "vpc-rwj54lfr"
DefaultMongoDBSubnetId = "subnet-nyt57zps"
DefaultMongoDBVPCId = "vpc-axrsmmrv"
DefaultMongoDBSubnetId = "subnet-9hcctbue"
)
const DefaultMongoDBSecurityGroupId = "sg-if748odn"
const DefaultMongoDBSpec = `
data "tencentcloud_mongodb_zone_config" "zone_config" {
available_zone = "ap-guangzhou-6"
available_zone = "ap-guangzhou-3"
}
data "tencentcloud_security_group" "foo" {
name = "default"
name = "keep-mongodb-sg"
}
variable "engine_versions" {
Expand All @@ -850,22 +850,22 @@ variable "subnet_id" {
}
locals {
filtered_spec = [for i in data.tencentcloud_mongodb_zone_config.zone_config.list: i if lookup(i, "machine_type") == "HIO10G" && lookup(i, "engine_version") != "3.2"]
filtered_spec = [for i in data.tencentcloud_mongodb_zone_config.zone_config.list: i if lookup(i, "machine_type") == "HIO10G" && lookup(i, "engine_version") == "4.4" && lookup(i, "memory") == 4096 && lookup(i, "default_storage") == 256000]
spec = concat(local.filtered_spec, data.tencentcloud_mongodb_zone_config.zone_config.list)
machine_type = local.spec.0.machine_type
cluster_type = local.spec.0.cluster_type
memory = local.spec.0.memory / 1024
volume = local.spec.0.min_storage / 1024
volume = local.spec.0.default_storage / 1000
engine_version = lookup(var.engine_versions, local.spec.0.engine_version)
security_group_id = data.tencentcloud_security_group.foo.id
}
locals {
filtered_sharding_spec = [for i in data.tencentcloud_mongodb_zone_config.zone_config.list: i if lookup(i, "cluster_type") == "SHARD" && lookup(i, "min_replicate_set_num") > 0 && lookup(i, "machine_type") == "HIO10G" && lookup(i, "engine_version") != "3.2"]
filtered_sharding_spec = [for i in data.tencentcloud_mongodb_zone_config.zone_config.list: i if lookup(i, "cluster_type") == "SHARD" && lookup(i, "min_replicate_set_num") > 0 && lookup(i, "machine_type") == "HIO10G" && lookup(i, "engine_version") == "4.4" && lookup(i, "memory") == 4096 && lookup(i, "default_storage") == 256000]
sharding_spec = concat(local.filtered_sharding_spec, [for i in data.tencentcloud_mongodb_zone_config.zone_config.list: i if lookup(i, "cluster_type") == "SHARD" && lookup(i, "min_replicate_set_num") > 0])
sharding_machine_type = local.sharding_spec.0.machine_type
sharding_memory = local.sharding_spec.0.memory / 1024
sharding_volume = local.sharding_spec.0.min_storage / 1024
sharding_volume = local.sharding_spec.0.default_storage / 1000
sharding_engine_version = lookup(var.engine_versions, local.sharding_spec.0.engine_version)
}
`
Expand Down
4 changes: 4 additions & 0 deletions tencentcloud/services/mongodb/extension_mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const (
MONGODB_TASK_SUCCESS = "success"
)

const (
MONGODB_STATUS_DELIVERY_SUCCESS = 4
)

func TencentMongodbBasicInfo() map[string]*schema.Schema {
return map[string]*schema.Schema{
"instance_name": {
Expand Down
99 changes: 85 additions & 14 deletions tencentcloud/services/mongodb/resource_tc_mongodb_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
mongodb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mongodb/v20190725"

"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
Expand Down Expand Up @@ -48,6 +49,59 @@ func ResourceTencentCloudMongodbInstance() *schema.Resource {
Computed: true,
Description: "The number of nodes in each replica set. Default value: 3.",
},
"add_node_list": {
Type: schema.TypeList,
Optional: true,
Description: "Add node attribute list.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role": {
Type: schema.TypeString,
Required: true,
Description: "The node role that needs to be added.\n" +
"- SECONDARY: Mongod node;\n" +
"- READONLY: read-only node;\n" +
"- MONGOS: Mongos node.",
},
"zone": {
Type: schema.TypeString,
Required: true,
Description: "The availability zone corresponding to the node.\n" +
"- single availability zone, where all nodes are in the same availability zone;\n" +
"- multiple availability zones: the current standard specification is the distribution of three availability zones, and the master and slave nodes are not in the same availability zone. You should pay attention to configuring the availability zone corresponding to the new node, and the rule that the number of nodes in any two availability zones is greater than the third availability zone must be met after the addition.",
},
},
},
},
"remove_node_list": {
Type: schema.TypeList,
Optional: true,
Description: "Add node attribute list.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role": {
Type: schema.TypeString,
Required: true,
Description: "The node role that needs to be deleted.\n" +
"- SECONDARY: Mongod node;\n" +
"- READONLY: read-only node;\n" +
"- MONGOS: Mongos node.",
},
"node_name": {
Type: schema.TypeString,
Required: true,
Description: "The node ID to delete. The shard cluster must specify the name of the node to be deleted by a group of shards, and the rest of the shards should be grouped and aligned.",
},
"zone": {
Type: schema.TypeString,
Required: true,
Description: "The availability zone corresponding to the node.\n" +
"- single availability zone, where all nodes are in the same availability zone;\n" +
"- multiple availability zones: the current standard specification is the distribution of three availability zones, and the master and slave nodes are not in the same availability zone. You should pay attention to configuring the availability zone corresponding to the new node, and the rule that the number of nodes in any two availability zones is greater than the third availability zone must be met after the addition.",
},
},
},
},
"availability_zone_list": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -446,36 +500,53 @@ func resourceTencentCloudMongodbInstanceUpdate(d *schema.ResourceData, meta inte

d.Partial(true)

immutableArgs := []string{"node_num", "availability_zone_list", "hidden_zone"}
immutableArgs := []string{"availability_zone_list", "hidden_zone"}

for _, v := range immutableArgs {
if d.HasChange(v) {
return fmt.Errorf("argument `%s` cannot be changed", v)
}
}

if d.HasChange("memory") || d.HasChange("volume") {
if d.HasChange("memory") || d.HasChange("volume") || d.HasChange("node_num") {
memory := d.Get("memory").(int)
volume := d.Get("volume").(int)
err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume)
params := make(map[string]interface{})
var nodeNum int
if v, ok := d.GetOk("node_num"); ok {
nodeNum = v.(int)
params["node_num"] = nodeNum
}
if v, ok := d.GetOk("add_node_list"); ok {
addNodeList := v.([]interface{})
params["add_node_list"] = addNodeList
}
if v, ok := d.GetOk("remove_node_list"); ok {
removeNodeList := v.([]interface{})
params["remove_node_list"] = removeNodeList
}
dealId, err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume, params)
if err != nil {
return err
}

// it will take time to wait for memory and volume change even describe request succeeded even the status returned in describe response is running
if dealId == "" {
return fmt.Errorf("deal id is empty")
}

errUpdate := resource.Retry(20*tccommon.ReadRetryTimeout, func() *resource.RetryError {
infos, has, e := mongodbService.DescribeInstanceById(ctx, instanceId)
if e != nil {
return resource.NonRetryableError(e)
}
if !has {
return resource.NonRetryableError(fmt.Errorf("[CRITAL]%s updating mongodb instance failed, instance doesn't exist", logId))
dealResponseParams, err := mongodbService.DescribeDBInstanceDeal(ctx, dealId)
if err != nil {
if sdkError, ok := err.(*errors.TencentCloudSDKError); ok {
if sdkError.Code == "InvalidParameter" && sdkError.Message == "deal resource not found." {
return resource.RetryableError(err)
}
}
return resource.NonRetryableError(err)
}

memoryDes := *infos.Memory / 1024 / (*infos.ReplicationSetNum)
volumeDes := *infos.Volume / 1024 / (*infos.ReplicationSetNum)
if memory != int(memoryDes) || volume != int(volumeDes) {
return resource.RetryableError(fmt.Errorf("[CRITAL] updating mongodb instance, current memory and volume values: %d, %d, waiting for them becoming new value: %d, %d", memoryDes, volumeDes, d.Get("memory").(int), d.Get("volume").(int)))
if *dealResponseParams.Status != MONGODB_STATUS_DELIVERY_SUCCESS {
return resource.RetryableError(fmt.Errorf("mongodb status is not delivery success"))
}
return nil
})
Expand Down
66 changes: 47 additions & 19 deletions tencentcloud/services/mongodb/resource_tc_mongodb_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ func TestAccTencentCloudMongodbInstanceResourcePostPaid(t *testing.T) {
CheckDestroy: testAccCheckMongodbInstanceDestroy,
Steps: []resource.TestStep{
{
PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
Config: testAccMongodbInstance,
Config: testAccMongodbInstance,
Check: resource.ComposeTestCheckFunc(
testAccCheckMongodbInstanceExists("tencentcloud_mongodb_instance.mongodb"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "instance_name", "tf-mongodb-test"),
Expand All @@ -102,20 +101,25 @@ func TestAccTencentCloudMongodbInstanceResourcePostPaid(t *testing.T) {
{
ResourceName: "tencentcloud_mongodb_instance.mongodb",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"security_groups", "password", "auto_renew_flag"},
},
{
SkipFunc: func() (bool, error) {
log.Printf("[WARN] MongoDB Update Need DealID query available, skip checking.")
return true, nil
},
PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
Config: testAccMongodbInstance_update,
Config: testAccMongodbInstance_updateConfig,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "instance_name", "tf-mongodb-update"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "memory", "8"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "volume", "200"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "volume", "512"),
resource.TestCheckNoResourceAttr("tencentcloud_mongodb_instance.mongodb", "tags.test"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "tags.abc", "abc"),
),
},
{
Config: testAccMongodbInstance_updateNode,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "instance_name", "tf-mongodb-update"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "memory", "8"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "volume", "512"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "node_num", "5"),
resource.TestCheckNoResourceAttr("tencentcloud_mongodb_instance.mongodb", "tags.test"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb", "tags.abc", "abc"),
),
Expand All @@ -132,8 +136,7 @@ func TestAccTencentCloudMongodbInstanceResource_multiZone(t *testing.T) {
CheckDestroy: testAccCheckMongodbInstanceDestroy,
Steps: []resource.TestStep{
{
PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
Config: testAccMongodbInstance_multiZone,
Config: testAccMongodbInstance_multiZone,
Check: resource.ComposeTestCheckFunc(
testAccCheckMongodbInstanceExists("tencentcloud_mongodb_instance.mongodb_mutil_zone"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb_mutil_zone", "node_num", "5"),
Expand All @@ -148,12 +151,11 @@ func TestAccTencentCloudMongodbInstanceResource_multiZone(t *testing.T) {
func TestAccTencentCloudMongodbInstanceResourcePrepaid(t *testing.T) {
// Avoid to set Parallel to make sure EnvVar secure
resource.Test(t, resource.TestCase{
PreCheck: func() { tcacctest.AccPreCheckCommon(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
PreCheck: func() { tcacctest.AccPreCheck(t) },
Providers: tcacctest.AccProviders,
Steps: []resource.TestStep{
{
PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
Config: testAccMongodbInstancePrepaid,
Config: testAccMongodbInstancePrepaid,
Check: resource.ComposeTestCheckFunc(
testAccCheckMongodbInstanceExists("tencentcloud_mongodb_instance.mongodb_prepaid"),
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb_prepaid", "instance_name", "tf-mongodb-test-prepaid"),
Expand All @@ -174,8 +176,7 @@ func TestAccTencentCloudMongodbInstanceResourcePrepaid(t *testing.T) {
),
},
{
PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_PREPAY) },
Config: testAccMongodbInstancePrepaid_update,
Config: testAccMongodbInstancePrepaid_update,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("tencentcloud_mongodb_instance.mongodb_prepaid", "instance_name", "tf-mongodb-test-prepaid-update"),
resource.TestCheckNoResourceAttr("tencentcloud_mongodb_instance.mongodb_prepaid", "tags.test"),
Expand All @@ -185,7 +186,6 @@ func TestAccTencentCloudMongodbInstanceResourcePrepaid(t *testing.T) {
{
ResourceName: "tencentcloud_mongodb_instance.mongodb_prepaid",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"security_groups", "password", "auto_renew_flag", "prepaid_period"},
},
},
Expand Down Expand Up @@ -258,7 +258,7 @@ resource "tencentcloud_mongodb_instance" "mongodb" {
}
`

const testAccMongodbInstance_update = tcacctest.DefaultMongoDBSpec + `
const testAccMongodbInstance_updateConfig = tcacctest.DefaultMongoDBSpec + `
resource "tencentcloud_mongodb_instance" "mongodb" {
instance_name = "tf-mongodb-update"
memory = local.memory * 2
Expand All @@ -271,7 +271,35 @@ resource "tencentcloud_mongodb_instance" "mongodb" {
password = "test1234update"
vpc_id = var.vpc_id
subnet_id = var.subnet_id
tags = {
abc = "abc"
}
}
`

const testAccMongodbInstance_updateNode = tcacctest.DefaultMongoDBSpec + `
resource "tencentcloud_mongodb_instance" "mongodb" {
instance_name = "tf-mongodb-update"
memory = local.memory * 2
volume = local.volume * 2
engine_version = local.engine_version
machine_type = local.machine_type
security_groups = [local.security_group_id]
available_zone = "ap-guangzhou-3"
project_id = 0
password = "test1234update"
vpc_id = var.vpc_id
subnet_id = var.subnet_id
node_num = 5
add_node_list {
role = "SECONDARY"
zone = "ap-guangzhou-3"
}
add_node_list {
role = "SECONDARY"
zone = "ap-guangzhou-3"
}
tags = {
abc = "abc"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ func resourceMongodbShardingInstanceUpdate(d *schema.ResourceData, meta interfac
if d.HasChange("memory") || d.HasChange("volume") {
memory := d.Get("memory").(int)
volume := d.Get("volume").(int)
err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume)
_, err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume, nil)
if err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ func resourceTencentCloudMongodbStandbyInstanceUpdate(d *schema.ResourceData, me
if d.HasChange("memory") || d.HasChange("volume") {
memory := d.Get("memory").(int)
volume := d.Get("volume").(int)
err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume)
_, err := mongodbService.UpgradeInstance(ctx, instanceId, memory, volume, nil)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 9c1b568

Please sign in to comment.