Skip to content

Commit

Permalink
Merge pull request #22489 from roberth-k/f-memorydb_sweepers_and_othe…
Browse files Browse the repository at this point in the history
…r_enhancements

MemoryDB: sweepers and other enhancements
  • Loading branch information
ewbankkit authored Jan 10, 2022
2 parents 297001a + 971cc47 commit 933ba4c
Show file tree
Hide file tree
Showing 22 changed files with 773 additions and 203 deletions.
3 changes: 3 additions & 0 deletions .changelog/22489.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_memorydb_cluster: Correctly propagate configurable timeouts to waiters.
```
1 change: 1 addition & 0 deletions internal/service/ec2/sweep.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ func init() {
"aws_fsx_windows_file_system",
"aws_lambda_function",
"aws_lb",
"aws_memorydb_subnet_group",
"aws_mq_broker",
"aws_msk_cluster",
"aws_network_interface",
Expand Down
25 changes: 3 additions & 22 deletions internal/service/memorydb/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package memorydb
import (
"context"
"log"
"regexp"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/memorydb"
Expand Down Expand Up @@ -48,33 +47,15 @@ func ResourceACL() *schema.Resource {
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name_prefix"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 40),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]*[a-z0-9]$`),
"Only lowercase alphanumeric characters and hyphens allowed. The name may not end with a hyphen."),
),
ValidateFunc: validateResourceName(aclNameMaxLength),
},
"name_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 40-resource.UniqueIDSuffixLength),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]+$`),
"Only lowercase alphanumeric characters and hyphens allowed."),
),
ValidateFunc: validateResourceNamePrefix(aclNameMaxLength - resource.UniqueIDSuffixLength),
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
Expand All @@ -83,7 +64,7 @@ func ResourceACL() *schema.Resource {
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringLenBetween(1, 40),
ValidateFunc: validation.StringLenBetween(1, userNameMaxLength),
},
},
},
Expand Down
52 changes: 12 additions & 40 deletions internal/service/memorydb/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package memorydb
import (
"context"
"log"
"regexp"
"time"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -71,18 +70,9 @@ func ResourceCluster() *schema.Resource {
Computed: true,
},
"final_snapshot_name": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 255),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]*[a-z0-9]$`),
"Only lowercase alphanumeric characters and hyphens allowed. The name may not end with a hyphen."),
),
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateResourceName(snapshotNameMaxLength),
},
"kms_key_arn": {
// The API will accept an ID, but return the ARN on every read.
Expand All @@ -106,33 +96,15 @@ func ResourceCluster() *schema.Resource {
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name_prefix"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 40),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]*[a-z0-9]$`),
"Only lowercase alphanumeric characters and hyphens allowed. The name may not end with a hyphen."),
),
ValidateFunc: validateResourceName(clusterNameMaxLength),
},
"name_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 40-resource.UniqueIDSuffixLength),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]+$`),
"Only lowercase alphanumeric characters and hyphens allowed."),
),
ValidateFunc: validateResourceNamePrefix(clusterNameMaxLength - resource.UniqueIDSuffixLength),
},
"node_type": {
Type: schema.TypeString,
Expand Down Expand Up @@ -364,7 +336,7 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta int
return diag.Errorf("error creating MemoryDB Cluster (%s): %s", name, err)
}

if err := waitClusterAvailable(ctx, conn, name); err != nil {
if err := waitClusterAvailable(ctx, conn, name, d.Timeout(schema.TimeoutCreate)); err != nil {
return diag.Errorf("error waiting for MemoryDB Cluster (%s) to be created: %s", name, err)
}

Expand Down Expand Up @@ -450,9 +422,9 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta int
input.SnsTopicArn = aws.String(v)

if v == "" {
input.SnsTopicStatus = aws.String(clusterSnsTopicStatusInactive)
input.SnsTopicStatus = aws.String(ClusterSNSTopicStatusInactive)
} else {
input.SnsTopicStatus = aws.String(clusterSnsTopicStatusActive)
input.SnsTopicStatus = aws.String(ClusterSNSTopicStatusActive)
}
}

