Skip to content

Commit

Permalink
Merge pull request #31264 from elrob/f-aws_elasticache_redis-support_…
Browse files Browse the repository at this point in the history
…redis_v7

[Enhancement]: aws elasticache redis - support redis v7
  • Loading branch information
gdavison authored Jun 13, 2023
2 parents 85373e5 + 20eec3b commit e982255
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 44 deletions.
11 changes: 11 additions & 0 deletions .changelog/31264.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:bug
resource/aws_elasticache_cluster: Correctly supports ElastiCache Redis version 7+
```

```release-note:bug
resource/aws_elasticache_global_replication_group: Correctly supports ElastiCache Redis version 7+
```

```release-note:bug
resource/aws_elasticache_replication_group: Correctly supports ElastiCache Redis version 7+
```
20 changes: 7 additions & 13 deletions internal/service/elasticache/engine_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,10 @@ func validMemcachedVersionString(v interface{}, k string) (ws []string, errors [
}

const (
redisVersionPreV6RegexpRaw = `[1-5](\.[[:digit:]]+){2}`
redisVersionPostV6RegexpRaw = `(([6-9])\.x)|([6-9]\.[[:digit:]]+)`
redisVersionPreV6RegexpPattern = `^[1-5](\.[[:digit:]]+){2}$`
redisVersionPostV6RegexpPattern = `^((6)\.x)|([6-9]\.[[:digit:]]+)$`

redisVersionRegexpRaw = redisVersionPreV6RegexpRaw + "|" + redisVersionPostV6RegexpRaw
)

const (
redisVersionRegexpPattern = "^" + redisVersionRegexpRaw + "$"
redisVersionPostV6RegexpPattern = "^" + redisVersionPostV6RegexpRaw + "$"
redisVersionRegexpPattern = redisVersionPreV6RegexpPattern + "|" + redisVersionPostV6RegexpPattern
)

var (
Expand Down Expand Up @@ -128,15 +123,14 @@ func engineVersionForceNewOnDowngrade(diff forceNewDiffer) error {
return diff.ForceNew("engine_version")
}

// normalizeEngineVersion returns a github.com/hashicorp/go-version Version
// that can handle a regular 1.2.3 version number or either the 6.x or 6.0 version number used for
// ElastiCache Redis version 6 and higher. 6.x will sort to 6.<maxint>
// normalizeEngineVersion returns a github.com/hashicorp/go-version Version from:
// - a regular 1.2.3 version number
// - either the 6.x or 6.0 version number used for ElastiCache Redis version 6. 6.x will sort to 6.<maxint>
// - a 7.0 version number used from version 7
func normalizeEngineVersion(version string) (*gversion.Version, error) {
if matches := redisVersionPostV6Regexp.FindStringSubmatch(version); matches != nil {
if matches[1] != "" {
version = fmt.Sprintf("%s.%d", matches[2], math.MaxInt)
} else if matches[3] != "" {
version = matches[3]
}
}
return gversion.NewVersion(version)
Expand Down
128 changes: 100 additions & 28 deletions internal/service/elasticache/engine_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,42 @@ func TestValidRedisVersionString(t *testing.T) {
version: "6.y",
valid: false,
},
{
version: "7.0",
valid: true,
},
{
version: "7.2",
valid: true,
},
{
version: "7.x",
valid: false,
},
{
version: "7.2.x",
valid: false,
},
{
version: "7.5.0",
valid: false,
},
{
version: "7.5.",
valid: false,
},
{
version: "7.",
valid: false,
},
{
version: "7",
valid: false,
},
{
version: "7.y",
valid: false,
},
}

for _, testcase := range testcases {
Expand Down Expand Up @@ -191,6 +227,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: false,
},
{
engine: "",
version: "7.0",
valid: false,
},

{
engine: engineMemcached,
Expand All @@ -207,6 +248,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: false,
},
{
engine: engineMemcached,
version: "7.0",
valid: false,
},

{
engine: engineRedis,
Expand All @@ -223,6 +269,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: true,
},
{
engine: engineRedis,
version: "7.0",
valid: true,
},
}

for _, testcase := range testcases {
Expand Down Expand Up @@ -277,17 +328,17 @@ func TestCustomizeDiffEngineVersionIsDowngrade(t *testing.T) {
expected: false,
},

// "upgrade major 6.x": {
// old: "5.0.6",
// new: "6.x",
// expectForceNew: false,
// },
"upgrade major 6.x": {
old: "5.0.6",
new: "6.x",
expected: false,
},

// "upgrade major 6.digit": {
// old: "5.0.6",
// new: "6.0",
// expectForceNew: false,
// },
"upgrade major 6.digit": {
old: "5.0.6",
new: "6.0",
expected: false,
},

"downgrade minor versions": {
old: "1.3.5",
Expand Down Expand Up @@ -319,15 +370,15 @@ func TestCustomizeDiffEngineVersionIsDowngrade(t *testing.T) {
expected: false,
},

"downgrade from major 7.x to 6.x": {
old: "7.x",
"downgrade from major 7.digit to 6.x": {
old: "7.2",
new: "6.x",
expected: true,
},

"downgrade from major 7.digit to 6.x": {
"downgrade from major 7.digit to 6.digit": {
old: "7.2",
new: "6.x",
new: "6.2",
expected: true,
},
}
Expand Down Expand Up @@ -419,17 +470,23 @@ func TestCustomizeDiffEngineVersionForceNewOnDowngrade(t *testing.T) {
expectForceNew: false,
},

// "upgrade major 6.x": {
// old: "5.0.6",
// new: "6.x",
// expectForceNew: false,
// },
"upgrade major 6.x": {
old: "5.0.6",
new: "6.x",
expectForceNew: false,
},

"upgrade major 6.digit": {
old: "5.0.6",
new: "6.0",
expectForceNew: false,
},

// "upgrade major 6.digit": {
// old: "5.0.6",
// new: "6.0",
// expectForceNew: false,
// },
"upgrade major 7.digit": {
old: "6.x",
new: "7.0",
expectForceNew: false,
},

"downgrade minor versions": {
old: "1.3.5",
Expand Down Expand Up @@ -461,15 +518,21 @@ func TestCustomizeDiffEngineVersionForceNewOnDowngrade(t *testing.T) {
expectForceNew: false,
},

"downgrade from major 7.x to 6.x": {
old: "7.x",
"downgrade from major 7.digit to 6.x": {
old: "7.2",
new: "6.x",
expectForceNew: true,
},

"downgrade from major 7.digit to 6.x": {
"downgrade from major 7.digit to 6.digit": {
old: "7.2",
new: "6.x",
new: "6.2",
expectForceNew: true,
},

"downgrade major 7.digit": {
old: "7.2",
new: "7.0",
expectForceNew: true,
},
}
Expand Down Expand Up @@ -529,10 +592,19 @@ func TestNormalizeEngineVersion(t *testing.T) {
normalized: fmt.Sprintf("6.%d.0", math.MaxInt),
valid: true,
},
{
version: "7.2",
normalized: "7.2.0",
valid: true,
},
{
version: "5.x",
valid: false,
},
{
version: "7.x",
valid: false,
},
}

for _, testcase := range testcases {
Expand Down
46 changes: 46 additions & 0 deletions internal/service/elasticache/replication_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,41 @@ func TestAccElastiCacheReplicationGroup_uppercase(t *testing.T) {
})
}

func TestAccElastiCacheReplicationGroup_EngineVersion_v7(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
t.Skip("skipping long-running test in short mode")
}

var rg elasticache.ReplicationGroup
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_elasticache_replication_group.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, elasticache.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckReplicationGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccReplicationGroupConfig_v7(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckReplicationGroupExists(ctx, resourceName, &rg),
resource.TestCheckResourceAttr(resourceName, "engine", "redis"),
resource.TestCheckResourceAttr(resourceName, "engine_version", "7.0"),
resource.TestMatchResourceAttr(resourceName, "engine_version_actual", regexp.MustCompile(`^7\.[[:digit:]]+\.[[:digit:]]+$`)),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"apply_immediately"}, //not in the API
},
},
})
}

func TestAccElastiCacheReplicationGroup_EngineVersion_update(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -2688,6 +2723,17 @@ resource "aws_elasticache_replication_group" "test" {
`, rName)
}

