Skip to content

Commit

Permalink
Merge branch 'feature/aws_db_cluster_snapshot' of https://github.com/…
Browse files Browse the repository at this point in the history
…4dz/terraform-provider-aws into 4dz-feature/aws_db_cluster_snapshot
  • Loading branch information
bflad committed Aug 8, 2018
2 parents f78b0db + 70a3f81 commit c7ab45e
Show file tree
Hide file tree
Showing 9 changed files with 810 additions and 0 deletions.
210 changes: 210 additions & 0 deletions aws/data_source_aws_db_cluster_snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package aws

import (
"fmt"
"log"
"sort"
"time"

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

func dataSourceAwsDbClusterSnapshot() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsDbClusterSnapshotRead,

Schema: map[string]*schema.Schema{
//selection criteria
"db_cluster_identifier": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"db_cluster_snapshot_identifier": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"snapshot_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"include_shared": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},

"include_public": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},
"most_recent": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},

//Computed values returned
"allocated_storage": {
Type: schema.TypeInt,
Computed: true,
},
"availability_zones": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
"db_cluster_snapshot_arn": {
Type: schema.TypeString,
Computed: true,
},
"storage_encrypted": {
Type: schema.TypeBool,
Computed: true,
},
"engine": {
Type: schema.TypeString,
Computed: true,
},
"engine_version": {
Type: schema.TypeString,
Computed: true,
},
"kms_key_id": {
Type: schema.TypeString,
Computed: true,
},
"license_model": {
Type: schema.TypeString,
Computed: true,
},
"port": {
Type: schema.TypeInt,
Computed: true,
},
"source_db_cluster_snapshot_arn": {
Type: schema.TypeString,
Computed: true,
},
"snapshot_create_time": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"vpc_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

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

clusterIdentifier, clusterIdentifierOk := d.GetOk("db_cluster_identifier")
snapshotIdentifier, snapshotIdentifierOk := d.GetOk("db_cluster_snapshot_identifier")

if !clusterIdentifierOk && !snapshotIdentifierOk {
return fmt.Errorf("One of db_cluster_snapshot_identifier or db_cluster_identifier must be assigned")
}

params := &rds.DescribeDBClusterSnapshotsInput{
IncludePublic: aws.Bool(d.Get("include_public").(bool)),
IncludeShared: aws.Bool(d.Get("include_shared").(bool)),
}
if v, ok := d.GetOk("snapshot_type"); ok {
params.SnapshotType = aws.String(v.(string))
}
if clusterIdentifierOk {
params.DBClusterIdentifier = aws.String(clusterIdentifier.(string))
}
if snapshotIdentifierOk {
params.DBClusterSnapshotIdentifier = aws.String(snapshotIdentifier.(string))
}

log.Printf("[DEBUG] Reading DB Cluster Snapshot: %s", params)
resp, err := conn.DescribeDBClusterSnapshots(params)
if err != nil {
return err
}

if len(resp.DBClusterSnapshots) < 1 {
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
}

var snapshot *rds.DBClusterSnapshot
if len(resp.DBClusterSnapshots) > 1 {
recent := d.Get("most_recent").(bool)
log.Printf("[DEBUG] aws_db_cluster_snapshot - multiple results found and `most_recent` is set to: %t", recent)
if recent {
snapshot = mostRecentDbClusterSnapshot(resp.DBClusterSnapshots)
} else {
return fmt.Errorf("Your query returned more than one result. Please try a more specific search criteria.")
}
} else {
snapshot = resp.DBClusterSnapshots[0]
}

return DBClusterSnapshotDescriptionAttributes(d, snapshot)
}

type rdsClusterSnapshotSort []*rds.DBClusterSnapshot

func (a rdsClusterSnapshotSort) Len() int { return len(a) }
func (a rdsClusterSnapshotSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a rdsClusterSnapshotSort) Less(i, j int) bool {
// Snapshot creation can be in progress
if a[i].SnapshotCreateTime == nil {
return true
}
if a[j].SnapshotCreateTime == nil {
return false
}

return (*a[i].SnapshotCreateTime).Before(*a[j].SnapshotCreateTime)
}

func mostRecentDbClusterSnapshot(snapshots []*rds.DBClusterSnapshot) *rds.DBClusterSnapshot {
sortedSnapshots := snapshots
sort.Sort(rdsClusterSnapshotSort(sortedSnapshots))
return sortedSnapshots[len(sortedSnapshots)-1]
}

