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

New Data Source: aws_redshift_orderable_cluster #15438

Merged
merged 1 commit into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions aws/data_source_aws_redshift_orderable_cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package aws

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceAwsRedshiftOrderableCluster() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsRedshiftOrderableClusterRead,
Schema: map[string]*schema.Schema{
"availability_zones": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"cluster_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"cluster_version": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"node_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"preferred_node_types": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func dataSourceAwsRedshiftOrderableClusterRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).redshiftconn

input := &redshift.DescribeOrderableClusterOptionsInput{}

if v, ok := d.GetOk("cluster_version"); ok {
input.ClusterVersion = aws.String(v.(string))
}

if v, ok := d.GetOk("node_type"); ok {
input.NodeType = aws.String(v.(string))
}

var orderableClusterOptions []*redshift.OrderableClusterOption

err := conn.DescribeOrderableClusterOptionsPages(input, func(page *redshift.DescribeOrderableClusterOptionsOutput, lastPage bool) bool {
for _, orderableClusterOption := range page.OrderableClusterOptions {
if orderableClusterOption == nil {
continue
}

if v, ok := d.GetOk("cluster_type"); ok {
if aws.StringValue(orderableClusterOption.ClusterType) != v.(string) {
continue
}
}

orderableClusterOptions = append(orderableClusterOptions, orderableClusterOption)
}
return !lastPage
})

if err != nil {
return fmt.Errorf("error reading Redshift Orderable Cluster Options: %w", err)
}

if len(orderableClusterOptions) == 0 {
return fmt.Errorf("no Redshift Orderable Cluster Options found matching criteria; try different search")
}

var orderableClusterOption *redshift.OrderableClusterOption
preferredNodeTypes := d.Get("preferred_node_types").([]interface{})
if len(preferredNodeTypes) > 0 {
for _, preferredNodeTypeRaw := range preferredNodeTypes {
preferredNodeType, ok := preferredNodeTypeRaw.(string)

if !ok {
continue
}

for _, option := range orderableClusterOptions {
if preferredNodeType == aws.StringValue(option.NodeType) {
orderableClusterOption = option
break
}
}

if orderableClusterOption != nil {
break
}
}
}

if orderableClusterOption == nil && len(orderableClusterOptions) > 1 {
return fmt.Errorf("multiple Redshift Orderable Cluster Options (%v) match the criteria; try a different search", orderableClusterOptions)
}

if orderableClusterOption == nil && len(orderableClusterOptions) == 1 {
orderableClusterOption = orderableClusterOptions[0]
}

if orderableClusterOption == nil {
return fmt.Errorf("no Redshift Orderable Cluster Options match the criteria; try a different search")
}

d.SetId(aws.StringValue(orderableClusterOption.NodeType))

var availabilityZones []string
for _, az := range orderableClusterOption.AvailabilityZones {
availabilityZones = append(availabilityZones, aws.StringValue(az.Name))
}
d.Set("availability_zones", availabilityZones)

d.Set("cluster_type", orderableClusterOption.ClusterType)
d.Set("cluster_version", orderableClusterOption.ClusterVersion)
d.Set("node_type", orderableClusterOption.NodeType)

return nil
}
141 changes: 141 additions & 0 deletions aws/data_source_aws_redshift_orderable_cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccAWSRedshiftOrderableClusterDataSource_ClusterType(t *testing.T) {
dataSourceName := "data.aws_redshift_orderable_cluster.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRedshiftOrderableClusterPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRedshiftOrderableClusterDataSourceConfig_ClusterType("multi-node"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "cluster_type", "multi-node"),
),
},
},
})
}

func TestAccAWSRedshiftOrderableClusterDataSource_ClusterVersion(t *testing.T) {
dataSourceName := "data.aws_redshift_orderable_cluster.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRedshiftOrderableClusterPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRedshiftOrderableClusterDataSourceConfig_ClusterVersion("1.0"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "cluster_version", "1.0"),
),
},
},
})
}

func TestAccAWSRedshiftOrderableClusterDataSource_NodeType(t *testing.T) {
dataSourceName := "data.aws_redshift_orderable_cluster.test"
nodeType := "dc2.8xlarge"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRedshiftOrderableClusterPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRedshiftOrderableClusterDataSourceConfig_NodeType(nodeType),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "node_type", nodeType),
),
},
},
})
}

