Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DWS] add resource/opentelekomcloud_dws_cluster_v1.go #2061

Merged
merged 5 commits into from Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
170 changes: 170 additions & 0 deletions docs/resources/dws_cluster_v1.md
@@ -0,0 +1,170 @@
---
subcategory: "Data Warehouse Service (DWS)"
---

# opentelekomcloud_dws_cluster_v1

Manages Cluster in the Data Warehouse Service.

## Example Usage

### Dws Cluster Example

```hcl
variable "availability_zone" {}
variable "network_id" {}
variable "vpc_id" {}
variable "security_group_id" {}

resource "opentelekomcloud_dws_cluster_v1" "cluster_1" {
name = "my_dws_cluster"
user_name = "dbadmin"
user_pwd = "#dbadmin123"
node_type = "dws.m3.xlarge"
number_of_node = 3
network_id = var.network_id
security_group_id = var.security_group_id
vpc_id = var.vpc_id
availability_zone = var.availability_zone
port = 8899

public_ip {
public_bind_type = "auto_assign"
}
}
```

## Argument Reference

The following arguments are supported:

* `name` - (Required, String, ForceNew) Cluster name, which must be unique and contains 4 to 64 characters, which
consist of letters, digits, hyphens(-), or underscores(_) only and must start with a letter.

* `network_id` - (Required, String, ForceNew) Network ID, which is used for configuring cluster network.

* `node_type` - (Required, String, ForceNew) Node type.

* `number_of_node` - (Required, Int) Number of nodes in a cluster. The value ranges from 3 to 32. When expanding,
add at least 3 nodes.

* `security_group_id` - (Required, String, ForceNew) ID of a security group. The ID is used for configuring cluster
network.

* `user_name` - (Required, String, ForceNew) Administrator username for logging in to a data warehouse cluster The
administrator username must: Consist of lowercase letters, digits, or underscores. Start with a lowercase letter or
an underscore. Contain 1 to 63 characters. Cannot be a keyword of the DWS database.

* `vpc_id` - (Required, String, ForceNew) VPC ID, which is used for configuring cluster network.

* `user_pwd` - (Required, String) Administrator password for logging in to a data warehouse cluster A password
must conform to the following rules: Contains 8 to 32 characters. Cannot be the same as the username or the username
written in reverse order. Contains three types of the following:
Lowercase letters Uppercase letters Digits Special characters
~!@#%^&*()-_=+|[{}];:,<.>/?

* `enterprise_project_id` - (Optional, String, ForceNew) Specifies the enterprise project id of the dws cluster,
Value 0 indicates the default enterprise project.
Changing this parameter will create a new resource.

* `availability_zone` - (Optional, String, ForceNew) AZ in a cluster.

* `port` - (Optional, Int) Service port of a cluster (8000 to 10000). The default value is 8000.

* `public_ip` - (Optional, List, ForceNew) A nested object resource Structure is documented below.

The `public_ip` block supports:

* `eip_id` - (Optional, String, ForceNew) EIP ID.

* `public_bind_type` - (Optional, String, ForceNew) Binding type of an EIP. The value can be either of the following:
`auto_assign` `not_use` `bind_existing` The default value is `not_use`.

* `number_of_cn` - (Optional, int, ForceNew) Specifies the number of CN. If you use a large-scale cluster, deploy
multiple CNs.

* `keep_last_manual_snapshot` - (Optional, int, ForceNew) The number of latest manual snapshots that need to be retained for a cluster.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

* `created` - Cluster creation time. The format is ISO8601:YYYY-MM-DDThh:mm:ssZ

* `endpoints` - View the private network connection information about the cluster. Structure is documented below.

* `id` - Cluster ID

* `public_endpoints` - Public network connection information about the cluster. If the value is not specified, the
public network connection information is not used by default Structure is documented below.

* `recent_event` - The recent event number.

* `status` - Cluster status, which can be one of the following: CREATING AVAILABLE UNAVAILABLE CREATION FAILED.

* `sub_status` - Sub-status of clusters in the AVAILABLE state. The value can be one of the following: NORMAL READONLY
REDISTRIBUTING REDISTRIBUTION-FAILURE UNBALANCED UNBALANCED | READONLY DEGRADED DEGRADED | READONLY DEGRADED |
UNBALANCED UNBALANCED | REDISTRIBUTING UNBALANCED | REDISTRIBUTION-FAILURE READONLY | REDISTRIBUTION-FAILURE
UNBALANCED | READONLY | REDISTRIBUTION-FAILURE DEGRADED | REDISTRIBUTION-FAILURE DEGRADED | UNBALANCED |
REDISTRIBUTION-FAILURE DEGRADED | UNBALANCED | READONLY | REDISTRIBUTION-FAILURE DEGRADED | UNBALANCED | READONLY

