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

data-source/aws_rds_orderable_db_instance: New data source #14853

Merged
merged 1 commit into from
Aug 31, 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
291 changes: 291 additions & 0 deletions aws/data_source_aws_rds_orderable_db_instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
package aws

import (
"fmt"
"log"

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

func dataSourceAwsRdsOrderableDbInstance() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsRdsOrderableDbInstanceRead,
Schema: map[string]*schema.Schema{
"availability_zone_group": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"availability_zones": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},

"db_instance_class": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"engine": {
Type: schema.TypeString,
Required: true,
},

"engine_version": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"license_model": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"max_iops_per_db_instance": {
Type: schema.TypeInt,
Computed: true,
},

"max_iops_per_gib": {
Type: schema.TypeFloat,
Computed: true,
},

"max_storage_size": {
Type: schema.TypeInt,
Computed: true,
},

"min_iops_per_db_instance": {
Type: schema.TypeInt,
Computed: true,
},

"min_iops_per_gib": {
Type: schema.TypeFloat,
Computed: true,
},

"min_storage_size": {
Type: schema.TypeInt,
Computed: true,
},

"multi_az_capable": {
Type: schema.TypeBool,
Computed: true,
},

"outpost_capable": {
Type: schema.TypeBool,
Computed: true,
},

"preferred_db_instance_classes": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},

"read_replica_capable": {
Type: schema.TypeBool,
Computed: true,
},

"storage_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"supported_engine_modes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},

"supports_enhanced_monitoring": {
Type: schema.TypeBool,
Computed: true,
},

"supports_global_databases": {
Type: schema.TypeBool,
Computed: true,
},

"supports_iam_database_authentication": {
Type: schema.TypeBool,
Computed: true,
},

"supports_iops": {
Type: schema.TypeBool,
Computed: true,
},

"supports_kerberos_authentication": {
Type: schema.TypeBool,
Computed: true,
},

"supports_performance_insights": {
Type: schema.TypeBool,
Computed: true,
},

"supports_storage_autoscaling": {
Type: schema.TypeBool,
Computed: true,
},

"supports_storage_encryption": {
Type: schema.TypeBool,
Computed: true,
},

"vpc": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
},
}
}

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

input := &rds.DescribeOrderableDBInstanceOptionsInput{}

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

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

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

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

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

if v, ok := d.GetOk("vpc"); ok {
input.Vpc = aws.Bool(v.(bool))
}

log.Printf("[DEBUG] Reading RDS Orderable DB Instance Options: %v", input)
var instanceClassResults []*rds.OrderableDBInstanceOption

err := conn.DescribeOrderableDBInstanceOptionsPages(input, func(resp *rds.DescribeOrderableDBInstanceOptionsOutput, lastPage bool) bool {
for _, instanceOption := range resp.OrderableDBInstanceOptions {
if instanceOption == nil {
continue
}

if v, ok := d.GetOk("storage_type"); ok {
if aws.StringValue(instanceOption.StorageType) != v.(string) {
continue
}
}

instanceClassResults = append(instanceClassResults, instanceOption)
}
return !lastPage
})

if err != nil {
return fmt.Errorf("error reading RDS orderable DB instance options: %w", err)
}

if len(instanceClassResults) == 0 {
return fmt.Errorf("no RDS Orderable DB Instance options found matching criteria; try different search")
}

// preferred classes
var found *rds.OrderableDBInstanceOption
if l := d.Get("preferred_db_instance_classes").([]interface{}); len(l) > 0 {
for _, elem := range l {
preferredInstanceClass, ok := elem.(string)

if !ok {
continue
}

for _, instanceClassResult := range instanceClassResults {
if preferredInstanceClass == aws.StringValue(instanceClassResult.DBInstanceClass) {
found = instanceClassResult
break
}
}

if found != nil {
break
}
}
}

if found == nil && len(instanceClassResults) > 1 {
return fmt.Errorf("multiple RDS DB Instance Classes (%v) match the criteria; try a different search", instanceClassResults)
}

if found == nil && len(instanceClassResults) == 1 {
found = instanceClassResults[0]
}

if found == nil {
return fmt.Errorf("no RDS DB Instance Classes match the criteria; try a different search")
}

d.SetId(aws.StringValue(found.DBInstanceClass))