func testAccReplicationGroupConfig_v7(rName string) string {
return fmt.Sprintf(`
resource "aws_elasticache_replication_group" "test" {
replication_group_id = %[1]q
replication_group_description = "test description"
node_type = "cache.t3.small"
engine_version = "7.0"
}
`, rName)
}

func testAccReplicationGroupConfig_uppercase(rName string) string {
return acctest.ConfigCompose(
acctest.ConfigVPCWithSubnets(rName, 2),
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/elasticache_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ The following arguments are optional:
* `engine_version` – (Optional) Version number of the cache engine to be used.
If not set, defaults to the latest version.
See [Describe Cache Engine Versions](https://docs.aws.amazon.com/cli/latest/reference/elasticache/describe-cache-engine-versions.html) in the AWS Documentation for supported versions.
When `engine` is `redis` and the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
When `engine` is `redis` and the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
When the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
Otherwise, specify the full version desired, e.g., `5.0.6`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ The following arguments are supported:
When creating, by default the Global Replication Group inherits the version of the primary replication group.
If a version is specified, the Global Replication Group and all member replication groups will be upgraded to this version.
Cannot be downgraded without replacing the Global Replication Group and all member replication groups.
If the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
When the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
When the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
* `global_replication_group_id_suffix` – (Required) The suffix name of a Global Datastore. If `global_replication_group_id_suffix` is changed, creates a new resource.
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/elasticache_replication_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ The following arguments are optional:
* `data_tiering_enabled` - (Optional) Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. This parameter must be set to `true` when using r6gd nodes.
* `engine` - (Optional) Name of the cache engine to be used for the clusters in this replication group. The only valid value is `redis`.
* `engine_version` - (Optional) Version number of the cache engine to be used for the cache clusters in this replication group.
If the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
If the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
If the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
Otherwise, specify the full version desired, e.g., `5.0.6`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
Expand Down

0 comments on commit e982255

Please sign in to comment.