* `task_status` - Cluster management task. The value can be one of the following:
RESTORING SNAPSHOTTING GROWING REBOOTING SETTING_CONFIGURATION CONFIGURING_EXT_DATASOURCE DELETING_EXT_DATASOURCE
REBOOT_FAILURE RESIZE_FAILURE

* `updated` - Last modification time of a cluster. The format is ISO8601:YYYY-MM-DDThh:mm:ssZ

* `version` - Data warehouse version.

* `private_ip` - List of private network IP address.

The `endpoints` block contains:

* `connect_info` - (Optional, String) Private network connection information.

* `jdbc_url` - (Optional, String)
JDBC URL. The following is the default format:
jdbc:postgresql://< connect_info>/<YOUR_DATABASE_NAME>

The `public_endpoints` block contains:

* `jdbc_url` - (Optional, String)
JDBC URL. The following is the default format:
jdbc:postgresql://< public_connect_info>/<YOUR_DATABASE_NAME>

* `public_connect_info` - (Optional, String)
Public network connection information.

## Timeouts

This resource provides the following timeouts configuration options:

* `create` - Default is 60 minute.
* `update` - Default is 60 minute.
* `delete` - Default is 60 minute.

## Import

Cluster can be imported using the following format:

```
$ terraform import opentelekomcloud_dws_cluster_v1.cluster_1 4ca46bf1-5c61-48ff-b4f3-0ad4e5e3ba90
```

Note that the imported state may not be identical to your resource definition, due to some attributes missing from the
API response, security or some other reason. The missing attributes include: `user_pwd`, `number_of_cn`.
It is generally recommended running `terraform plan` after importing a cluster.
You can then decide if changes should be applied to the cluster, or the resource definition
should be updated to align with the cluster. Also you can ignore changes as below.

```
resource "opentelekomcloud_dws_cluster_v1" "cluster_1" {
...

lifecycle {
ignore_changes = [
user_pwd, number_of_cn,
]
}
}
```
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -14,7 +14,7 @@ require (
github.com/jinzhu/copier v0.3.5
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/mitchellh/go-homedir v1.1.0
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123135116-3a75ec2da837
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123155616-6123409669db
github.com/unknwon/com v1.0.1
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -209,6 +209,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123135116-3a75ec2da837 h1:mxCr7nKsDMSwd8SLNItm4uG4PPjbGctWMvx0dIeIUUE=
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123135116-3a75ec2da837/go.mod h1:/QD0ZIzm3zMdE0iBSAP3+Z9eCViU2PgnQqp4KGrpR/M=
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123155616-6123409669db h1:rQQ7MA/ruBOwrHDIggH0RCK8UUsbLiNIbsd1ey6duAQ=
github.com/opentelekomcloud/gophertelekomcloud v0.5.28-0.20230123155616-6123409669db/go.mod h1:/QD0ZIzm3zMdE0iBSAP3+Z9eCViU2PgnQqp4KGrpR/M=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
@@ -0,0 +1,154 @@
package acceptance

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dws/v1/cluster"

"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/common"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/env"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common/cfg"
)

const resourceInstanceName = "opentelekomcloud_dws_cluster_v1.cluster_1"

func TestAccDwsClusterV1_basic(t *testing.T) {
var cls cluster.ClusterDetail
var clusterName = fmt.Sprintf("dws_cluster_%s", acctest.RandString(5))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { common.TestAccPreCheck(t) },
ProviderFactories: common.TestAccProviderFactories,
CheckDestroy: testAccCheckDwsV1ClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccDwsV1ClusterBasic(clusterName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDwsV1ClusterExists(resourceInstanceName, &cls),
resource.TestCheckResourceAttr(resourceInstanceName, "name", clusterName),
resource.TestCheckResourceAttr(resourceInstanceName, "number_of_node", "3"),
),
},
// {
// Config: testAccDwsV1ClusterUpdated(clusterName),
// Check: resource.ComposeTestCheckFunc(
// resource.TestCheckResourceAttr(resourceInstanceName, "name", clusterName),
// resource.TestCheckResourceAttr(resourceInstanceName, "number_of_node", "6"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not working?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uncommented, it is working but not often

// ),
// },
{
ResourceName: resourceInstanceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"user_pwd", "number_of_cn",
},
},
},
})
}

