Skip to content

Commit c035f43

Browse files
Merge pull request #599 from RedisLabs/feat/query_performance_factors
Adding in support for query performance factors on affected resources
2 parents 03b6c95 + 9b23830 commit c035f43

9 files changed

+548
-23
lines changed

.github/workflows/terraform_provider_pr.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,19 @@ jobs:
149149
go-version-file: go.mod
150150
- run: EXECUTE_TESTS=true make testacc TESTARGS='-run="TestAccResourceRedisCloud(PrivateServiceConnect_CRUDI|AclRule_CRUDI)"'
151151

152+
# TODO: remove this after release
153+
# qpf = query performance factor
154+
go_test_smoke_qpf:
155+
name: go test smoke qpf
156+
needs: [ go_build ]
157+
runs-on: ubuntu-latest
158+
steps:
159+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
160+
- uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0
161+
with:
162+
go-version-file: go.mod
163+
- run: EXECUTE_TESTS=true make testacc TESTARGS='-run="TestAccResourceRedisCloudProDatabase_qpf.*"'
164+
152165
tfproviderlint:
153166
name: tfproviderlint
154167
needs: [go_build]

provider/datasource_rediscloud_pro_database.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ func dataSourceRedisCloudProDatabase() *schema.Resource {
5959
Type: schema.TypeFloat,
6060
Computed: true,
6161
},
62+
"query_performance_factor": {
63+
Description: "Query performance factor for this specific database",
64+
Type: schema.TypeString,
65+
Computed: true,
66+
},
6267
"support_oss_cluster_api": {
6368
Description: "Supports the Redis open-source (OSS) Cluster API",
6469
Type: schema.TypeBool,
@@ -476,6 +481,10 @@ func dataSourceRedisCloudProDatabaseRead(ctx context.Context, d *schema.Resource
476481
return diag.FromErr(err)
477482
}
478483

484+
if err := d.Set("query_performance_factor", redis.String(*db.QueryPerformanceFactor)); err != nil {
485+
return diag.FromErr(err)
486+
}
487+
479488
return diags
480489
}
481490

