Skip to content

Commit

Permalink
Added resp_version to normal (flexible) database resource and datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnSharpe committed Nov 14, 2023
1 parent 2f4e921 commit 0619e87
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 50 deletions.
4 changes: 2 additions & 2 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ PROVIDER_VERSION = 99.99.99
PLUGINS_PATH = ~/.terraform.d/plugins
PLUGINS_PROVIDER_PATH=$(PROVIDER_HOSTNAME)/$(PROVIDER_NAMESPACE)/$(PROVIDER_TYPE)/$(PROVIDER_VERSION)/$(PROVIDER_TARGET)

# Use a parallelism of 4 by default for tests, overriding whatever GOMAXPROCS is set to.
TEST_PARALLELISM?=4
# Use a parallelism of 6 by default for tests, overriding whatever GOMAXPROCS is set to.
TEST_PARALLELISM?=6
TESTARGS?=-short

bin:
Expand Down
2 changes: 2 additions & 0 deletions docs/data-sources/rediscloud_database.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ data "rediscloud_database" "example" {
* `protocol` - The protocol of the database.
* `memory_limit_in_gb` - The maximum memory usage for the database.
* `support_oss_cluster_api` - Supports the Redis open-source (OSS) Cluster API.
* `resp_version` - Either `resp2` or `resp3`. Database's RESP version.
* `replica_of` - The set of Redis database URIs, in the format `redis://user:password@host:port`, that this
database will be a replica of.
* `alert` - Set of alerts to enable on the database, documented below.
Expand All @@ -57,6 +58,7 @@ hashing policy.
* `public_endpoint` - Public endpoint to access the database
* `private_endpoint` - Private endpoint to access the database
* `enable_tls` - Enable TLS for database, default is `false`
* `enable_default_user` - When `true` enables connecting to the database with the default user. Default `true`.

The `alert` block supports:

Expand Down
6 changes: 5 additions & 1 deletion docs/resources/rediscloud_subscription_database.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ resource "rediscloud_subscription_database" "database-resource" {
throughput_measurement_by = "operations-per-second"
throughput_measurement_value = 20000
replication = true
resp_version = "resp2"
enable_default_user = true
modules = [
{
name = "RedisJSON"
Expand All @@ -81,6 +83,7 @@ The following arguments are supported:
* `memory_limit_in_gb` - (Required) Maximum memory usage for this specific database
* `protocol` - (Optional) The protocol that will be used to access the database, (either ‘redis’ or ‘memcached’) Default: ‘redis’. **Modifying this attribute will force creation of a new resource.**
* `support_oss_cluster_api` - (Optional) Support Redis open-source (OSS) Cluster API. Default: ‘false’
* `resp_version` - (Optional) Either `resp2` or `resp3`. Database's RESP version. Must be compatible with the Redis version.
* `external_endpoint_for_oss_cluster_api` - (Optional) Should use the external endpoint for open-source (OSS) Cluster API.
Can only be enabled if OSS Cluster API support is enabled. Default: 'false'
* `client_ssl_certificate` - (Optional) SSL certificate to authenticate user connections
Expand All @@ -103,6 +106,7 @@ The following arguments are supported:
* `enable_tls` - (Optional) Use TLS for authentication. Default: ‘false’
* `port` - (Optional) TCP port on which the database is available - must be between 10000 and 19999. **Modifying this attribute will force creation of a new resource.**
* `remote_backup` (Optional) Specifies the backup options for the database, documented below
* `enable_default_user` (Optional) When `true` enables connecting to the database with the default user. Default `true`.

The `alert` block supports:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/RedisLabs/terraform-provider-rediscloud
go 1.19

require (
github.com/RedisLabs/rediscloud-go-api v0.6.0
github.com/RedisLabs/rediscloud-go-api v0.7.0
github.com/bflad/tfproviderlint v0.29.0
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/RedisLabs/rediscloud-go-api v0.6.0 h1:GPIY2mhnpk4LU0M7XB5Du3XmBaG4dyDfaDonFi21RZo=
github.com/RedisLabs/rediscloud-go-api v0.6.0/go.mod h1:cfuU+p/rgB+TObm0cq+AkyxwXWra8JOrPLKKj+nv7lM=
github.com/RedisLabs/rediscloud-go-api v0.7.0 h1:UysRfci3M1B7pDGRBsGMPhj8LRt3s1PpOEkTH2h9D4w=
github.com/RedisLabs/rediscloud-go-api v0.7.0/go.mod h1:cfuU+p/rgB+TObm0cq+AkyxwXWra8JOrPLKKj+nv7lM=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
Expand Down
4 changes: 2 additions & 2 deletions provider/datasource_rediscloud_acl_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestAccDataSourceRedisCloudAclRole_Default(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) },
ProviderFactories: providerFactories,
CheckDestroy: nil, // test doesn't create a resource at the moment, so don't need to check anything
CheckDestroy: testAccCheckAclRoleDestroy,
Steps: []resource.TestStep{
{
Config: createAndGetRoleTerraform,
Expand Down Expand Up @@ -86,7 +86,7 @@ resource "rediscloud_subscription" "example" {
support_oss_cluster_api=true
throughput_measurement_by = "operations-per-second"
throughput_measurement_value = 1000
modules = ["RedisJSON", "RedisBloom"]
modules = []
}
}
Expand Down
2 changes: 1 addition & 1 deletion provider/datasource_rediscloud_acl_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestAccDataSourceRedisCloudAclUser_Default(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
CheckDestroy: nil, // test doesn't create a resource at the moment, so don't need to check anything
CheckDestroy: testAccCheckAclUserDestroy,
Steps: []resource.TestStep{
{
Config: createAndGetUserTerraform,
Expand Down
16 changes: 16 additions & 0 deletions provider/datasource_rediscloud_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ func dataSourceRedisCloudDatabase() *schema.Resource {
Type: schema.TypeBool,
Computed: true,
},
"resp_version": {
Description: "The database's RESP version",
Type: schema.TypeString,
Computed: true,
},
"data_persistence": {
Description: "The rate of database data persistence (in persistent storage)",
Type: schema.TypeString,
Expand Down Expand Up @@ -142,6 +147,11 @@ func dataSourceRedisCloudDatabase() *schema.Resource {
Type: schema.TypeString,
},
},
"enable_default_user": {
Description: "When 'true', enables connecting to the database with the 'default' user. Default: 'true'",
Type: schema.TypeBool,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -209,6 +219,9 @@ func dataSourceRedisCloudDatabaseRead(ctx context.Context, d *schema.ResourceDat
if err := d.Set("support_oss_cluster_api", redis.BoolValue(db.SupportOSSClusterAPI)); err != nil {
return diag.FromErr(err)
}
if err := d.Set("resp_version", redis.StringValue(db.RespVersion)); err != nil {
return diag.FromErr(err)
}
if err := d.Set("data_persistence", redis.StringValue(db.DataPersistence)); err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -249,6 +262,9 @@ func dataSourceRedisCloudDatabaseRead(ctx context.Context, d *schema.ResourceDat
if err := d.Set("hashing_policy", flattenRegexRules(db.Clustering.RegexRules)); err != nil {
return diag.FromErr(err)
}
if err := d.Set("enable_default_user", redis.BoolValue(db.Security.EnableDefaultUser)); err != nil {
return diag.FromErr(err)
}

return diags
}
Expand Down
3 changes: 3 additions & 0 deletions provider/datasource_rediscloud_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestAccDataSourceRedisCloudDatabase_basic(t *testing.T) {
resource.TestCheckResourceAttr(dataSourceName, "region", "eu-west-1"),
resource.TestCheckResourceAttr(dataSourceName, "memory_limit_in_gb", "1"),
resource.TestCheckResourceAttr(dataSourceName, "support_oss_cluster_api", "true"),
resource.TestCheckResourceAttr(dataSourceName, "resp_version", "resp2"),
resource.TestCheckResourceAttr(dataSourceName, "data_persistence", "none"),
resource.TestCheckResourceAttr(dataSourceName, "data_eviction", "volatile-lru"),
resource.TestCheckResourceAttr(dataSourceName, "replication", "false"),
Expand All @@ -37,6 +38,7 @@ func TestAccDataSourceRedisCloudDatabase_basic(t *testing.T) {
resource.TestCheckResourceAttr(dataSourceName, "password", password),
resource.TestCheckResourceAttrSet(dataSourceName, "public_endpoint"),
resource.TestCheckResourceAttrSet(dataSourceName, "private_endpoint"),
resource.TestCheckResourceAttr(dataSourceName, "enable_default_user", "true"),
),
},
},
Expand Down Expand Up @@ -92,6 +94,7 @@ resource "rediscloud_subscription_database" "example" {
password = "%s"
support_oss_cluster_api = true
replication = false
enable_default_user = true
}
data "rediscloud_database" "example" {
Expand Down
8 changes: 8 additions & 0 deletions provider/resource_rediscloud_acl_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ func resourceRedisCloudAclRoleDelete(ctx context.Context, d *schema.ResourceData
return diag.FromErr(err)
}

// Sometimes ACL Users and Roles flip between Active and Pending a few times after creation/update.
// This delay gives the API a chance to settle
// TODO Ultimately this is an API problem
err = waitForAclRoleToBeActive(ctx, id, api)
if err != nil {
return diag.FromErr(err)
}

err = api.client.Roles.Delete(ctx, id)

if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions provider/resource_rediscloud_acl_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ func resourceRedisCloudAclUserDelete(ctx context.Context, d *schema.ResourceData
return diag.FromErr(err)
}

// Sometimes ACL Users and Roles flip between Active and Pending a few times after creation/update.
// This delay gives the API a chance to settle
// TODO Ultimately this is an API problem
err = waitForAclUserToBeActive(ctx, id, api)
if err != nil {
return diag.FromErr(err)
}

err = api.client.Users.Delete(ctx, id)

if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ func waitForDatabaseToBeDeleted(ctx context.Context, subId int, dbId int, api *a
Timeout: 10 * time.Minute,

Refresh: func() (result interface{}, state string, err error) {
log.Printf("[DEBUG] Waiting for datbase %d to be deleted", dbId)
log.Printf("[DEBUG] Waiting for database %d to be deleted", dbId)

_, err = api.client.Database.Get(ctx, subId, dbId)
if err != nil {
Expand Down
34 changes: 33 additions & 1 deletion provider/resource_rediscloud_subscription_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ func resourceRedisCloudSubscriptionDatabase() *schema.Resource {
Optional: true,
Default: false,
},
"resp_version": {
Description: "The database's RESP version",
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"external_endpoint_for_oss_cluster_api": {
Description: "Should use the external endpoint for open-source (OSS) Cluster API",
Type: schema.TypeBool,
Expand Down Expand Up @@ -235,6 +241,12 @@ func resourceRedisCloudSubscriptionDatabase() *schema.Resource {
Optional: true,
Default: false,
},
"enable_default_user": {
Description: "When 'true', enables connecting to the database with the 'default' user. Default: 'true'",
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"port": {
Description: "TCP port on which the database is available",
Type: schema.TypeInt,
Expand Down Expand Up @@ -291,6 +303,7 @@ func resourceRedisCloudSubscriptionDatabaseCreate(ctx context.Context, d *schema
protocol := d.Get("protocol").(string)
memoryLimitInGB := d.Get("memory_limit_in_gb").(float64)
supportOSSClusterAPI := d.Get("support_oss_cluster_api").(bool)
respVersion := d.Get("resp_version").(string)
dataPersistence := d.Get("data_persistence").(string)
dataEviction := d.Get("data_eviction").(string)
password := d.Get("password").(string)
Expand Down Expand Up @@ -345,6 +358,7 @@ func resourceRedisCloudSubscriptionDatabaseCreate(ctx context.Context, d *schema
Alerts: createAlerts,
RemoteBackup: buildBackupPlan(d.Get("remote_backup").([]interface{}), d.Get("periodic_backup_path")),
}

if password != "" {
createDatabase.Password = redis.String(password)
}
Expand All @@ -357,6 +371,10 @@ func resourceRedisCloudSubscriptionDatabaseCreate(ctx context.Context, d *schema
createDatabase.PortNumber = redis.Int(v.(int))
}

if respVersion != "" {
createDatabase.RespVersion = redis.String(respVersion)
}

dbId, err := api.client.Database.Create(ctx, subId, createDatabase)
if err != nil {
return diag.FromErr(err)
Expand All @@ -373,7 +391,7 @@ func resourceRedisCloudSubscriptionDatabaseCreate(ctx context.Context, d *schema
// Locate Databases to confirm Active status

// Some attributes on a database are not accessible by the subscription creation API.
// Run the subscription update function to apply any additional changes to the databases, such as password and so on.
// Run the subscription update function to apply any additional changes to the databases, such as password, enableDefaultUser and so on.
subscriptionMutex.Unlock(subId)
return resourceRedisCloudSubscriptionDatabaseUpdate(ctx, d, meta)
}
Expand Down Expand Up @@ -422,6 +440,10 @@ func resourceRedisCloudSubscriptionDatabaseRead(ctx context.Context, d *schema.R
return diag.FromErr(err)
}

if err := d.Set("resp_version", redis.StringValue(db.RespVersion)); err != nil {
return diag.FromErr(err)
}

if err := d.Set("data_persistence", redis.StringValue(db.DataPersistence)); err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -494,6 +516,10 @@ func resourceRedisCloudSubscriptionDatabaseRead(ctx context.Context, d *schema.R
return diag.FromErr(err)
}

if err := d.Set("enable_default_user", redis.Bool(*db.Security.EnableDefaultUser)); err != nil {
return diag.FromErr(err)
}

if err := d.Set("remote_backup", flattenBackupPlan(db.Backup, d.Get("remote_backup").([]interface{}), d.Get("periodic_backup_path").(string))); err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -567,6 +593,7 @@ func resourceRedisCloudSubscriptionDatabaseUpdate(ctx context.Context, d *schema
SourceIP: setToStringSlice(d.Get("source_ips").(*schema.Set)),
Alerts: &alerts,
RemoteBackup: buildBackupPlan(d.Get("remote_backup").([]interface{}), d.Get("periodic_backup_path")),
EnableDefaultUser: redis.Bool(d.Get("enable_default_user").(bool)),
}
if len(setToStringSlice(d.Get("source_ips").(*schema.Set))) == 0 {
update.SourceIP = []*string{redis.String("0.0.0.0/0")}
Expand Down Expand Up @@ -613,6 +640,11 @@ func resourceRedisCloudSubscriptionDatabaseUpdate(ctx context.Context, d *schema

update.UseExternalEndpointForOSSClusterAPI = redis.Bool(d.Get("external_endpoint_for_oss_cluster_api").(bool))

respVersion := d.Get("resp_version").(string)
if respVersion != "" {
update.RespVersion = redis.String(respVersion)
}

err = api.client.Database.Update(ctx, subId, dbId, update)
if err != nil {
return diag.FromErr(err)
Expand Down
Loading

0 comments on commit 0619e87

Please sign in to comment.