Skip to content

Commit

Permalink
Merge pull request #14853 from terraform-providers/f-rds-orderable-db
Browse files Browse the repository at this point in the history
data-source/aws_rds_orderable_db_instance: New data source
  • Loading branch information
YakDriver authored Aug 31, 2020
2 parents 1206283 + 096c625 commit 3886e9b
Show file tree
Hide file tree
Showing 4 changed files with 460 additions and 0 deletions.
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

0 comments on commit 3886e9b

Please sign in to comment.