diff --git a/flexibleengine/resource_flexibleengine_dcs_instance_v1.go b/flexibleengine/resource_flexibleengine_dcs_instance_v1.go index fe4732fa3..091caa259 100644 --- a/flexibleengine/resource_flexibleengine_dcs_instance_v1.go +++ b/flexibleengine/resource_flexibleengine_dcs_instance_v1.go @@ -3,6 +3,7 @@ package flexibleengine import ( "fmt" "log" + "strconv" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -43,7 +44,7 @@ func resourceDcsInstanceV1() *schema.Resource { ForceNew: true, }, "capacity": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Required: true, ForceNew: true, }, @@ -63,22 +64,14 @@ func resourceDcsInstanceV1() *schema.Resource { Required: true, ForceNew: true, }, - "security_group_id": { + "network_id": { Type: schema.TypeString, Required: true, + ForceNew: true, }, - "subnet_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"network_id"}, - Deprecated: "use network_id instead", - }, - "network_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"subnet_id"}, + "security_group_id": { + Type: schema.TypeString, + Optional: true, }, "available_zones": { Type: schema.TypeList, @@ -88,9 +81,10 @@ func resourceDcsInstanceV1() *schema.Resource { }, "instance_type": { Type: schema.TypeString, - ConflictsWith: []string{"product_id"}, ForceNew: true, Optional: true, + ConflictsWith: []string{"product_id"}, + Deprecated: "use product_id instead", }, "product_id": { Type: schema.TypeString, @@ -183,6 +177,20 @@ func resourceDcsInstanceV1() *schema.Resource { } } +func resourceDcsInstancesCheck(d *schema.ResourceData) error { + engineVersion := d.Get("engine_version").(string) + secGroupID := d.Get("security_group_id").(string) + + // check for Memcached and Redis 3.0 + if engineVersion == "3.0" { + if secGroupID == "" { + return fmt.Errorf("security_group_id is mandatory for this DCS instance") + } + } + + return nil +} + func getInstanceBackupPolicy(d *schema.ResourceData) *instances.InstanceBackupPolicy { backupAts := d.Get("backup_at").([]interface{}) ats := make([]int, len(backupAts)) @@ -233,6 +241,10 @@ func resourceDcsInstancesV1Create(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error creating FlexibleEngine dcs instance client: %s", err) } + if err := resourceDcsInstancesCheck(d); err != nil { + return err + } + no_password_access := "true" if d.Get("access_user").(string) != "" || d.Get("password").(string) != "" { no_password_access = "false" @@ -243,28 +255,18 @@ func resourceDcsInstancesV1Create(d *schema.ResourceData, meta interface{}) erro Description: d.Get("description").(string), Engine: d.Get("engine").(string), EngineVersion: d.Get("engine_version").(string), - Capacity: d.Get("capacity").(int), + Capacity: d.Get("capacity").(float64), NoPasswordAccess: no_password_access, Password: d.Get("password").(string), AccessUser: d.Get("access_user").(string), VPCID: d.Get("vpc_id").(string), + SubnetID: d.Get("network_id").(string), SecurityGroupID: d.Get("security_group_id").(string), AvailableZones: getAllAvailableZones(d), MaintainBegin: d.Get("maintain_begin").(string), MaintainEnd: d.Get("maintain_end").(string), } - subnet_id, subnet_ok := d.GetOk("subnet_id") - network_id, network_ok := d.GetOk("network_id") - if !subnet_ok && !network_ok { - return fmt.Errorf("one of subnet_id or network_id must be configured") - } - if subnet_ok { - createOpts.SubnetID = subnet_id.(string) - } else { - createOpts.SubnetID = network_id.(string) - } - product_id, product_ok := d.GetOk("product_id") instance_type, type_ok := d.GetOk("instance_type") if !product_ok && !type_ok { @@ -321,7 +323,7 @@ func resourceDcsInstancesV1Read(d *schema.ResourceData, meta interface{}) error } v, err := instances.Get(dcsV1Client, d.Id()).Extract() if err != nil { - return err + return CheckDeleted(d, err, "DCS instance") } log.Printf("[DEBUG] Dcs instance %s: %+v", d.Id(), v) @@ -330,7 +332,6 @@ func resourceDcsInstancesV1Read(d *schema.ResourceData, meta interface{}) error d.Set("name", v.Name) d.Set("engine", v.Engine) d.Set("engine_version", v.EngineVersion) - d.Set("capacity", v.Capacity) d.Set("used_memory", v.UsedMemory) d.Set("max_memory", v.MaxMemory) d.Set("port", v.Port) @@ -339,6 +340,7 @@ func resourceDcsInstancesV1Read(d *schema.ResourceData, meta interface{}) error d.Set("resource_spec_code", v.ResourceSpecCode) d.Set("internal_version", v.InternalVersion) d.Set("vpc_id", v.VPCID) + d.Set("network_id", v.SubnetID) d.Set("vpc_name", v.VPCName) d.Set("created_at", v.CreatedAt) d.Set("product_id", v.ProductID) @@ -353,11 +355,14 @@ func resourceDcsInstancesV1Read(d *schema.ResourceData, meta interface{}) error d.Set("access_user", v.AccessUser) d.Set("ip", v.IP) - if _, ok := d.GetOk("subnet_id"); ok { - d.Set("subnet_id", v.SubnetID) - } else { - d.Set("network_id", v.SubnetID) + // set capacity by Capacity and CapacityMinor + var capacity float64 = float64(v.Capacity) + if v.CapacityMinor != "" { + if minor, err := strconv.ParseFloat(v.CapacityMinor, 64); err == nil { + capacity += minor + } } + d.Set("capacity", capacity) return nil } @@ -368,6 +373,11 @@ func resourceDcsInstancesV1Update(d *schema.ResourceData, meta interface{}) erro if err != nil { return fmt.Errorf("Error updating FlexibleEngine dcs instance client: %s", err) } + + if err := resourceDcsInstancesCheck(d); err != nil { + return err + } + var updateOpts instances.UpdateOpts if d.HasChange("name") { updateOpts.Name = d.Get("name").(string) diff --git a/flexibleengine/resource_flexibleengine_dcs_instance_v1_test.go b/flexibleengine/resource_flexibleengine_dcs_instance_v1_test.go index f755846df..50e3392d6 100644 --- a/flexibleengine/resource_flexibleengine_dcs_instance_v1_test.go +++ b/flexibleengine/resource_flexibleengine_dcs_instance_v1_test.go @@ -87,37 +87,39 @@ func testAccCheckDcsV1InstanceExists(n string, instance instances.Instance) reso func testAccDcsV1Instance_basic(instanceName string) string { return fmt.Sprintf(` resource "flexibleengine_networking_secgroup_v2" "secgroup_1" { - name = "secgroup_1" + name = "secgroup_1" description = "secgroup_1" } - resource "flexibleengine_vpc_v1" "vpc_3" { - name = "terraform_provider_vpc3" - cidr= "192.168.0.0/16" + +resource "flexibleengine_vpc_v1" "vpc_1" { + name = "terraform_vpc1" + cidr = "192.168.0.0/16" } resource "flexibleengine_vpc_subnet_v1" "subnet_1" { - name = "flexibleengine_subnet" - cidr = "192.168.0.0/16" + name = "terraform_subnet" + cidr = "192.168.0.0/24" gateway_ip = "192.168.0.1" - vpc_id = flexibleengine_vpc_v1.vpc_3.id + vpc_id = flexibleengine_vpc_v1.vpc_1.id } resource "flexibleengine_dcs_instance_v1" "instance_1" { - name = "%s" - engine_version = "3.0" - password = "Huawei_test" - engine = "Redis" - capacity = 2 - vpc_id = flexibleengine_vpc_v1.vpc_3.id + name = "%s" + engine = "Redis" + engine_version = "3.0" + password = "Huawei_test" + product_id = "dcs.master_standby-h" + capacity = 2 + vpc_id = flexibleengine_vpc_v1.vpc_1.id + network_id = flexibleengine_vpc_subnet_v1.subnet_1.id security_group_id = flexibleengine_networking_secgroup_v2.secgroup_1.id - subnet_id = flexibleengine_vpc_subnet_v1.subnet_1.id - available_zones = ["eu-west-0a"] - instance_type = "dcs.master_standby" - save_days = 1 + available_zones = ["eu-west-0a"] + + save_days = 1 backup_type = "manual" - begin_at = "00:00-01:00" + begin_at = "00:00-01:00" period_type = "weekly" - backup_at = [1] + backup_at = [1] } `, instanceName) } diff --git a/go.mod b/go.mod index 3088c178b..e531f7193 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/terraform-plugin-sdk v1.0.0 - github.com/huaweicloud/golangsdk v0.0.0-20210205050659-642d3daa3d9f + github.com/huaweicloud/golangsdk v0.0.0-20210207050553-158e5bc3ef64 github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index ce01946c1..f447b3177 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,8 @@ github.com/huaweicloud/golangsdk v0.0.0-20210116064948-5bfe83790eb2 h1:S1zh1Z7Ja github.com/huaweicloud/golangsdk v0.0.0-20210116064948-5bfe83790eb2/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/huaweicloud/golangsdk v0.0.0-20210205050659-642d3daa3d9f h1:Ru5t1Mf0JLu0KzlDQ0V9grsBhf0BqxBgoEDIij3sa38= github.com/huaweicloud/golangsdk v0.0.0-20210205050659-642d3daa3d9f/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= +github.com/huaweicloud/golangsdk v0.0.0-20210207050553-158e5bc3ef64 h1:CHIzZqEyYFRY+Tro+AVR6EsnHrqs1AnxV1ol+ZCv8RY= +github.com/huaweicloud/golangsdk v0.0.0-20210207050553-158e5bc3ef64/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a h1:FyS/ubzBR5xJlnJGRTwe7GUHpJOR4ukYK3y+LFNffuA= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a/go.mod h1:uoIMjNxUfXi48Ci40IXkPRbghZ1vbti6v9LCbNqRgHY= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/requests.go index 1cbee26a5..87019dd18 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/requests.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/requests.go @@ -22,21 +22,21 @@ type CreateOps struct { // A brief description supports up to 1024 characters. Description string `json:"description,omitempty"` - // Cache engine, which is Redis. + // Cache engine, which is Redis or Memcached. Engine string `json:"engine" required:"true"` - // Cache engine version, which is 3.0.7. + // Cache engine version, When the cache engine is Redis, the value is 3.0, 4.0 or 5.0. EngineVersion string `json:"engine_version"` + // Cache capacity. Unit: GB. // Indicates the message storage space. - // Cache capacity. - - // Unit: GB. - // For a DCS Redis instance in single-node or master/standby mode, - // the cache capacity can be 2 GB, 4 GB, 8 GB, 16 GB, 32 GB, or 64 GB. - // For a DCS Redis instance in cluster mode, the cache capacity can be - // 64, 128, 256, 512, or 1024 GB. - Capacity int `json:"capacity" required:"true"` + // + // Redis 3.0: Stand-alone and active/standby type instance values: 2, 4, 8, 16, 32, 64. + // Proxy cluster instance specifications support 64, 128, 256, 512, and 1024. + // Redis4.0 and 5.0: Stand-alone and active/standby type instance values: 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64. + // Cluster instance specifications support 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024. + // Memcached: Stand-alone and active/standby type instance values: 2, 4, 8, 16, 32, 64. + Capacity float64 `json:"capacity" required:"true"` // Indicate if no password visit cache instance is allowed. NoPasswordAccess string `json:"no_password_access,omitempty"` @@ -62,7 +62,7 @@ type CreateOps struct { VPCID string `json:"vpc_id" required:"true"` // Tenant's security group ID. - SecurityGroupID string `json:"security_group_id" required:"true"` + SecurityGroupID string `json:"security_group_id,omitempty"` // Subnet ID. SubnetID string `json:"subnet_id" required:"true"` diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/results.go index 99043e900..adbb45d94 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/results.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dcs/v1/instances/results.go @@ -31,6 +31,7 @@ type Instance struct { Name string `json:"name"` Engine string `json:"engine"` Capacity int `json:"capacity"` + CapacityMinor string `json:"capacity_minor"` IP string `json:"ip"` Port int `json:"port"` Status string `json:"status"` diff --git a/vendor/modules.txt b/vendor/modules.txt index f154ce329..ec52d3d77 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -183,7 +183,7 @@ github.com/hashicorp/terraform-plugin-sdk/plugin github.com/hashicorp/terraform-plugin-sdk/terraform # github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d github.com/hashicorp/yamux -# github.com/huaweicloud/golangsdk v0.0.0-20210205050659-642d3daa3d9f +# github.com/huaweicloud/golangsdk v0.0.0-20210207050553-158e5bc3ef64 ## explicit github.com/huaweicloud/golangsdk github.com/huaweicloud/golangsdk/internal diff --git a/website/docs/r/dcs_instance_v1.html.markdown b/website/docs/r/dcs_instance_v1.html.markdown index 1b34f0359..e1e01c8f9 100644 --- a/website/docs/r/dcs_instance_v1.html.markdown +++ b/website/docs/r/dcs_instance_v1.html.markdown @@ -12,41 +12,63 @@ Manages a DCS instance in the flexibleengine DCS Service. ## Example Usage -### Automatically detect the correct network +### DCS instance for Redis 3.0 ```hcl resource "flexibleengine_networking_secgroup_v2" "secgroup_1" { - name = "secgroup_1" + name = "secgroup_1" description = "secgroup_1" } -resource "flexibleengine_vpc_v1" "vpc_3" { - name = "terraform_provider_vpc3" - cidr= "192.168.0.0/16" + +resource "flexibleengine_vpc_v1" "vpc_1" { + name = "test_vpc1" + cidr = "192.168.0.0/16" } resource "flexibleengine_vpc_subnet_v1" "subnet_1" { - name = "flexibleengine_subnet" - cidr = "192.168.0.0/16" + name = "test_subnet1" + cidr = "192.168.0.0/24" gateway_ip = "192.168.0.1" - vpc_id = flexibleengine_vpc_v1.vpc_3.id + vpc_id = flexibleengine_vpc_v1.vpc_1.id } resource "flexibleengine_dcs_instance_v1" "instance_1" { - name = "%s" - engine_version = "3.0" - password = var.password - engine = "Redis" - capacity = 2 - vpc_id = flexibleengine_vpc_v1.vpc_3.id + name = "test_dcs_instance" + engine = "Redis" + engine_version = "3.0" + password = var.my_password + product_id = "dcs.master_standby-h" + capacity = 2 + vpc_id = flexibleengine_vpc_v1.vpc_1.id + network_id = flexibleengine_vpc_subnet_v1.subnet_1.id security_group_id = flexibleengine_networking_secgroup_v2.secgroup_1.id - subnet_id = flexibleengine_vpc_subnet_v1.subnet_1.id - available_zones = ["eu-west-0a"] - instance_type = "dcs.master_standby" - save_days = 1 - backup_type = "manual" - begin_at = "00:00-01:00" - period_type = "weekly" - backup_at = [1] + available_zones = ["eu-west-0a"] + save_days = 1 + backup_type = "manual" + begin_at = "00:00-01:00" + period_type = "weekly" + backup_at = [1] +} +``` + +### DCS instance for Redis 5.0 + +```hcl +resource "flexibleengine_dcs_instance_v1" "instance_1" { + name = "test_dcs_instance" + engine = "Redis" + engine_version = "5.0" + password = var.my_password + product_id = "redis.cluster.xu1.large.r1.8-h" + capacity = 8 + vpc_id = flexibleengine_vpc.vpc_1.id + subnet_id = flexibleengine_vpc_subnet.subnet_1.id + available_zones = ["eu-west-0a", "eu-west-0b"] + save_days = 1 + backup_type = "manual" + begin_at = "00:00-01:00" + period_type = "weekly" + backup_at = [1] } ``` @@ -81,16 +103,12 @@ The following arguments are supported: The password of a DCS Redis instance must meet the following complexity requirements: Changing this creates a new instance. -* `vpc_id` - (Required) Tenant's VPC ID. For details on how to create VPCs, see the - Virtual Private Cloud API Reference. - Changing this creates a new instance. - -* `security_group_id` - (Required) Tenant's security group ID. For details on how to - create security groups, see the Virtual Private Cloud API Reference. +* `vpc_id` - (Required) Specifies the id of the VPC. Changing this creates a new instance. -* `subnet_id` - (Deprecated, Optional, conflict with `network_id`) Network ID. Changing this creates a new instance. +* `network_id` - (Required) Specifies the network id of the subnet. Changing this creates a new instance. -* `network_id` - (Optional, conflict with `subnet_id`) Network ID. Changing this creates a new instance. +* `security_group_id` - (Optional) Specifies the id of the security group which the instance belongs to. + This parameter is mandatory for Memcached and Redis 3.0 versions. * `available_zones` - (Required) IDs or Names of the AZs where cache nodes reside. For details on how to query AZs, see Querying AZ Information. @@ -136,7 +154,7 @@ For the whole list and the specification of product id please check the DCS API Changing this creates a new instance. -* `instance_type` - (Optional) DCS instance specification code. For example now there are following values available: +* `instance_type` - (Deprecated, Optional) DCS instance specification code. For example now there are following values available: - dcs.single_node - dcs.master_standby @@ -194,7 +212,6 @@ The following attributes are exported: * `vpc_name` - Indicates the name of a vpc. * `security_group_id` - See Argument Reference above. * `security_group_name` - Indicates the name of a security group. -* `subnet_id` - See Argument Reference above. * `subnet_name` - Indicates the name of a subnet. * `available_zones` - See Argument Reference above. * `product_id` - See Argument Reference above.