d.Set("db_instance_class", found.DBInstanceClass)
d.Set("availability_zone_group", found.AvailabilityZoneGroup)

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

d.Set("engine", found.Engine)
d.Set("engine_version", found.EngineVersion)
d.Set("license_model", found.LicenseModel)
d.Set("max_iops_per_db_instance", found.MaxIopsPerDbInstance)
d.Set("max_iops_per_gib", found.MaxIopsPerGib)
d.Set("max_storage_size", found.MaxStorageSize)
d.Set("min_iops_per_db_instance", found.MinIopsPerDbInstance)
d.Set("min_iops_per_gib", found.MinIopsPerGib)
d.Set("min_storage_size", found.MinStorageSize)
d.Set("multi_az_capable", found.MultiAZCapable)
d.Set("outpost_capable", found.OutpostCapable)
d.Set("read_replica_capable", found.ReadReplicaCapable)
d.Set("storage_type", found.StorageType)
d.Set("supported_engine_modes", found.SupportedEngineModes)
d.Set("supports_enhanced_monitoring", found.SupportsEnhancedMonitoring)
d.Set("supports_global_databases", found.SupportsGlobalDatabases)
d.Set("supports_iam_database_authentication", found.SupportsIAMDatabaseAuthentication)
d.Set("supports_iops", found.SupportsIops)
d.Set("supports_kerberos_authentication", found.SupportsKerberosAuthentication)
d.Set("supports_performance_insights", found.SupportsPerformanceInsights)
d.Set("supports_storage_autoscaling", found.SupportsStorageAutoscaling)
d.Set("supports_storage_encryption", found.SupportsStorageEncryption)
d.Set("vpc", found.Vpc)

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

import (
"fmt"
"testing"

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

func TestAccAWSRdsOrderableDbInstanceDataSource_basic(t *testing.T) {
dataSourceName := "data.aws_rds_orderable_db_instance.test"
class := "db.t2.small"
engine := "mysql"
engineVersion := "5.7.22"
licenseModel := "general-public-license"
storageType := "standard"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRdsOrderableDbInstance(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRdsOrderableDbInstanceDataSourceConfigBasic(class, engine, engineVersion, licenseModel, storageType),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", class),
resource.TestCheckResourceAttr(dataSourceName, "engine", engine),
resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion),
resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel),
resource.TestCheckResourceAttr(dataSourceName, "storage_type", storageType),
),
},
},
})
}

func TestAccAWSRdsOrderableDbInstanceDataSource_preferred(t *testing.T) {
dataSourceName := "data.aws_rds_orderable_db_instance.test"
engine := "mysql"
engineVersion := "5.7.22"
licenseModel := "general-public-license"
storageType := "standard"
preferredOption := "db.t2.small"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRdsOrderableDbInstance(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRdsOrderableDbInstanceDataSourceConfigPreferred(engine, engineVersion, licenseModel, storageType, preferredOption),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "engine", engine),
resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion),
resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel),
resource.TestCheckResourceAttr(dataSourceName, "storage_type", storageType),
resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", preferredOption),
),
},
},
})
}

func testAccPreCheckAWSRdsOrderableDbInstance(t *testing.T) {
conn := testAccProvider.Meta().(*AWSClient).rdsconn

input := &rds.DescribeOrderableDBInstanceOptionsInput{
Engine: aws.String("mysql"),
}

_, err := conn.DescribeOrderableDBInstanceOptions(input)

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

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

func testAccAWSRdsOrderableDbInstanceDataSourceConfigBasic(class, engine, version, license, storage string) string {
return fmt.Sprintf(`
data "aws_rds_orderable_db_instance" "test" {
db_instance_class = %q
engine = %q
engine_version = %q
license_model = %q
storage_type = %q
}
`, class, engine, version, license, storage)
}

func testAccAWSRdsOrderableDbInstanceDataSourceConfigPreferred(engine, version, license, storage, preferredOption string) string {
return fmt.Sprintf(`
data "aws_rds_orderable_db_instance" "test" {
engine = %q
engine_version = %q
license_model = %q
storage_type = %q

preferred_db_instance_classes = ["db.xyz.xlarge", %q, "db.t3.small"]
}
`, engine, version, license, storage, preferredOption)
}
Loading