diff --git a/docs/resources/dds_instance.md b/docs/resources/dds_instance.md index 33443eb2aed..edf92c8d597 100644 --- a/docs/resources/dds_instance.md +++ b/docs/resources/dds_instance.md @@ -139,24 +139,27 @@ The `flavor` block supports: * For a Community Edition replica set instance, the value is replica. * For a Community Edition single node instance, the value is single. -* `num` - (Required, Int, ForceNew) Specifies the node quantity. Valid value: +* `num` - (Required, Int) Specifies the node quantity. Valid value: * In a Community Edition cluster instance,the number of mongos ranges from 2 to 16. * In a Community Edition cluster instance,the number of shards ranges from 2 to 16. * In an Enhanced Edition cluster instance, the number of shards ranges from 2 to 12. * config: the value is 1. * replica: the value is 1. * single: The value is 1. + This parameter can be updated when the value of `type` is mongos or shard. * `storage` - (Optional, String, ForceNew) Specifies the disk type. Valid value: ULTRAHIGH which indicates the type SSD. -* `size` - (Optional, Int, ForceNew) Specifies the disk size. The value must be a multiple of 10. The unit is GB. +* `size` - (Optional, Int) Specifies the disk size. The value must be a multiple of 10. The unit is GB. This parameter is mandatory for nodes except mongos and invalid for mongos. + This parameter can be updated when the value of `type` is shard, replica or single. -* `spec_code` - (Required, String, ForceNew) Specifies the resource specification code. In a cluster instance, +* `spec_code` - (Required, String) Specifies the resource specification code. In a cluster instance, multiple specifications need to be specified. All specifications must be of the same series, that is, general-purpose (s6), enhanced (c3), or enhanced II (c6). For example: * dds.mongodb.s6.large.4.mongos and dds.mongodb.s6.large.4.config have the same specifications. * dds.mongodb.s6.large.4.mongos and dds.mongodb.c3.large.4.config are not of the same specifications. + This parameter can be updated when the value of `type` is mongos, shard, replica or single. The `backup_strategy ` block supports: diff --git a/go.mod b/go.mod index ef971e075d2..fd789df1085 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/terraform-plugin-sdk v1.16.0 - github.com/huaweicloud/golangsdk v0.0.0-20210715061636-f0d85a483f0b + github.com/huaweicloud/golangsdk v0.0.0-20210721120754-82d566870da2 github.com/jen20/awspolicyequivalence v1.1.0 github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index de952958695..494dac33b84 100644 --- a/go.sum +++ b/go.sum @@ -206,10 +206,8 @@ github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/huaweicloud/golangsdk v0.0.0-20210714031135-2f101c51a35d h1:GJFDZ3hxptdDs10RjT1+Tq4oDsWXu+e2yNoHzLRgJ38= -github.com/huaweicloud/golangsdk v0.0.0-20210714031135-2f101c51a35d/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= -github.com/huaweicloud/golangsdk v0.0.0-20210715061636-f0d85a483f0b h1:s3ZJgf61mC4EaZp3OEMrC7hbZixXMr9JbFL5cgATB/o= -github.com/huaweicloud/golangsdk v0.0.0-20210715061636-f0d85a483f0b/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= +github.com/huaweicloud/golangsdk v0.0.0-20210721120754-82d566870da2 h1:dBwVW7sDLvSIqCG8hOFQoXW0nee30Kp4WMGAKwI37Lg= +github.com/huaweicloud/golangsdk v0.0.0-20210721120754-82d566870da2/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= diff --git a/huaweicloud/resource_huaweicloud_dds_instance_v3.go b/huaweicloud/resource_huaweicloud_dds_instance_v3.go index e8c5a672174..439534bf50b 100644 --- a/huaweicloud/resource_huaweicloud_dds_instance_v3.go +++ b/huaweicloud/resource_huaweicloud_dds_instance_v3.go @@ -1,6 +1,7 @@ package huaweicloud import ( + "fmt" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -24,6 +25,7 @@ func ResourceDdsInstanceV3() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), Delete: schema.DefaultTimeout(30 * time.Minute), }, @@ -126,7 +128,6 @@ func ResourceDdsInstanceV3() *schema.Resource { "num": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, "storage": { Type: schema.TypeString, @@ -139,12 +140,10 @@ func ResourceDdsInstanceV3() *schema.Resource { "size": { Type: schema.TypeInt, Optional: true, - ForceNew: true, }, "spec_code": { Type: schema.TypeString, Required: true, - ForceNew: true, }, }, }, @@ -529,7 +528,7 @@ func resourceDdsInstanceV3Update(d *schema.ResourceData, meta interface{}) error Pending: []string{"updating"}, Target: []string{"normal"}, Refresh: DdsInstanceStateRefreshFunc(client, d.Id()), - Timeout: d.Timeout(schema.TimeoutCreate), + Timeout: d.Timeout(schema.TimeoutUpdate), Delay: 15 * time.Second, MinTimeout: 10 * time.Second, } @@ -548,6 +547,33 @@ func resourceDdsInstanceV3Update(d *schema.ResourceData, meta interface{}) error } } + // update flavor + if d.HasChange("flavor") { + for i := range d.Get("flavor").([]interface{}) { + numIndex := fmt.Sprintf("flavor.%d.num", i) + volumeSizeIndex := fmt.Sprintf("flavor.%d.size", i) + specCodeIndex := fmt.Sprintf("flavor.%d.spec_code", i) + if d.HasChange(numIndex) { + err := flavorNumUpdate(client, d, i) + if err != nil { + return err + } + } + if d.HasChange(volumeSizeIndex) { + err := flavorSizeUpdate(client, d, i) + if err != nil { + return err + } + } + if d.HasChange(specCodeIndex) { + err := flavorSpecCodeUpdate(client, d, i) + if err != nil { + return err + } + } + } + } + return resourceDdsInstanceV3Read(d, meta) } @@ -567,7 +593,7 @@ func resourceDdsInstanceV3Delete(d *schema.ResourceData, meta interface{}) error Pending: []string{"normal", "abnormal", "frozen", "createfail", "enlargefail", "data_disk_full"}, Target: []string{"deleted"}, Refresh: DdsInstanceStateRefreshFunc(client, instanceId), - Timeout: d.Timeout(schema.TimeoutCreate), + Timeout: d.Timeout(schema.TimeoutDelete), Delay: 15 * time.Second, MinTimeout: 10 * time.Second, } @@ -601,3 +627,284 @@ func flattenDdsInstanceV3Nodes(dds instances.InstanceResponse) interface{} { } return nodesList } + +func getDdsInstanceV3ShardGroupID(client *golangsdk.ServiceClient, d *schema.ResourceData) ([]string, error) { + groupIDs := make([]string, 0) + + instanceID := d.Id() + opts := instances.ListInstanceOpts{ + Id: instanceID, + } + allPages, err := instances.List(client, &opts).AllPages() + if err != nil { + return groupIDs, fmtp.Errorf("Error fetching DDS instance: %s", err) + } + instances, err := instances.ExtractInstances(allPages) + if err != nil { + return groupIDs, fmtp.Errorf("Error extracting DDS instance: %s", err) + } + if instances.TotalCount == 0 { + logp.Printf("[WARN] DDS instance (%s) was not found", instanceID) + return groupIDs, nil + } + insts := instances.Instances + instance := insts[0] + + logp.Printf("[DEBUG] Retrieved instance %s: %#v", instanceID, instance) + + for _, group := range instance.Groups { + if group.Type == "shard" { + groupIDs = append(groupIDs, group.Id) + } + } + + return groupIDs, nil + +} + +func getDdsInstanceV3MongosNodeID(client *golangsdk.ServiceClient, d *schema.ResourceData) ([]string, error) { + nodeIDs := make([]string, 0) + + instanceID := d.Id() + opts := instances.ListInstanceOpts{ + Id: instanceID, + } + allPages, err := instances.List(client, &opts).AllPages() + if err != nil { + return nodeIDs, fmtp.Errorf("Error fetching DDS instance: %s", err) + } + instances, err := instances.ExtractInstances(allPages) + if err != nil { + return nodeIDs, fmtp.Errorf("Error extracting DDS instance: %s", err) + } + if instances.TotalCount == 0 { + logp.Printf("[WARN] DDS instance (%s) was not found", instanceID) + return nodeIDs, nil + } + insts := instances.Instances + instance := insts[0] + + logp.Printf("[DEBUG] Retrieved instance %s: %#v", instanceID, instance) + + for _, group := range instance.Groups { + if group.Type == "mongos" { + for _, node := range group.Nodes { + nodeIDs = append(nodeIDs, node.Id) + } + } + } + + return nodeIDs, nil + +} + +func flavorUpdate(client *golangsdk.ServiceClient, d *schema.ResourceData, opts []instances.UpdateOpt) error { + r := instances.Update(client, d.Id(), opts) + if r.Err != nil { + return fmtp.Errorf("Error updating instance from result: %s ", r.Err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"updating"}, + Target: []string{"normal"}, + Refresh: DdsInstanceStateRefreshFunc(client, d.Id()), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 15 * time.Second, + MinTimeout: 10 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + return fmtp.Errorf( + "Error waiting for instance (%s) to become ready: %s ", + d.Id(), err) + } + + return nil +} + +func flavorNumUpdate(client *golangsdk.ServiceClient, d *schema.ResourceData, i int) error { + groupTypeIndex := fmt.Sprintf("flavor.%d.type", i) + groupType := d.Get(groupTypeIndex).(string) + if groupType != "mongos" && groupType != "shard" { + return fmtp.Errorf("Error updating instance: %s does not support adding nodes", groupType) + } + specCodeIndex := fmt.Sprintf("flavor.%d.spec_code", i) + volumeSizeIndex := fmt.Sprintf("flavor.%d.size", i) + volumeSize := d.Get(volumeSizeIndex).(int) + numIndex := fmt.Sprintf("flavor.%d.num", i) + oldNumRaw, newNumRaw := d.GetChange(numIndex) + oldNum := oldNumRaw.(int) + newNum := newNumRaw.(int) + if newNum < oldNum { + return fmtp.Errorf("Error updating instance: the new num(%d) must be greater than the old num(%d)", newNum, oldNum) + } + + var numUpdateOpts []instances.UpdateOpt + + if groupType == "mongos" { + opt := instances.UpdateOpt{ + Param: "", + Value: instances.UpdateNodeNumOpts{ + Type: groupType, + SpecCode: d.Get(specCodeIndex).(string), + Num: newNum - oldNum, + }, + Action: "enlarge", + Method: "post", + } + numUpdateOpts = append(numUpdateOpts, opt) + } else { + volume := instances.UpdateVolumeOpts{ + Size: &volumeSize, + } + + opt := instances.UpdateOpt{ + Param: "", + Value: instances.UpdateNodeNumOpts{ + Type: groupType, + SpecCode: d.Get(specCodeIndex).(string), + Num: newNum - oldNum, + Volume: &volume, + }, + Action: "enlarge", + Method: "post", + } + numUpdateOpts = append(numUpdateOpts, opt) + } + err := flavorUpdate(client, d, numUpdateOpts) + if err != nil { + return err + } + return nil +} + +func flavorSizeUpdate(client *golangsdk.ServiceClient, d *schema.ResourceData, i int) error { + volumeSizeIndex := fmt.Sprintf("flavor.%d.size", i) + oldSizeRaw, newSizeRaw := d.GetChange(volumeSizeIndex) + oldSize := oldSizeRaw.(int) + newSize := newSizeRaw.(int) + if newSize < oldSize { + return fmtp.Errorf("Error updating instance: the new size(%d) must be greater than the old size(%d)", newSize, oldSize) + } + groupTypeIndex := fmt.Sprintf("flavor.%d.type", i) + groupType := d.Get(groupTypeIndex).(string) + if groupType != "replica" && groupType != "single" && groupType != "shard" { + return fmtp.Errorf("Error updating instance: %s does not support scaling up storage space", groupType) + } + + if groupType == "shard" { + groupIDs, err := getDdsInstanceV3ShardGroupID(client, d) + if err != nil { + return err + } + + for _, groupID := range groupIDs { + var sizeUpdateOpts []instances.UpdateOpt + opt := instances.UpdateOpt{ + Param: "volume", + Value: instances.UpdateVolumeOpts{ + GroupID: groupID, + Size: &newSize, + }, + Action: "enlarge-volume", + Method: "post", + } + sizeUpdateOpts = append(sizeUpdateOpts, opt) + err := flavorUpdate(client, d, sizeUpdateOpts) + if err != nil { + return err + } + } + } else { + var sizeUpdateOpts []instances.UpdateOpt + opt := instances.UpdateOpt{ + Param: "volume", + Value: instances.UpdateVolumeOpts{ + Size: &newSize, + }, + Action: "enlarge-volume", + Method: "post", + } + sizeUpdateOpts = append(sizeUpdateOpts, opt) + err := flavorUpdate(client, d, sizeUpdateOpts) + if err != nil { + return err + } + } + return nil +} + +func flavorSpecCodeUpdate(client *golangsdk.ServiceClient, d *schema.ResourceData, i int) error { + specCodeIndex := fmt.Sprintf("flavor.%d.spec_code", i) + groupTypeIndex := fmt.Sprintf("flavor.%d.type", i) + groupType := d.Get(groupTypeIndex).(string) + if groupType == "config" { + return fmtp.Errorf("Error updating instance: %s does not support updating spec_code", groupType) + } + if groupType == "mongos" { + nodeIDs, err := getDdsInstanceV3MongosNodeID(client, d) + if err != nil { + return err + } + for _, ID := range nodeIDs { + var specUpdateOpts []instances.UpdateOpt + opt := instances.UpdateOpt{ + Param: "resize", + Value: instances.UpdateSpecOpts{ + TargetType: "mongos", + TargetID: ID, + TargetSpecCode: d.Get(specCodeIndex).(string), + }, + Action: "resize", + Method: "post", + } + specUpdateOpts = append(specUpdateOpts, opt) + err := flavorUpdate(client, d, specUpdateOpts) + if err != nil { + return err + } + } + } else if groupType == "shard" { + groupIDs, err := getDdsInstanceV3ShardGroupID(client, d) + if err != nil { + return err + } + + for _, ID := range groupIDs { + var specUpdateOpts []instances.UpdateOpt + opt := instances.UpdateOpt{ + Param: "resize", + Value: instances.UpdateSpecOpts{ + TargetType: "shard", + TargetID: ID, + TargetSpecCode: d.Get(specCodeIndex).(string), + }, + Action: "resize", + Method: "post", + } + specUpdateOpts = append(specUpdateOpts, opt) + err := flavorUpdate(client, d, specUpdateOpts) + if err != nil { + return err + } + } + } else { + var specUpdateOpts []instances.UpdateOpt + opt := instances.UpdateOpt{ + Param: "resize", + Value: instances.UpdateSpecOpts{ + TargetID: d.Id(), + TargetSpecCode: d.Get(specCodeIndex).(string), + }, + Action: "resize", + Method: "post", + } + specUpdateOpts = append(specUpdateOpts, opt) + err := flavorUpdate(client, d, specUpdateOpts) + if err != nil { + return err + } + } + return nil +} diff --git a/huaweicloud/resource_huaweicloud_dds_instance_v3_test.go b/huaweicloud/resource_huaweicloud_dds_instance_v3_test.go index a111dbc738e..213940a95b0 100644 --- a/huaweicloud/resource_huaweicloud_dds_instance_v3_test.go +++ b/huaweicloud/resource_huaweicloud_dds_instance_v3_test.go @@ -14,7 +14,7 @@ import ( ) func TestAccDDSV3Instance_basic(t *testing.T) { - var instance instances.Instance + var instance instances.InstanceResponse rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) resourceName := "huaweicloud_dds_instance.instance" @@ -44,12 +44,36 @@ func TestAccDDSV3Instance_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "7"), ), }, + { + Config: testAccDDSInstanceV3Config_updateFlavorNum(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDDSV3InstanceExists(resourceName, &instance), + resource.TestCheckResourceAttr(resourceName, "name", rName), + testAccCheckDDSV3InstanceFlavor(&instance, "shard", "num", 3), + ), + }, + { + Config: testAccDDSInstanceV3Config_updateFlavorSize(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDDSV3InstanceExists(resourceName, &instance), + resource.TestCheckResourceAttr(resourceName, "name", rName), + testAccCheckDDSV3InstanceFlavor(&instance, "shard", "size", "30"), + ), + }, + { + Config: testAccDDSInstanceV3Config_updateFlavorSpecCode(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDDSV3InstanceExists(resourceName, &instance), + resource.TestCheckResourceAttr(resourceName, "name", rName), + testAccCheckDDSV3InstanceFlavor(&instance, "mongos", "spec_code", "dds.mongodb.c6.large.4.mongos"), + ), + }, }, }) } func TestAccDDSV3Instance_withEpsId(t *testing.T) { - var instance instances.Instance + var instance instances.InstanceResponse rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) resourceName := "huaweicloud_dds_instance.instance" @@ -102,7 +126,7 @@ func testAccCheckDDSV3InstanceDestroy(s *terraform.State) error { return nil } -func testAccCheckDDSV3InstanceExists(n string, instance *instances.Instance) resource.TestCheckFunc { +func testAccCheckDDSV3InstanceExists(n string, instance *instances.InstanceResponse) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -134,11 +158,76 @@ func testAccCheckDDSV3InstanceExists(n string, instance *instances.Instance) res return fmtp.Errorf("dds instance not found.") } + insts := instances.Instances + found := insts[0] + *instance = found + return nil } } -func testAccDDSInstanceV3Config_basic(rName string) string { +func testAccCheckDDSV3InstanceFlavor(instance *instances.InstanceResponse, groupType, key string, v interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + if key == "num" { + if groupType == "mongos" { + for _, group := range instance.Groups { + if group.Type == "mongos" { + if len(group.Nodes) != v.(int) { + return fmtp.Errorf( + "Error updating HuaweiCloud DDS instance: num of mongos nodes expect %d, but got %d", + v.(int), len(group.Nodes)) + } + return nil + } + } + } else { + groupIDs := make([]string, 0) + for _, group := range instance.Groups { + if group.Type == "shard" { + groupIDs = append(groupIDs, group.Id) + } + } + if len(groupIDs) != v.(int) { + return fmtp.Errorf( + "Error updating HuaweiCloud DDS instance: num of shard groups expect %d, but got %d", + v.(int), len(groupIDs)) + } + return nil + } + } + + if key == "size" { + for _, group := range instance.Groups { + if group.Type == groupType { + if group.Volume.Size != v.(string) { + return fmtp.Errorf( + "Error updating HuaweiCloud DDS instance: size expect %s, but got %s", + v.(string), group.Volume.Size) + } + return nil + } + } + } + + if key == "spec_code" { + for _, group := range instance.Groups { + if group.Type == groupType { + for _, node := range group.Nodes { + if node.SpecCode != v.(string) { + return fmtp.Errorf( + "Error updating HuaweiCloud DDS instance: spec_code expect %s, but got %s", + v.(string), node.SpecCode) + } + } + return nil + } + } + } + return nil + } +} + +func testAccDDSInstanceV3Config_Base(rName string) string { return fmt.Sprintf(` data "huaweicloud_availability_zones" "test" {} @@ -152,8 +241,13 @@ data "huaweicloud_vpc_subnet" "test" { resource "huaweicloud_networking_secgroup" "secgroup_acc" { name = "%s" +}`, rName) } +func testAccDDSInstanceV3Config_basic(rName string) string { + return fmt.Sprintf(` +%s + resource "huaweicloud_dds_instance" "instance" { name = "%s" availability_zone = data.huaweicloud_availability_zones.test.names[0] @@ -172,21 +266,21 @@ resource "huaweicloud_dds_instance" "instance" { flavor { type = "mongos" num = 2 - spec_code = "dds.mongodb.c3.medium.4.mongos" + spec_code = "dds.mongodb.c6.large.2.mongos" } flavor { type = "shard" num = 2 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.medium.4.shard" + spec_code = "dds.mongodb.c6.large.2.shard" } flavor { type = "config" num = 1 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.large.2.config" + spec_code = "dds.mongodb.c6.large.2.config" } backup_strategy { @@ -198,24 +292,12 @@ resource "huaweicloud_dds_instance" "instance" { foo = "bar" owner = "terraform" } -}`, rName, rName) +}`, testAccDDSInstanceV3Config_Base(rName), rName) } func testAccDDSInstanceV3Config_updateBackupStrategy(rName string) string { return fmt.Sprintf(` -data "huaweicloud_availability_zones" "test" {} - -data "huaweicloud_vpc" "test" { - name = "vpc-default" -} - -data "huaweicloud_vpc_subnet" "test" { - name = "subnet-default" -} - -resource "huaweicloud_networking_secgroup" "secgroup_acc" { - name = "%s" -} +%s resource "huaweicloud_dds_instance" "instance" { name = "%s" @@ -235,21 +317,21 @@ resource "huaweicloud_dds_instance" "instance" { flavor { type = "mongos" num = 2 - spec_code = "dds.mongodb.c3.medium.4.mongos" + spec_code = "dds.mongodb.c6.large.2.mongos" } flavor { type = "shard" num = 2 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.medium.4.shard" + spec_code = "dds.mongodb.c6.large.2.shard" } flavor { type = "config" num = 1 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.large.2.config" + spec_code = "dds.mongodb.c6.large.2.config" } backup_strategy { @@ -261,25 +343,166 @@ resource "huaweicloud_dds_instance" "instance" { foo = "bar" owner = "terraform" } -}`, rName, rName) +}`, testAccDDSInstanceV3Config_Base(rName), rName) } -func testAccDDSInstanceV3Config_withEpsId(rName string) string { +func testAccDDSInstanceV3Config_updateFlavorNum(rName string) string { return fmt.Sprintf(` -data "huaweicloud_availability_zones" "test" {} +%s -data "huaweicloud_vpc" "test" { - name = "vpc-default" +resource "huaweicloud_dds_instance" "instance" { + name = "%s" + availability_zone = data.huaweicloud_availability_zones.test.names[0] + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.secgroup_acc.id + password = "Test@123" + mode = "Sharding" + + datastore { + type = "DDS-Community" + version = "3.4" + storage_engine = "wiredTiger" + } + + flavor { + type = "mongos" + num = 2 + spec_code = "dds.mongodb.c6.large.2.mongos" + } + flavor { + type = "shard" + num = 3 + storage = "ULTRAHIGH" + size = 20 + spec_code = "dds.mongodb.c6.large.2.shard" + } + flavor { + type = "config" + num = 1 + storage = "ULTRAHIGH" + size = 20 + spec_code = "dds.mongodb.c6.large.2.config" + } + + backup_strategy { + start_time = "08:00-09:00" + keep_days = "8" + } + + tags = { + foo = "bar" + owner = "terraform" + } +}`, testAccDDSInstanceV3Config_Base(rName), rName) } -data "huaweicloud_vpc_subnet" "test" { - name = "subnet-default" +func testAccDDSInstanceV3Config_updateFlavorSize(rName string) string { + return fmt.Sprintf(` +%s + +resource "huaweicloud_dds_instance" "instance" { + name = "%s" + availability_zone = data.huaweicloud_availability_zones.test.names[0] + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.secgroup_acc.id + password = "Test@123" + mode = "Sharding" + + datastore { + type = "DDS-Community" + version = "3.4" + storage_engine = "wiredTiger" + } + + flavor { + type = "mongos" + num = 2 + spec_code = "dds.mongodb.c6.large.2.mongos" + } + flavor { + type = "shard" + num = 3 + storage = "ULTRAHIGH" + size = 30 + spec_code = "dds.mongodb.c6.large.2.shard" + } + flavor { + type = "config" + num = 1 + storage = "ULTRAHIGH" + size = 20 + spec_code = "dds.mongodb.c6.large.2.config" + } + + backup_strategy { + start_time = "08:00-09:00" + keep_days = "8" + } + + tags = { + foo = "bar" + owner = "terraform" + } +}`, testAccDDSInstanceV3Config_Base(rName), rName) } -resource "huaweicloud_networking_secgroup" "secgroup_acc" { - name = "%s" +func testAccDDSInstanceV3Config_updateFlavorSpecCode(rName string) string { + return fmt.Sprintf(` +%s + +resource "huaweicloud_dds_instance" "instance" { + name = "%s" + availability_zone = data.huaweicloud_availability_zones.test.names[0] + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.secgroup_acc.id + password = "Test@123" + mode = "Sharding" + + datastore { + type = "DDS-Community" + version = "3.4" + storage_engine = "wiredTiger" + } + + flavor { + type = "mongos" + num = 2 + spec_code = "dds.mongodb.c6.large.4.mongos" + } + flavor { + type = "shard" + num = 3 + storage = "ULTRAHIGH" + size = 30 + spec_code = "dds.mongodb.c6.large.2.shard" + } + flavor { + type = "config" + num = 1 + storage = "ULTRAHIGH" + size = 20 + spec_code = "dds.mongodb.c6.large.2.config" + } + + backup_strategy { + start_time = "08:00-09:00" + keep_days = "8" + } + + tags = { + foo = "bar" + owner = "terraform" + } +}`, testAccDDSInstanceV3Config_Base(rName), rName) } +func testAccDDSInstanceV3Config_withEpsId(rName string) string { + return fmt.Sprintf(` +%s + resource "huaweicloud_dds_instance" "instance" { name = "%s" availability_zone = data.huaweicloud_availability_zones.test.names[0] @@ -299,21 +522,21 @@ resource "huaweicloud_dds_instance" "instance" { flavor { type = "mongos" num = 2 - spec_code = "dds.mongodb.c3.medium.4.mongos" + spec_code = "dds.mongodb.c6.large.2.mongos" } flavor { type = "shard" num = 2 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.medium.4.shard" + spec_code = "dds.mongodb.c6.large.2.shard" } flavor { type = "config" num = 1 storage = "ULTRAHIGH" size = 20 - spec_code = "dds.mongodb.c3.large.2.config" + spec_code = "dds.mongodb.c6.large.2.config" } backup_strategy { @@ -325,5 +548,5 @@ resource "huaweicloud_dds_instance" "instance" { foo = "bar" owner = "terraform" } -}`, rName, rName, HW_ENTERPRISE_PROJECT_ID_TEST) +}`, testAccDDSInstanceV3Config_Base(rName), rName, HW_ENTERPRISE_PROJECT_ID_TEST) } diff --git a/vendor/github.com/huaweicloud/golangsdk/.travis.yml b/vendor/github.com/huaweicloud/golangsdk/.travis.yml deleted file mode 100644 index 23da127928b..00000000000 --- a/vendor/github.com/huaweicloud/golangsdk/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: go -sudo: false -install: -- go get golang.org/x/crypto/ssh -- go get -v ./... -- go get github.com/wadey/gocovmerge -- go get github.com/mattn/goveralls -- go get golang.org/x/tools/cmd/goimports -go: -- "1.13" -- "1.14" -- tip -env: - global: - - secure: "5XfjlctyrfCccnP8hSUFv3bmGsYTS912L" -before_script: -- go vet ./... -script: -- ./script/coverage -- ./script/format -after_success: -- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=cover.out diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dds/v3/instances/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dds/v3/instances/requests.go index 7e4b19f9bcf..05853b51d38 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/dds/v3/instances/requests.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dds/v3/instances/requests.go @@ -145,11 +145,34 @@ type UpdateOpt struct { Method string } +type UpdateVolumeOpts struct { + GroupID string `json:"group_id,omitempty"` + Size *int `json:"size,omitempty"` +} + +type UpdateNodeNumOpts struct { + Type string `json:"type" required:"true"` + SpecCode string `json:"spec_code" required:"true"` + Num int `json:"num" required:"true"` + Volume *UpdateVolumeOpts `json:"volume,omitempty"` +} + +type UpdateSpecOpts struct { + TargetType string `json:"target_type,omitempty"` + TargetID string `json:"target_id" required:"true"` + TargetSpecCode string `json:"target_spec_code" required:"true"` +} + func Update(client *golangsdk.ServiceClient, instanceId string, opts []UpdateOpt) (r UpdateInstanceResult) { for _, optRaw := range opts { url := modifyURL(client, instanceId, optRaw.Action) - body := map[string]interface{}{ - optRaw.Param: optRaw.Value, + var body interface{} + if optRaw.Param != "" { + body = map[string]interface{}{ + optRaw.Param: optRaw.Value, + } + } else { + body = optRaw.Value } var httpMethod func(string, interface{}, interface{}, *golangsdk.RequestOpts) (*http.Response, error) diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go index 25f94f2472e..37faa826d06 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go @@ -60,7 +60,7 @@ type ComponentOpts struct { type JobOpts struct { JobType int `json:"job_type" required:"true"` JobName string `json:"job_name" required:"true"` - JarPath string `json:"jar_path" required:"true"` + JarPath string `json:"jar_path,omitempty"` Arguments string `json:"arguments,omitempty"` Input string `json:"input,omitempty"` Output string `json:"output,omitempty"` diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go index 283e83c6f7c..6ba73586719 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go @@ -3,62 +3,67 @@ package cluster import "github.com/huaweicloud/golangsdk" type Cluster struct { - Clusterid string `json:"clusterId"` - Clustername string `json:"clusterName"` - Masternodenum string `json:"masterNodeNum"` - Corenodenum string `json:"coreNodeNum"` - Totalnodenum string `json:"totalNodeNum"` - Clusterstate string `json:"clusterState"` - Createat string `json:"createAt"` - Updateat string `json:"updateAt"` - Billingtype string `json:"billingType"` - Datacenter string `json:"dataCenter"` - Duration string `json:"duration"` - Fee string `json:"fee"` - Hadoopversion string `json:"hadoopVersion"` - Masternodesize string `json:"masterNodeSize"` - Corenodesize string `json:"coreNodeSize"` - Componentlist []Component `json:"componentList"` - Externalip string `json:"externalIp"` - Externalalternateip string `json:"externalAlternateIp"` - Internalip string `json:"internalIp"` - Deploymentid string `json:"deploymentId"` - Remark string `json:"remark"` - Orderid string `json:"orderId"` - Azid string `json:"azId"` - Azname string `json:"azName"` - Masternodeproductid string `json:"masterNodeProductId"` - Masternodespecid string `json:"masterNodeSpecId"` - Corenodeproductid string `json:"coreNodeProductId"` - Corenodespecid string `json:"coreNodeSpecId"` - Instanceid string `json:"instanceId"` - Vnc string `json:"vnc"` - Tenantid string `json:"tenantId"` - Volumesize int `json:"volumeSize"` - Vpc string `json:"vpc"` - Vpcid string `json:"vpcId"` - Subnetid string `json:"subnetId"` - Subnetname string `json:"subnetName"` - Securitygroupsid string `json:"securityGroupsId"` - Slavesecuritygroupsid string `json:"slaveSecurityGroupsId"` - Stagedesc string `json:"stageDesc"` - Safemode int `json:"safeMode"` - Clusterversion string `json:"clusterVersion"` - Nodepubliccertname string `json:"nodePublicCertName"` - Masternodeip string `json:"masterNodeIp"` - Privateipfirst string `json:"privateIpFirst"` - Errorinfo string `json:"errorInfo"` - Chargingstarttime string `json:"chargingStartTime"` - LogCollection int `json:"logCollection"` - TaskNodeGroups []NodeGroup `json:"taskNodeGroups"` - NodeGroups []NodeGroup `json:"nodeGroups"` - MasterDataVolumeType string `json:"masterDataVolumeType"` - MasterDataVolumeSize int `json:"masterDataVolumeSize"` - MasterDataVolumeCount int `json:"masterDataVolumeCount"` - CoreDataVolumeType string `json:"coreDataVolumeType"` - CoreDataVolumeSize int `json:"coreDataVolumeSize"` - CoreDataVolumeCount int `json:"coreDataVolumeCount"` - BootstrapScripts []ScriptOpts `json:"bootstrapScripts"` + Clusterid string `json:"clusterId"` + Clustername string `json:"clusterName"` + Masternodenum string `json:"masterNodeNum"` + Corenodenum string `json:"coreNodeNum"` + Totalnodenum string `json:"totalNodeNum"` + Clusterstate string `json:"clusterState"` + Createat string `json:"createAt"` + Updateat string `json:"updateAt"` + Billingtype string `json:"billingType"` + Datacenter string `json:"dataCenter"` + Duration string `json:"duration"` + Fee string `json:"fee"` + Hadoopversion string `json:"hadoopVersion"` + Masternodesize string `json:"masterNodeSize"` + Corenodesize string `json:"coreNodeSize"` + Componentlist []Component `json:"componentList"` + Externalip string `json:"externalIp"` + Externalalternateip string `json:"externalAlternateIp"` + Internalip string `json:"internalIp"` + Deploymentid string `json:"deploymentId"` + Remark string `json:"remark"` + Orderid string `json:"orderId"` + Azid string `json:"azId"` + Azname string `json:"azName"` + Masternodeproductid string `json:"masterNodeProductId"` + Masternodespecid string `json:"masterNodeSpecId"` + Corenodeproductid string `json:"coreNodeProductId"` + Corenodespecid string `json:"coreNodeSpecId"` + Instanceid string `json:"instanceId"` + Vnc string `json:"vnc"` + Tenantid string `json:"tenantId"` + Volumesize int `json:"volumeSize"` + Vpc string `json:"vpc"` + Vpcid string `json:"vpcId"` + Subnetid string `json:"subnetId"` + Subnetname string `json:"subnetName"` + Securitygroupsid string `json:"securityGroupsId"` + Slavesecuritygroupsid string `json:"slaveSecurityGroupsId"` + Stagedesc string `json:"stageDesc"` + Safemode int `json:"safeMode"` + Clusterversion string `json:"clusterVersion"` + ClusterType int `json:"clusterType"` + Nodepubliccertname string `json:"nodePublicCertName"` + Masternodeip string `json:"masterNodeIp"` + Privateipfirst string `json:"privateIpFirst"` + Errorinfo string `json:"errorInfo"` + Chargingstarttime string `json:"chargingStartTime"` + LogCollection int `json:"logCollection"` + TaskNodeGroups []NodeGroup `json:"taskNodeGroups"` + NodeGroups []NodeGroup `json:"nodeGroups"` + MasterDataVolumeType string `json:"masterDataVolumeType"` + MasterDataVolumeSize int `json:"masterDataVolumeSize"` + MasterDataVolumeCount int `json:"masterDataVolumeCount"` + CoreDataVolumeType string `json:"coreDataVolumeType"` + CoreDataVolumeSize int `json:"coreDataVolumeSize"` + CoreDataVolumeCount int `json:"coreDataVolumeCount"` + BootstrapScripts []BootStrapScript `json:"bootstrapScripts"` + EnterpriseProjectId string `json:"enterpriseProjectId"` + IsMrsManagerFinish bool `json:"ismrsManagerFinish"` + PeriodType int `json:"periodType"` + Scale string `json:"scale"` } type Component struct { @@ -69,18 +74,34 @@ type Component struct { } type NodeGroup struct { - GroupName string `json:"groupName"` - NodeNum int `json:"nodeNum"` - NodeSize string `json:"nodeSize"` - NodeSpecId string `json:"nodeSpecId"` - NodeProductId string `json:"nodeProductId"` - VMProductId string `json:"vmProductId"` - VMSpecCode string `json:"vmSpecCode"` - RootVolumeSize int `json:"rootVolumeSize"` - RootVolumeType string `json:"rootVolumeType"` - DataVolumeType string `json:"dataVolumeType"` - DataVolumeSize int `json:"dataVolumeSize"` - DataVolumeCount int `json:"dataVolumeCount"` + GroupName string `json:"groupName"` + NodeNum int `json:"nodeNum"` + NodeSize string `json:"nodeSize"` + NodeSpecId string `json:"nodeSpecId"` + NodeProductId string `json:"nodeProductId"` + VMProductId string `json:"vmProductId"` + VMSpecCode string `json:"vmSpecCode"` + RootVolumeSize int `json:"rootVolumeSize"` + RootVolumeType string `json:"rootVolumeType"` + RootVolumeProductId string `json:"rootVolumeProductId"` + RootVolumeResourceSpecCode string `json:"rootVolumeResourceSpecCode"` + DataVolumeType string `json:"dataVolumeType"` + DataVolumeSize int `json:"dataVolumeSize"` + DataVolumeCount int `json:"dataVolumeCount"` + DataVolumeResourceSpecCode string `json:"dataVolumeResourceSpecCode"` + DataVolumeResourceType string `json:"dataVolumeResourceType"` +} + +type BootStrapScript struct { + Name string `json:"name"` + Uri string `json:"uri"` + Parameters string `json:"parameters"` + Nodes []string `json:"nodes"` + ActiveMaster bool `json:"active_master"` + BeforeComponentStart bool `json:"before_component_start"` + FailAction string `json:"fail_action"` + StartTime string `json:"start_time"` + State string `json:"state"` } type ClusterResult struct { diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/scm/v3/certificates/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/scm/v3/certificates/requests.go index d4c65ea7478..0710e2948ee 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/scm/v3/certificates/requests.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/scm/v3/certificates/requests.go @@ -1,8 +1,9 @@ package certificates import ( - "github.com/huaweicloud/golangsdk" "strings" + + "github.com/huaweicloud/golangsdk" ) // ImportOptsBuilder is the interface options structs have to satisfy in order diff --git a/vendor/modules.txt b/vendor/modules.txt index abb921d0eab..55668a6157a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -267,7 +267,7 @@ github.com/hashicorp/terraform-svchost/auth github.com/hashicorp/terraform-svchost/disco # github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d github.com/hashicorp/yamux -# github.com/huaweicloud/golangsdk v0.0.0-20210715061636-f0d85a483f0b +# github.com/huaweicloud/golangsdk v0.0.0-20210721120754-82d566870da2 ## explicit github.com/huaweicloud/golangsdk github.com/huaweicloud/golangsdk/internal