provider/datasource_rediscloud_pro_database_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func TestAccDataSourceRedisCloudProDatabase_basic(t *testing.T) {
4343
resource.TestCheckResourceAttrSet(dataSourceById, "public_endpoint"),
4444
resource.TestCheckResourceAttrSet(dataSourceById, "private_endpoint"),
4545
resource.TestCheckResourceAttr(dataSourceById, "enable_default_user", "true"),
46+
resource.TestCheckResourceAttr(dataSourceById, "query_performance_factor", "2x"),
4647

4748
resource.TestCheckResourceAttr(dataSourceByName, "name", "tf-database"),
4849
resource.TestCheckResourceAttr(dataSourceByName, "protocol", "redis"),
@@ -59,6 +60,7 @@ func TestAccDataSourceRedisCloudProDatabase_basic(t *testing.T) {
5960
resource.TestCheckResourceAttrSet(dataSourceByName, "public_endpoint"),
6061
resource.TestCheckResourceAttrSet(dataSourceByName, "private_endpoint"),
6162
resource.TestCheckResourceAttr(dataSourceByName, "enable_default_user", "true"),
63+
resource.TestCheckResourceAttr(dataSourceByName, "query_performance_factor", "2x"),
6264
),
6365
},
6466
},
@@ -94,6 +96,8 @@ resource "rediscloud_subscription" "example" {
9496
support_oss_cluster_api=true
9597
throughput_measurement_by = "operations-per-second"
9698
throughput_measurement_value = 1000
99+
query_performance_factor = "2x"
100+
modules = ["RediSearch"]
97101
}
98102
}
99103
resource "rediscloud_subscription_database" "example" {
@@ -108,6 +112,12 @@ resource "rediscloud_subscription_database" "example" {
108112
support_oss_cluster_api = true
109113
replication = false
110114
enable_default_user = true
115+
query_performance_factor = "2x"
116+
modules = [
117+
{
118+
name: "RediSearch"
119+
}
120+
]
111121
}
112122
113123
data "rediscloud_database" "example-by-id" {

provider/resource_rediscloud_active_active_subscription_peering_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ package provider
22

33
import (
44
"fmt"
5+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
57
"os"
68
"regexp"
79
"testing"
8-
9-
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
10-
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1110
)
1211

1312
func TestAccResourceRedisCloudActiveActiveSubscriptionPeering_aws(t *testing.T) {

provider/resource_rediscloud_pro_database.go

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package provider
33
import (
44
"context"
55
"fmt"
6+
"regexp"
67
"strconv"
78
"strings"
89
"time"
@@ -49,7 +50,7 @@ func resourceRedisCloudProDatabase() *schema.Resource {
4950
Delete: schema.DefaultTimeout(10 * time.Minute),
5051
},
5152

52-
CustomizeDiff: remoteBackupIntervalSetCorrectly("remote_backup"),
53+
CustomizeDiff: customizeDiff(),
5354

5455
Schema: map[string]*schema.Schema{
5556
"subscription_id": {
@@ -215,6 +216,25 @@ func resourceRedisCloudProDatabase() *schema.Resource {
215216
},
216217
},
217218
},
219+
"query_performance_factor": {
220+
Description: "Query performance factor for this specific database",
221+
Type: schema.TypeString,
222+
Optional: true,
223+
Computed: true,
224+
ForceNew: true,
225+
ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
226+
v := val.(string)
227+
matched, err := regexp.MatchString(`^([2468])x$`, v)
228+
if err != nil {
229+
errs = append(errs, fmt.Errorf("regex match failed: %s", err))
230+
return
231+
}
232+
if !matched {
233+
errs = append(errs, fmt.Errorf("%q must be an even value between 2x and 8x (inclusive), got: %s", key, v))
234+
}
235+
return
236+
},
237+
},
218238
"modules": {
219239
Description: "Modules to be provisioned in the database",
220240
Type: schema.TypeSet,
@@ -341,6 +361,7 @@ func resourceRedisCloudProDatabaseCreate(ctx context.Context, d *schema.Resource
341361
throughputMeasurementBy := d.Get("throughput_measurement_by").(string)
342362
throughputMeasurementValue := d.Get("throughput_measurement_value").(int)
343363
averageItemSizeInBytes := d.Get("average_item_size_in_bytes").(int)
364+
queryPerformanceFactor := d.Get("query_performance_factor").(string)
344365

345366
createModules := make([]*databases.Module, 0)
346367
modules := d.Get("modules").(*schema.Set)
@@ -388,6 +409,10 @@ func resourceRedisCloudProDatabaseCreate(ctx context.Context, d *schema.Resource
388409
RemoteBackup: buildBackupPlan(d.Get("remote_backup").([]interface{}), d.Get("periodic_backup_path")),
389410
}
390411

412+
if queryPerformanceFactor != "" {
413+
createDatabase.QueryPerformanceFactor = redis.String(queryPerformanceFactor)
414+
}
415+
391416
if password != "" {
392417
createDatabase.Password = redis.String(password)
393418
}
@@ -513,6 +538,10 @@ func resourceRedisCloudProDatabaseRead(ctx context.Context, d *schema.ResourceDa
513538
return diag.FromErr(err)
514539
}
515540

541+
if err := d.Set("query_performance_factor", redis.StringValue(db.QueryPerformanceFactor)); err != nil {
542+
return diag.FromErr(err)
543+
}
544+
516545
if err := d.Set("modules", flattenModules(db.Modules)); err != nil {
517546
return diag.FromErr(err)
518547
}
@@ -585,6 +614,12 @@ func resourceRedisCloudProDatabaseRead(ctx context.Context, d *schema.ResourceDa
585614
return diag.FromErr(err)
586615
}
587616

617+
if db.QueryPerformanceFactor != nil {
618+
if err := d.Set("query_performance_factor", redis.String(*db.QueryPerformanceFactor)); err != nil {
619+
return diag.FromErr(err)
620+
}
621+
}
622+
588623
if err := readTags(ctx, api, subId, dbId, d); err != nil {
589624
return diag.FromErr(err)
590625
}
@@ -681,6 +716,11 @@ func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.Resource
681716
update.SourceIP = []*string{redis.String("0.0.0.0/0")}
682717
}
683718

719+
queryPerformanceFactor := d.Get("query_performance_factor").(string)
720+
if queryPerformanceFactor != "" {
721+
update.QueryPerformanceFactor = redis.String(queryPerformanceFactor)
722+
}
723+
684724
if d.Get("password").(string) != "" {
685725
update.Password = redis.String(d.Get("password").(string))
686726
}
@@ -873,6 +913,61 @@ func skipDiffIfIntervalIs12And12HourTimeDiff(k, oldValue, newValue string, d *sc
873913
return oldTime.Minute() == newTime.Minute() && oldTime.Add(12*time.Hour).Hour() == newTime.Hour()
874914
}
875915

916+
func customizeDiff() schema.CustomizeDiffFunc {
917+
return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
918+
if err := validateQueryPerformanceFactor()(ctx, diff, meta); err != nil {
919+
return err
920+
}
921+
if err := remoteBackupIntervalSetCorrectly("remote_backup")(ctx, diff, meta); err != nil {
922+
return err
923+
}
924+
return nil
925+
}
926+
}
927+
928+
func validateQueryPerformanceFactor() schema.CustomizeDiffFunc {
929+
return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
930+
// Check if "query_performance_factor" is set
931+
qpf, qpfExists := diff.GetOk("query_performance_factor")
932+
933+
// Ensure "modules" is explicitly defined in the HCL
934+
_, modulesExists := diff.GetOkExists("modules")
935+
936+
if qpfExists && qpf.(string) != "" {
937+
if !modulesExists {
938+
return fmt.Errorf(`"query_performance_factor" requires the "modules" key to be explicitly defined in HCL`)
939+
}
940+
941+
// Retrieve modules as a slice of interfaces
942+
rawModules := diff.Get("modules").(*schema.Set).List()
943+
944+
// Convert modules to []map[string]interface{}
945+
var modules []map[string]interface{}
946+
for _, rawModule := range rawModules {
947+
if moduleMap, ok := rawModule.(map[string]interface{}); ok {
948+
modules = append(modules, moduleMap)
949+
}
950+
}
951+
952+
// Check if "RediSearch" exists
953+
if !containsDBModule(modules, "RediSearch") {
954+
return fmt.Errorf(`"query_performance_factor" requires the "modules" list to contain "RediSearch"`)
955+
}
956+
}
957+
return nil
958+
}
959+
}
960+
961+
// Helper function to check if a module exists
962+
func containsDBModule(modules []map[string]interface{}, moduleName string) bool {
963+
for _, module := range modules {
964+
if name, ok := module["name"].(string); ok && name == moduleName {
965+
return true
966+
}
967+
}
968+
return false
969+
}
970+
876971
func remoteBackupIntervalSetCorrectly(key string) schema.CustomizeDiffFunc {
877972
// Validate multiple attributes - https://github.com/hashicorp/terraform-plugin-sdk/issues/233
878973

0 commit comments

Comments
 (0)