func TestAccAWSRedshiftOrderableClusterDataSource_PreferredNodeTypes(t *testing.T) {
dataSourceName := "data.aws_redshift_orderable_cluster.test"
preferredNodeType := "dc2.8xlarge"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRedshiftOrderableClusterPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRedshiftOrderableClusterDataSourceConfig_PreferredNodeTypes(preferredNodeType),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "node_type", preferredNodeType),
),
},
},
})
}

func testAccAWSRedshiftOrderableClusterPreCheck(t *testing.T) {
conn := testAccProvider.Meta().(*AWSClient).redshiftconn

input := &redshift.DescribeOrderableClusterOptionsInput{
MaxRecords: aws.Int64(20),
}

_, err := conn.DescribeOrderableClusterOptions(input)

if testAccPreCheckSkipError(err) {
t.Skipf("skipping acceptance testing: %s", err)
}

if err != nil {
t.Fatalf("unexpected PreCheck error: %s", err)
}
}

func testAccAWSRedshiftOrderableClusterDataSourceConfig_ClusterType(clusterType string) string {
return fmt.Sprintf(`
data "aws_redshift_orderable_cluster" "test" {
cluster_type = %[1]q
preferred_node_types = ["dc2.large", "ds2.xlarge"]
}
`, clusterType)
}

func testAccAWSRedshiftOrderableClusterDataSourceConfig_ClusterVersion(clusterVersion string) string {
return fmt.Sprintf(`
data "aws_redshift_orderable_cluster" "test" {
cluster_version = %[1]q
preferred_node_types = ["dc2.8xlarge", "ds2.8xlarge"]
}
`, clusterVersion)
}

func testAccAWSRedshiftOrderableClusterDataSourceConfig_NodeType(nodeType string) string {
return fmt.Sprintf(`
data "aws_redshift_orderable_cluster" "test" {
node_type = %[1]q
preferred_node_types = ["dc2.8xlarge", "ds2.8xlarge"]
}
`, nodeType)
}

func testAccAWSRedshiftOrderableClusterDataSourceConfig_PreferredNodeTypes(preferredNodeType string) string {
return fmt.Sprintf(`
data "aws_redshift_orderable_cluster" "test" {
preferred_node_types = [
"non-existent",
%[1]q,
"try-again",
]
}
`, preferredNodeType)
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ func Provider() *schema.Provider {
"aws_rds_engine_version": dataSourceAwsRdsEngineVersion(),
"aws_rds_orderable_db_instance": dataSourceAwsRdsOrderableDbInstance(),
"aws_redshift_cluster": dataSourceAwsRedshiftCluster(),
"aws_redshift_orderable_cluster": dataSourceAwsRedshiftOrderableCluster(),
"aws_redshift_service_account": dataSourceAwsRedshiftServiceAccount(),
"aws_region": dataSourceAwsRegion(),
"aws_regions": dataSourceAwsRegions(),
Expand Down
35 changes: 35 additions & 0 deletions website/docs/d/redshift_orderable_cluster.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
subcategory: "Redshift"
layout: "aws"
page_title: "AWS: aws_redshift_orderable_cluster"
description: |-
Information about RDS orderable DB instances.
---

# Data Source: aws_redshift_orderable_cluster

Information about Redshift Orderable Clusters and valid parameter combinations.

## Example Usage

```hcl
data "aws_redshift_orderable_cluster" "test" {
cluster_type = "multi-node"
preferred_node_types = ["dc2.large", "ds2.xlarge"]
}
```

## Argument Reference

The following arguments are supported:

* `cluster_type` - (Optional) Reshift Cluster type. e.g. `multi-node` or `single-node`
* `cluster_version` - (Optional) Redshift Cluster version. e.g. `1.0`
* `node_type` - (Optional) Redshift Cluster node type. e.g. `dc2.8xlarge`
* `preferred_node_types` - (Optional) Ordered list of preferred Redshift Cluster node types. The first match in this list will be returned. If no preferred matches are found and the original search returned more than one result, an error is returned.

## Attribute Reference

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

* `availability_zones` - List of Availability Zone names where the Redshit Cluster is available.