Skip to content

Commit 1de39cb

Browse files
committed
feat: redis 8 module validation
1 parent 89c8f84 commit 1de39cb

7 files changed

+321
-25
lines changed

provider/pro/resource_rediscloud_pro_database.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func ResourceRedisCloudProDatabase() *schema.Resource {
242242
},
243243
},
244244
"modules": {
245-
Description: "Modules to be provisioned in the database",
245+
Description: "Modules to be provisioned in the database. Note: NOT supported for Redis 8.0 and higher as modules are bundled by default.",
246246
Type: schema.TypeSet,
247247
// In TF <0.12 List of objects is not supported, so we need to opt in to use this old behaviour.
248248
ConfigMode: schema.SchemaConfigModeAttr,
@@ -961,6 +961,9 @@ func customizeDiff() schema.CustomizeDiffFunc {
961961
if err := validateQueryPerformanceFactor()(ctx, diff, meta); err != nil {
962962
return err
963963
}
964+
if err := validateModulesForRedis8()(ctx, diff, meta); err != nil {
965+
return err
966+
}
964967
if err := RemoteBackupIntervalSetCorrectly("remote_backup")(ctx, diff, meta); err != nil {
965968
return err
966969
}
@@ -1011,6 +1014,25 @@ func containsDBModule(modules []map[string]interface{}, moduleName string) bool
10111014
return false
10121015
}
10131016

1017+
func validateModulesForRedis8() schema.CustomizeDiffFunc {
1018+
return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
1019+
redisVersion, versionExists := diff.GetOk("redis_version")
1020+
modules, modulesExists := diff.GetOkExists("modules")
1021+
1022+
if versionExists && modulesExists {
1023+
version := redisVersion.(string)
1024+
// Check if version is >= 8.0
1025+
if strings.HasPrefix(version, "8.") {
1026+
moduleSet := modules.(*schema.Set)
1027+
if moduleSet.Len() > 0 {
1028+
return fmt.Errorf(`"modules" cannot be explicitly set for Redis version %s as modules are bundled by default. Remove the "modules" field from your configuration`, version)
1029+
}
1030+
}
1031+
}
1032+
return nil
1033+
}
1034+
}
1035+
10141036
func RemoteBackupIntervalSetCorrectly(key string) schema.CustomizeDiffFunc {
10151037
// Validate multiple attributes - https://github.com/hashicorp/terraform-plugin-sdk/issues/233
10161038

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
locals {
2+
rediscloud_cloud_account = "%s"
3+
rediscloud_subscription_name = "%s"
4+
rediscloud_database_password = "%s"
5+
}
6+
7+
data "rediscloud_payment_method" "card" {
8+
card_type = "Visa"
9+
last_four_numbers = "5556"
10+
}
11+
12+
data "rediscloud_cloud_account" "account" {
13+
exclude_internal_account = true
14+
provider_type = "AWS"
15+
name = local.rediscloud_cloud_account
16+
}
17+
18+
resource "rediscloud_subscription" "example" {
19+
name = local.rediscloud_subscription_name
20+
payment_method_id = data.rediscloud_payment_method.card.id
21+
cloud_provider {
22+
provider = data.rediscloud_cloud_account.account.provider_type
23+
cloud_account_id = data.rediscloud_cloud_account.account.id
24+
region {
25+
region = "eu-west-1"
26+
networking_deployment_cidr = "10.0.0.0/24"
27+
preferred_availability_zones = ["eu-west-1a"]
28+
}
29+
}
30+
31+
creation_plan {
32+
dataset_size_in_gb = 15
33+
quantity = 1
34+
replication = true
35+
throughput_measurement_by = "operations-per-second"
36+
throughput_measurement_value = 20000
37+
}
38+
}
39+
40+
resource "rediscloud_subscription_database" "example" {
41+
subscription_id = rediscloud_subscription.example.id
42+
name = "example"
43+
protocol = "redis"
44+
dataset_size_in_gb = 3
45+
data_persistence = "none"
46+
data_eviction = "allkeys-random"
47+
throughput_measurement_by = "operations-per-second"
48+
throughput_measurement_value = 1000
49+
password = local.rediscloud_database_password
50+
support_oss_cluster_api = false
51+
external_endpoint_for_oss_cluster_api = false
52+
replication = false
53+
average_item_size_in_bytes = 0
54+
client_ssl_certificate = ""
55+
periodic_backup_path = ""
56+
enable_default_user = true
57+
redis_version = "7.2"
58+
59+
alert {
60+
name = "dataset-size"
61+
value = 1
62+
}
63+
64+
tags = {
65+
"market" = "emea"
66+
"material" = "cardboard"
67+
}
68+
}
69+
70+
resource "rediscloud_subscription_database" "example_replica" {
71+
subscription_id = rediscloud_subscription.example.id
72+
name = "example-replica"
73+
protocol = "redis"
74+
dataset_size_in_gb = 1
75+
data_persistence = "none"
76+
throughput_measurement_by = "operations-per-second"
77+
throughput_measurement_value = 1000
78+
password = local.rediscloud_database_password
79+
replication = false
80+
81+
replica_of = ["redis://${rediscloud_subscription_database.example.public_endpoint}"]
82+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
locals {
2+
rediscloud_cloud_account = "%s"
3+
rediscloud_subscription_name = "%s"
4+
}
5+
6+
data "rediscloud_payment_method" "card" {
7+
card_type = "Visa"
8+
last_four_numbers = "5556"
9+
}
10+
11+
data "rediscloud_cloud_account" "account" {
12+
exclude_internal_account = true
13+
provider_type = "AWS"
14+
name = local.rediscloud_cloud_account
15+
}
16+
17+
resource "rediscloud_subscription" "example" {
18+
name = local.rediscloud_subscription_name
19+
payment_method_id = data.rediscloud_payment_method.card.id
20+
cloud_provider {
21+
provider = data.rediscloud_cloud_account.account.provider_type
22+
cloud_account_id = data.rediscloud_cloud_account.account.id
23+
region {
24+
region = "eu-west-1"
25+
networking_deployment_cidr = "10.0.0.0/24"
26+
preferred_availability_zones = ["eu-west-1a"]
27+
}
28+
}
29+
30+
creation_plan {
31+
dataset_size_in_gb = 15
32+
quantity = 1
33+
replication = true
34+
throughput_measurement_by = "operations-per-second"
35+
throughput_measurement_value = 20000
36+
}
37+
}
38+
39+
resource "rediscloud_subscription_database" "example" {
40+
subscription_id = rediscloud_subscription.example.id
41+
name = "example-updated"
42+
protocol = "redis"
43+
dataset_size_in_gb = 1
44+
data_persistence = "aof-every-write"
45+
data_eviction = "volatile-lru"
46+
throughput_measurement_by = "operations-per-second"
47+
throughput_measurement_value = 2000
48+
password = "updated-password"
49+
support_oss_cluster_api = true
50+
external_endpoint_for_oss_cluster_api = true
51+
replication = true
52+
average_item_size_in_bytes = 0
53+
client_ssl_certificate = ""
54+
periodic_backup_path = ""
55+
enable_default_user = true
56+
redis_version = "8.0"
57+
58+
alert {
59+
name = "dataset-size"
60+
value = 80
61+
}
62+
63+
tags = {
64+
"market" = "emea"
65+
"material" = "cardboard"
66+
}
67+
}
68+
69+
resource "rediscloud_subscription_database" "example_replica" {
70+
subscription_id = rediscloud_subscription.example.id
71+
name = "example-replica"
72+
protocol = "redis"
73+
dataset_size_in_gb = 1
74+
data_persistence = "none"
75+
throughput_measurement_by = "operations-per-second"
76+
throughput_measurement_value = 1000
77+
password = "updated-password"
78+
replication = false
79+
redis_version = "8.0"
80+
81+
replica_of = ["redis://${rediscloud_subscription_database.example.public_endpoint}"]
82+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
locals {
2+
rediscloud_cloud_account = "%s"
3+
rediscloud_subscription_name = "%s"
4+
rediscloud_database_password = "%s"
5+
}
6+
7+
data "rediscloud_payment_method" "card" {
8+
card_type = "Visa"
9+
last_four_numbers = "5556"
10+
}
11+
12+
data "rediscloud_cloud_account" "account" {
13+
exclude_internal_account = true
14+
provider_type = "AWS"
15+
name = local.rediscloud_cloud_account
16+
}
17+
18+
resource "rediscloud_subscription" "example" {
19+
name = local.rediscloud_subscription_name
20+
payment_method_id = data.rediscloud_payment_method.card.id
21+
cloud_provider {
22+
provider = data.rediscloud_cloud_account.account.provider_type
23+
cloud_account_id = data.rediscloud_cloud_account.account.id
24+
region {
25+
region = "eu-west-1"
26+
networking_deployment_cidr = "10.0.0.0/24"
27+
preferred_availability_zones = ["eu-west-1a"]
28+
}
29+
}
30+
31+
creation_plan {
32+
dataset_size_in_gb = 15
33+
quantity = 1
34+
replication = true
35+
throughput_measurement_by = "operations-per-second"
36+
throughput_measurement_value = 20000
37+
}
38+
}
39+
40+
resource "rediscloud_subscription_database" "example" {
41+
subscription_id = rediscloud_subscription.example.id
42+
name = "example"
43+
protocol = "redis"
44+
dataset_size_in_gb = 1
45+
data_persistence = "none"
46+
throughput_measurement_by = "operations-per-second"
47+
throughput_measurement_value = 1000
48+
password = local.rediscloud_database_password
49+
redis_version = "8.0"
50+
51+
modules = [
52+
{
53+
name = "RedisBloom"
54+
}
55+
]
56+
}

provider/pro/testdata/pro_subscription_boilerplate.tf

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,13 @@ resource "rediscloud_subscription_database" "example" {
2020
client_ssl_certificate = ""
2121
periodic_backup_path = ""
2222
enable_default_user = true
23-
redis_version = 8.0
23+
redis_version = 7.2
2424

2525
alert {
2626
name = "dataset-size"
2727
value = 1
2828
}
2929

30-
modules = [
31-
{
32-
name = "RedisBloom"
33-
}
34-
]
35-
3630
tags = {
3731
"market" = "emea"
3832
"material" = "cardboard"

provider/resource_rediscloud_essentials_database.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package provider
22

33
import (
44
"context"
5+
"fmt"
56
"log"
7+
"strings"
68
"time"
79

810
"github.com/RedisLabs/rediscloud-go-api/redis"
@@ -50,6 +52,8 @@ func resourceRedisCloudEssentialsDatabase() *schema.Resource {
5052
Delete: schema.DefaultTimeout(10 * time.Minute),
5153
},
5254

55+
CustomizeDiff: essentialsCustomizeDiff(),
56+
5357
Schema: map[string]*schema.Schema{
5458
"subscription_id": {
5559
Description: "Identifier of the essentials subscription",
@@ -220,7 +224,7 @@ func resourceRedisCloudEssentialsDatabase() *schema.Resource {
220224
},
221225
},
222226
"modules": {
223-
Description: "Modules to be provisioned in the database",
227+
Description: "Modules to be provisioned in the database. Note: Not supported for Redis 8.0 and higher as modules are bundled by default.",
224228
Type: schema.TypeSet,
225229
// In TF <0.12 List of objects is not supported, so we need to opt-in to use this old behaviour.
226230
ConfigMode: schema.SchemaConfigModeAttr,
@@ -815,3 +819,30 @@ func writeFixedTags(ctx context.Context, api *client.ApiClient, subId int, datab
815819
}
816820
return api.Client.Tags.PutFixed(ctx, subId, databaseId, tags.AllTags{Tags: &t})
817821
}
822+
823+
func essentialsCustomizeDiff() schema.CustomizeDiffFunc {
824+
return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
825+
if err := validateModulesForRedis8Essentials()(ctx, diff, meta); err != nil {
826+
return err
827+
}
828+
return nil
829+
}
830+
}
831+
832+
func validateModulesForRedis8Essentials() schema.CustomizeDiffFunc {
833+
return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
834+
redisVersion, versionExists := diff.GetOk("redis_version")
835+
modules, modulesExists := diff.GetOkExists("modules")
836+
837+
if versionExists && modulesExists {
838+
version := redisVersion.(string)
839+
if strings.HasPrefix(version, "8.") {
840+
moduleSet := modules.(*schema.Set)
841+
if moduleSet.Len() > 0 {
842+
return fmt.Errorf(`"modules" cannot be explicitly set for Redis version %s as modules are bundled by default. Remove the "modules" field from your configuration`, version)
843+
}
844+
}
845+
}
846+
return nil
847+
}
848+
}

0 commit comments

Comments
 (0)