Expand All @@ -463,7 +435,7 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta int
return diag.Errorf("error updating MemoryDB Cluster (%s): %s", d.Id(), err)
}

if err := waitClusterAvailable(ctx, conn, d.Id()); err != nil {
if err := waitClusterAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil {
return diag.Errorf("error waiting for MemoryDB Cluster (%s) to be modified: %s", d.Id(), err)
}

Expand Down Expand Up @@ -532,7 +504,7 @@ func resourceClusterRead(ctx context.Context, d *schema.ResourceData, meta inter
// For the sake of caution, limit this search to stable shards.
var maxNumberOfNodesPerShard int64
for _, shard := range cluster.Shards {
if aws.StringValue(shard.Status) != clusterShardStatusAvailable {
if aws.StringValue(shard.Status) != ClusterShardStatusAvailable {
continue
}

Expand Down Expand Up @@ -562,7 +534,7 @@ func resourceClusterRead(ctx context.Context, d *schema.ResourceData, meta inter
d.Set("snapshot_retention_limit", cluster.SnapshotRetentionLimit)
d.Set("snapshot_window", cluster.SnapshotWindow)

if aws.StringValue(cluster.SnsTopicStatus) == clusterSnsTopicStatusActive {
if aws.StringValue(cluster.SnsTopicStatus) == ClusterSNSTopicStatusActive {
d.Set("sns_topic_arn", cluster.SnsTopicArn)
} else {
d.Set("sns_topic_arn", "")
Expand Down Expand Up @@ -613,7 +585,7 @@ func resourceClusterDelete(ctx context.Context, d *schema.ResourceData, meta int
return diag.Errorf("error deleting MemoryDB Cluster (%s): %s", d.Id(), err)
}

if err := waitClusterDeleted(ctx, conn, d.Id()); err != nil {
if err := waitClusterDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
return diag.Errorf("error waiting for MemoryDB Cluster (%s) to be deleted: %s", d.Id(), err)
}

Expand Down
51 changes: 51 additions & 0 deletions internal/service/memorydb/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,27 @@ func TestAccMemoryDBCluster_create_withPort(t *testing.T) {
})
}

func TestAccMemoryDBCluster_create_fromSnapshot(t *testing.T) {
rName1 := "tf-test-" + sdkacctest.RandString(8)
rName2 := "tf-test-" + sdkacctest.RandString(8)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, memorydb.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccClusterConfig_withSnapshotFromCluster(rName1, rName2),
Check: resource.ComposeTestCheckFunc(
testAccCheckClusterExists("aws_memorydb_cluster.test1"),
testAccCheckClusterExists("aws_memorydb_cluster.test2"),
),
},
},
})
}

func TestAccMemoryDBCluster_delete_withFinalSnapshot(t *testing.T) {
rName := "tf-test-" + sdkacctest.RandString(8)
resourceName := "aws_memorydb_cluster.test"
Expand Down Expand Up @@ -1419,6 +1440,36 @@ resource "aws_memorydb_cluster" "test" {
)
}

func testAccClusterConfig_withSnapshotFromCluster(rName1, rName2 string) string {
return acctest.ConfigCompose(
testAccClusterConfigBaseNetwork(),
fmt.Sprintf(`
resource "aws_memorydb_cluster" "test1" {
acl_name = "open-access"
name = %[1]q
node_type = "db.t4g.small"
num_replicas_per_shard = 0
num_shards = 1
subnet_group_name = aws_memorydb_subnet_group.test.id
}
resource "aws_memorydb_snapshot" "test" {
cluster_name = aws_memorydb_cluster.test1.name
}
resource "aws_memorydb_cluster" "test2" {
acl_name = "open-access"
name = %[2]q
node_type = "db.t4g.small"
num_replicas_per_shard = 0
num_shards = 1
snapshot_name = aws_memorydb_snapshot.test.name
subnet_group_name = aws_memorydb_subnet_group.test.id
}
`, rName1, rName2),
)
}

func testAccClusterConfig_withSnapshotWindow(rName, snapshotWindow string) string {
return acctest.ConfigCompose(
testAccClusterConfigBaseNetwork(),
Expand Down
124 changes: 124 additions & 0 deletions internal/service/memorydb/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package memorydb

// WARNING: As of 01/2022, the MemoryDB API does not provide a formal definition
// of its enumerations, and what documentation there is does not align with the
// API itself. The following values were determined experimentally, and is
// unlikely to be exhaustive.

const (
ACLStatusActive = "active"
ACLStatusCreating = "creating"
ACLStatusDeleting = "deleting"
ACLStatusModifying = "modifying"
)

func ACLStatus_Values() []string {
return []string{
ACLStatusActive,
ACLStatusCreating,
ACLStatusDeleting,
ACLStatusModifying,
}
}

const (
ClusterStatusAvailable = "available"
ClusterStatusCreating = "creating"
ClusterStatusDeleting = "deleting"
ClusterStatusSnapshotting = "snapshotting"
ClusterStatusUpdating = "updating"
)

func ClusterStatus_Values() []string {
return []string{
ClusterStatusAvailable,
ClusterStatusCreating,
ClusterStatusDeleting,
ClusterStatusSnapshotting,
ClusterStatusUpdating,
}
}

const (
ClusterParameterGroupStatusApplying = "applying"
ClusterParameterGroupStatusInSync = "in-sync"
)

func ClusterParameterGroupStatus_Values() []string {
return []string{
ClusterParameterGroupStatusApplying,
ClusterParameterGroupStatusInSync,
}
}

const (
ClusterSecurityGroupStatusActive = "active"
ClusterSecurityGroupStatusModifying = "modifying"
)

func ClusterSecurityGroupStatus_Values() []string {
return []string{
ClusterSecurityGroupStatusActive,
ClusterSecurityGroupStatusModifying,
}
}

const (
ClusterShardStatusAvailable = "available"
ClusterShardStatusCreating = "creating"
ClusterShardStatusDeleting = "deleting"
ClusterShardStatusModifying = "modifying"
)

func ClusterShardStatus_Values() []string {
return []string{
ClusterShardStatusAvailable,
ClusterShardStatusCreating,
ClusterShardStatusDeleting,
ClusterShardStatusModifying,
}
}

const (
ClusterSNSTopicStatusActive = "ACTIVE"
ClusterSNSTopicStatusInactive = "INACTIVE"
)

func ClusterSNSTopicStatus_Values() []string {
return []string{
ClusterSNSTopicStatusActive,
ClusterSNSTopicStatusInactive,
}
}

const (
SnapshotStatusAvailable = "available"
SnapshotStatusCopying = "copying"
SnapshotStatusCreating = "creating"
SnapshotStatusDeleting = "deleting"
SnapshotStatusRestoring = "restoring"
)

func SnapshotStatus_Values() []string {
return []string{
SnapshotStatusCreating,
SnapshotStatusAvailable,
SnapshotStatusRestoring,
SnapshotStatusCopying,
SnapshotStatusDeleting,
}
}

const (
UserStatusActive = "active"
UserStatusDeleting = "deleting"
UserStatusModifying = "modifying"
)

func UserStatus_Values() []string {
return []string{
UserStatusActive,
UserStatusDeleting,
UserStatusModifying,
}
}
1 change: 1 addition & 0 deletions internal/service/memorydb/generate.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:generate go run ../../generate/listpages/main.go -ListOps=DescribeACLs,DescribeClusters,DescribeParameterGroups,DescribeSnapshots,DescribeSubnetGroups,DescribeUsers
//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsOp=ListTags -ListTagsOutTagsElem=TagList -ServiceTagsSlice -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

Expand Down
Loading

0 comments on commit 933ba4c

Please sign in to comment.