func testAccCheckDwsV1ClusterDestroy(s *terraform.State) error {
config := common.TestAccProvider.Meta().(*cfg.Config)
client, err := config.DwsV1Client(env.OS_REGION_NAME)
if err != nil {
return fmt.Errorf("error creating DWSv1 client: %w", err)
}

for _, rs := range s.RootModule().Resources {
if rs.Type != "opentelekomcloud_dws_cluster_v1" {
continue
}

_, err := cluster.ListClusterDetails(client, rs.Primary.ID)
if err == nil {
return fmt.Errorf("DWS cluster still exists")
}
}
return nil
}

func testAccCheckDwsV1ClusterExists(n string, cls *cluster.ClusterDetail) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("no ID is set")
}

config := common.TestAccProvider.Meta().(*cfg.Config)
dwsClient, err := config.DwsV1Client(env.OS_REGION_NAME)
if err != nil {
return fmt.Errorf("error creating DWSv1 client: %w", err)
}

v, err := cluster.ListClusterDetails(dwsClient, rs.Primary.ID)
if err != nil {
return fmt.Errorf("error getting cluster (%s): %w", rs.Primary.ID, err)
}

if v.Id != rs.Primary.ID {
return fmt.Errorf("DWS cluster not found")
}
*cls = *v
return nil
}
}

func testAccDwsV1ClusterBasic(clusterName string) string {
return fmt.Sprintf(`
%s

%s

resource "opentelekomcloud_dws_cluster_v1" "cluster_1" {
name = "%s"
user_name = "dbadmin"
user_pwd = "#dbadmin123"
node_type = "dws.m3.xlarge"
number_of_node = 3
network_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.network_id
security_group_id = data.opentelekomcloud_networking_secgroup_v2.default_secgroup.id
vpc_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.vpc_id
availability_zone = "%s"
port = 8899

public_ip {
public_bind_type = "auto_assign"
}
}
`, common.DataSourceSecGroupDefault, common.DataSourceSubnet, clusterName, env.OS_AVAILABILITY_ZONE)
}

// extend not stable, skip this for now
func testAccDwsV1ClusterUpdated(clusterName string) string {
return fmt.Sprintf(`
%s

%s

resource "opentelekomcloud_dws_cluster_v1" "cluster_1" {
name = "%s"
user_name = "dbadmin"
user_pwd = "#dbadmin1234"
node_type = "dws.m3.xlarge"
number_of_node = 6
network_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.network_id
security_group_id = data.opentelekomcloud_networking_secgroup_v2.default_secgroup.id
vpc_id = data.opentelekomcloud_vpc_subnet_v1.shared_subnet.vpc_id
availability_zone = "%s"
port = 8899

public_ip {
public_bind_type = "auto_assign"
}
}
`, common.DataSourceSecGroupDefault, common.DataSourceSubnet, clusterName, env.OS_AVAILABILITY_ZONE)
}
7 changes: 7 additions & 0 deletions opentelekomcloud/common/cfg/config.go
Expand Up @@ -1008,6 +1008,13 @@ func (c *Config) VpcEpV1Client(region string) (*golangsdk.ServiceClient, error)
})
}

func (c *Config) DwsV1Client(region string) (*golangsdk.ServiceClient, error) {
return openstack.NewDWSV1(c.HwClient, golangsdk.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}

func reconfigProjectName(src Config, projectName ProjectName) (*Config, error) {
config := &Config{}
if err := copier.Copy(config, &src); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions opentelekomcloud/provider.go
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/deh"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/dms"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/dns"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/dws"
"github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/ecs"
elbv2 "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/elb/v2"
elbv3 "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/services/elb/v3"
Expand Down Expand Up @@ -350,6 +351,7 @@ func Provider() *schema.Provider {
"opentelekomcloud_dns_zone_v2": dns.ResourceDNSZoneV2(),
"opentelekomcloud_dms_instance_v1": dms.ResourceDmsInstancesV1(),
"opentelekomcloud_dms_topic_v1": dms.ResourceDmsTopicsV1(),
"opentelekomcloud_dws_cluster_v1": dws.ResourceDcsInstanceV1(),
"opentelekomcloud_ecs_instance_v1": ecs.ResourceEcsInstanceV1(),
"opentelekomcloud_evs_volume_v3": evs.ResourceEvsStorageVolumeV3(),
"opentelekomcloud_fw_firewall_group_v2": fw.ResourceFWFirewallGroupV2(),
Expand Down
5 changes: 5 additions & 0 deletions opentelekomcloud/services/dws/common.go
@@ -0,0 +1,5 @@
package dws

const (
errCreationClient = "error creating OpenTelekomCloud DWSv1 client: %w"
)