func DBClusterSnapshotDescriptionAttributes(d *schema.ResourceData, snapshot *rds.DBClusterSnapshot) error {
d.SetId(*snapshot.DBClusterSnapshotIdentifier)
d.Set("allocated_storage", snapshot.AllocatedStorage)
d.Set("availability_zones", flattenStringList(snapshot.AvailabilityZones))
d.Set("db_cluster_identifier", snapshot.DBClusterIdentifier)
d.Set("db_cluster_snapshot_arn", snapshot.DBClusterSnapshotArn)
d.Set("db_cluster_snapshot_identifier", snapshot.DBClusterSnapshotIdentifier)
d.Set("engine", snapshot.Engine)
d.Set("engine_version", snapshot.EngineVersion)
d.Set("kms_key_id", snapshot.KmsKeyId)
d.Set("license_model", snapshot.LicenseModel)
d.Set("port", snapshot.Port)
if snapshot.SnapshotCreateTime != nil {
d.Set("snapshot_create_time", snapshot.SnapshotCreateTime.Format(time.RFC3339))
}
d.Set("snapshot_type", snapshot.SnapshotType)
d.Set("source_db_cluster_snapshot_arn", snapshot.SourceDBClusterSnapshotArn)
d.Set("status", snapshot.Status)
d.Set("storage_encrypted", snapshot.StorageEncrypted)
d.Set("vpc_id", snapshot.VpcId)

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

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsDbClusterSnapshotDataSource_basic(t *testing.T) {
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckAwsDbClusterSnapshotDataSourceConfig(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsDbClusterSnapshotDataSourceID("data.aws_db_cluster_snapshot.snapshot"),
),
},
},
})
}

func testAccCheckAwsDbClusterSnapshotDataSourceID(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find data source: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("Snapshot data source ID not set")
}
return nil
}
}

func testAccCheckAwsDbClusterSnapshotDataSourceConfig(rInt int) string {
return fmt.Sprintf(`
resource "aws_rds_cluster" "aurora" {
master_username = "foo"
master_password = "barbarbarbar"
db_subnet_group_name = "${aws_db_subnet_group.aurora.name}"
backup_retention_period = 1
skip_final_snapshot = true
}
resource "aws_rds_cluster_instance" "aurora" {
count=1
cluster_identifier = "${aws_rds_cluster.aurora.id}"
instance_class = "db.t2.small"
db_subnet_group_name = "${aws_db_subnet_group.aurora.name}"
}
resource "aws_vpc" "aurora" {
cidr_block = "192.168.0.0/16"
tags {
Name = "data_source_aws_db_cluster_snapshot_test"
}
}
resource "aws_subnet" "aurora1" {
vpc_id = "${aws_vpc.aurora.id}"
cidr_block = "192.168.0.0/20"
availability_zone = "us-west-2a"
tags {
Name = "data_source_aws_db_cluster_snapshot_test"
}
}
resource "aws_subnet" "aurora2" {
vpc_id = "${aws_vpc.aurora.id}"
cidr_block = "192.168.16.0/20"
availability_zone = "us-west-2b"
tags {
Name = "data_source_aws_db_cluster_snapshot_test"
}
}
resource "aws_db_subnet_group" "aurora" {
subnet_ids = [
"${aws_subnet.aurora1.id}",
"${aws_subnet.aurora2.id}"
]
}
data "aws_db_cluster_snapshot" "snapshot" {
most_recent = "true"
db_cluster_snapshot_identifier = "${aws_db_cluster_snapshot.test.id}"
}
resource "aws_db_cluster_snapshot" "test" {
db_cluster_identifier = "${aws_rds_cluster.aurora.id}"
db_cluster_snapshot_identifier = "testsnapshot%d"
}`, rInt)
}
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func Provider() terraform.ResourceProvider {
"aws_cloudwatch_log_group": dataSourceAwsCloudwatchLogGroup(),
"aws_cognito_user_pools": dataSourceAwsCognitoUserPools(),
"aws_codecommit_repository": dataSourceAwsCodeCommitRepository(),
"aws_db_cluster_snapshot": dataSourceAwsDbClusterSnapshot(),
"aws_db_instance": dataSourceAwsDbInstance(),
"aws_db_snapshot": dataSourceAwsDbSnapshot(),
"aws_dx_gateway": dataSourceAwsDxGateway(),
Expand Down Expand Up @@ -362,6 +363,7 @@ func Provider() terraform.ResourceProvider {
"aws_dax_cluster": resourceAwsDaxCluster(),
"aws_dax_parameter_group": resourceAwsDaxParameterGroup(),
"aws_dax_subnet_group": resourceAwsDaxSubnetGroup(),
"aws_db_cluster_snapshot": resourceAwsDbClusterSnapshot(),
"aws_db_event_subscription": resourceAwsDbEventSubscription(),
"aws_db_instance": resourceAwsDbInstance(),
"aws_db_option_group": resourceAwsDbOptionGroup(),
Expand Down
Loading

0 comments on commit c7ab45e

Please sign in to comment.