diff --git a/provider/datasource_rediscloud_active_active_subscription.go b/provider/datasource_rediscloud_active_active_subscription.go index 0f836824..a1270080 100644 --- a/provider/datasource_rediscloud_active_active_subscription.go +++ b/provider/datasource_rediscloud_active_active_subscription.go @@ -30,6 +30,16 @@ func dataSourceRedisCloudActiveActiveSubscription() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "number_of_databases": { + Description: "The number of databases that are linked to this subscription", + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Description: "Current status of the subscription", + Type: schema.TypeString, + Computed: true, + }, "cloud_provider": { Description: "A cloud provider string either GCP or AWS", Type: schema.TypeString, @@ -141,6 +151,12 @@ func dataSourceRedisCloudActiveActiveSubscriptionRead(ctx context.Context, d *sc if err := d.Set("payment_method", sub.PaymentMethod); err != nil { return diag.FromErr(err) } + if err := d.Set("number_of_databases", redis.IntValue(sub.NumberOfDatabases)); err != nil { + return diag.FromErr(err) + } + if err := d.Set("status", redis.StringValue(sub.Status)); err != nil { + return diag.FromErr(err) + } cloudDetails := sub.CloudDetails if len(cloudDetails) == 0 { @@ -155,13 +171,6 @@ func dataSourceRedisCloudActiveActiveSubscriptionRead(ctx context.Context, d *sc } } - if err := d.Set("number_of_databases", redis.IntValue(sub.NumberOfDatabases)); err != nil { - return diag.FromErr(err) - } - if err := d.Set("status", redis.StringValue(sub.Status)); err != nil { - return diag.FromErr(err) - } - subId := redis.IntValue(sub.ID) pricingList, err := api.client.Pricing.List(ctx, subId) diff --git a/provider/datasource_rediscloud_database_test.go b/provider/datasource_rediscloud_database_test.go deleted file mode 100644 index 66cb451b..00000000 --- a/provider/datasource_rediscloud_database_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package provider - -import ( - "fmt" - "os" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func TestAccDataSourceRedisCloudDatabase_basic(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - password := acctest.RandString(20) - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - dataSourceName := "data.rediscloud_database.example" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccDatasourceRedisCloudDatabase, testCloudAccountName, name, password), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", "tf-database"), - resource.TestCheckResourceAttr(dataSourceName, "protocol", "redis"), - 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"), - resource.TestCheckResourceAttr(dataSourceName, "throughput_measurement_by", "operations-per-second"), - resource.TestCheckResourceAttr(dataSourceName, "throughput_measurement_value", "1000"), - resource.TestCheckResourceAttr(dataSourceName, "password", password), - resource.TestCheckResourceAttrSet(dataSourceName, "public_endpoint"), - resource.TestCheckResourceAttrSet(dataSourceName, "private_endpoint"), - resource.TestCheckResourceAttr(dataSourceName, "enable_default_user", "true"), - ), - }, - }, - }) -} - -func TestAccDataSourceRedisCloudDatabase_filterAADatabases(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - password := acctest.RandString(20) - - dataSourceName := "data.rediscloud_database.example" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccDatasourceRedisCloudAADatabase, name+"-subscription", name+"-database", password), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", name+"-database"), - resource.TestCheckResourceAttr(dataSourceName, "protocol", "redis"), - resource.TestCheckResourceAttr(dataSourceName, "support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(dataSourceName, "data_eviction", "volatile-lru"), - ), - }, - }, - }) -} - -const testAccDatasourceRedisCloudDatabase = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=true - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - modules = ["RedisJSON", "RedisBloom"] - } -} - -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_subscription.example.id - name = "tf-database" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - password = "%s" - support_oss_cluster_api = true - replication = false - enable_default_user = true -} - -data "rediscloud_database" "example" { - subscription_id = rediscloud_subscription.example.id - name = rediscloud_subscription_database.example.name -} -` - -const testAccDatasourceRedisCloudAADatabase = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} -resource "rediscloud_active_active_subscription" "example" { - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - cloud_provider = "AWS" - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - region { - region = "us-east-1" - networking_deployment_cidr = "192.168.0.0/24" - write_operations_per_second = 1000 - read_operations_per_second = 1000 - } - region { - region = "us-east-2" - networking_deployment_cidr = "10.0.1.0/24" - write_operations_per_second = 1000 - read_operations_per_second = 1000 - } - } -} -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 3 - support_oss_cluster_api = false - external_endpoint_for_oss_cluster_api = false - enable_tls = false - - global_data_persistence = "none" - global_password = "%s" - global_source_ips = ["192.168.0.0/16", "192.170.0.0/16"] - global_alert { - name = "dataset-size" - value = 40 - } - override_region { - name = "us-east-1" - override_global_data_persistence = "aof-every-write" - override_global_source_ips = ["192.175.0.0/16"] - override_global_password = "region-specific-password" - override_global_alert { - name = "dataset-size" - value = 42 - } - } - override_region { - name = "us-east-2" - } -} -data "rediscloud_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = rediscloud_active_active_subscription_database.example.name -} -` diff --git a/provider/datasource_rediscloud_subscription_peerings_test.go b/provider/datasource_rediscloud_subscription_peerings_test.go index 468440ee..d9226f8f 100644 --- a/provider/datasource_rediscloud_subscription_peerings_test.go +++ b/provider/datasource_rediscloud_subscription_peerings_test.go @@ -36,7 +36,7 @@ func TestAccDataSourceRedisCloudSubscriptionPeerings_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPeeringPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: tf, diff --git a/provider/datasource_rediscloud_subscription_test.go b/provider/datasource_rediscloud_subscription_test.go deleted file mode 100644 index 07dd1abb..00000000 --- a/provider/datasource_rediscloud_subscription_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package provider - -import ( - "fmt" - "os" - "regexp" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func TestAccDataSourceRedisCloudSubscription_basic(t *testing.T) { - name := acctest.RandomWithPrefix("tf-test") - - resourceName := "rediscloud_subscription.example" - dataSourceName := "data.rediscloud_subscription.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccDatasourceRedisCloudSubscription, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr(resourceName, "name", regexp.MustCompile(name)), - ), - }, - { - Config: fmt.Sprintf(testAccDatasourceRedisCloudSubscriptionDataSource, name) + fmt.Sprintf(testAccDatasourceRedisCloudSubscription, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr(dataSourceName, "name", regexp.MustCompile(name)), - resource.TestCheckResourceAttr(dataSourceName, "payment_method", "credit-card"), - resource.TestCheckResourceAttrSet(dataSourceName, "payment_method_id"), - resource.TestMatchResourceAttr(dataSourceName, "memory_storage", regexp.MustCompile("ram")), - resource.TestCheckResourceAttr(dataSourceName, "number_of_databases", "1"), - resource.TestCheckResourceAttr(dataSourceName, "cloud_provider.0.provider", "AWS"), - resource.TestCheckResourceAttrSet(dataSourceName, "cloud_provider.0.cloud_account_id"), - resource.TestCheckResourceAttr(dataSourceName, "cloud_provider.0.region.0.region", "eu-west-1"), - resource.TestCheckResourceAttr(dataSourceName, "cloud_provider.0.region.0.networks.0.networking_deployment_cidr", "10.0.0.0/24"), - resource.TestCheckResourceAttr(dataSourceName, "status", "active"), - - resource.TestCheckResourceAttr(dataSourceName, "pricing.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.type", "Shards"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.type_details", "micro"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.quantity", "2"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.quantity_measurement", "shards"), - resource.TestCheckResourceAttrSet(dataSourceName, "pricing.0.price_per_unit"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.price_currency", "USD"), - resource.TestCheckResourceAttr(dataSourceName, "pricing.0.price_period", "hour"), - ), - }, - }, - }) -} - -const testAccDatasourceRedisCloudSubscription = ` - -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method = "credit-card" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication = false - support_oss_cluster_api = false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - modules = [] - } -} - -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_subscription.example.id - name = "tf-database" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 -} -` - -const testAccDatasourceRedisCloudSubscriptionDataSource = ` - -data "rediscloud_subscription" "example" { - name = "%s" -} -` diff --git a/provider/rediscloud_active_active_database_test.go b/provider/rediscloud_active_active_database_test.go index 8f7aac3f..98ae6df8 100644 --- a/provider/rediscloud_active_active_database_test.go +++ b/provider/rediscloud_active_active_database_test.go @@ -225,7 +225,7 @@ func TestAccResourceRedisCloudActiveActiveDatabase_timeUtcRequiresValidInterval( resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckActiveActiveSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveDatabaseInvalidTimeUtc, testCloudAccountName, name, password), diff --git a/provider/rediscloud_active_active_subscription_database_test.go b/provider/rediscloud_active_active_subscription_database_test.go deleted file mode 100644 index 1423c357..00000000 --- a/provider/rediscloud_active_active_subscription_database_test.go +++ /dev/null @@ -1,443 +0,0 @@ -package provider - -import ( - "context" - "fmt" - "os" - "regexp" - "strconv" - "testing" - - "github.com/RedisLabs/rediscloud-go-api/redis" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -// Checks CRUDI (CREATE,READ,UPDATE,IMPORT) operations on the database resource. -func TestAccResourceRedisCloudActiveActiveSubscriptionDatabase_CRUDI(t *testing.T) { - - subscriptionName := acctest.RandomWithPrefix(testResourcePrefix) + "-subscription" - name := acctest.RandomWithPrefix(testResourcePrefix) + "-database" - password := acctest.RandString(20) - resourceName := "rediscloud_active_active_subscription_database.example" - datasourceName := "data.rediscloud_active_active_database.example" - subscriptionResourceName := "rediscloud_active_active_subscription.example" - - var subId int - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckActiveActiveSubscriptionDestroy, - Steps: []resource.TestStep{ - // Test database creation - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabase, subscriptionName, name, password), - Check: resource.ComposeTestCheckFunc( - // Test resource - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "memory_limit_in_gb", "3"), - resource.TestCheckResourceAttr(resourceName, "support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "global_data_persistence", "none"), - resource.TestCheckResourceAttr(resourceName, "external_endpoint_for_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "global_password", password), - resource.TestCheckResourceAttr(resourceName, "enable_tls", "false"), - resource.TestCheckResourceAttr(resourceName, "data_eviction", "volatile-lru"), - resource.TestCheckResourceAttr(resourceName, "global_alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "global_alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "global_alert.0.value", "40"), - resource.TestCheckResourceAttr(resourceName, "global_modules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "global_modules.0", "RedisJSON"), - resource.TestCheckResourceAttr(resourceName, "global_source_ips.#", "2"), - - resource.TestCheckResourceAttr(resourceName, "override_region.#", "2"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.name", "us-east-1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_data_persistence", "aof-every-write"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_password", "region-specific-password"), - // check override region alert block - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.0.value", "42"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_source_ips.#", "1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_source_ips.0", "192.175.0.0/16"), - - // Check that global values are used for the second region where no override is set - resource.TestCheckResourceAttr(resourceName, "override_region.1.name", "us-east-2"), - resource.TestCheckResourceAttr(resourceName, "override_region.1.override_global_data_persistence", ""), - resource.TestCheckResourceAttr(resourceName, "override_region.1.override_global_password", ""), - resource.TestCheckResourceAttr(resourceName, "override_region.1.override_global_alert.#", "0"), - resource.TestCheckResourceAttr(resourceName, "override_region.1.override_source_ips.#", "0"), - - // Test databases exist - func(s *terraform.State) error { - r := s.RootModule().Resources[subscriptionResourceName] - - var err error - subId, err = strconv.Atoi(r.Primary.ID) - if err != nil { - return fmt.Errorf("couldn't parse the subscription ID: %s", redis.StringValue(&r.Primary.ID)) - } - - client := testProvider.Meta().(*apiClient) - sub, err := client.client.Subscription.Get(context.TODO(), subId) - if err != nil { - return err - } - - if redis.StringValue(sub.Name) != subscriptionName { - return fmt.Errorf("unexpected name value: %s", redis.StringValue(sub.Name)) - } - - listDb := client.client.Database.List(context.TODO(), subId) - if listDb.Next() != true { - return fmt.Errorf("no database found: %s", listDb.Err()) - } - if listDb.Err() != nil { - return listDb.Err() - } - - return nil - }, - - // Test datasource - resource.TestCheckResourceAttrSet(datasourceName, "subscription_id"), - resource.TestCheckResourceAttrSet(datasourceName, "db_id"), - resource.TestCheckResourceAttr(datasourceName, "name", name), - resource.TestCheckResourceAttr(datasourceName, "memory_limit_in_gb", "3"), - resource.TestCheckResourceAttr(datasourceName, "support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(datasourceName, "external_endpoint_for_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(datasourceName, "enable_tls", "false"), - resource.TestCheckResourceAttr(datasourceName, "data_eviction", "volatile-lru"), - resource.TestCheckResourceAttr(datasourceName, "global_modules.#", "1"), - resource.TestCheckResourceAttr(datasourceName, "global_modules.0", "RedisJSON"), - ), - }, - // Test database is updated successfully, including updates to both global and local alerts and clearing modules - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabaseUpdate, subscriptionName, name), - Check: resource.ComposeTestCheckFunc( - // Test resource - resource.TestCheckResourceAttr(resourceName, "memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(resourceName, "support_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "external_endpoint_for_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "global_data_persistence", "aof-every-1-second"), - resource.TestCheckResourceAttr(resourceName, "global_password", "updated-password"), - resource.TestCheckResourceAttr(resourceName, "global_alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "global_alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "global_alert.0.value", "60"), - - // Changes are ignored after creation - resource.TestCheckResourceAttr(resourceName, "global_modules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "global_modules.0", "RedisJSON"), - - resource.TestCheckResourceAttr(resourceName, "override_region.#", "1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.name", "us-east-1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_data_persistence", "none"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_password", "password-updated"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.0.value", "41"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_source_ips.#", "0"), - - // Test datasource - resource.TestCheckResourceAttr(datasourceName, "memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(datasourceName, "support_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(datasourceName, "external_endpoint_for_oss_cluster_api", "true"), - ), - }, - // Test database is updated, including deletion of global and local alerts and replacing modules - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabaseUpdateNoAlerts, subscriptionName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(resourceName, "support_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "external_endpoint_for_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "global_data_persistence", "aof-every-1-second"), - resource.TestCheckResourceAttr(resourceName, "global_password", "updated-password"), - resource.TestCheckResourceAttr(resourceName, "global_alert.#", "0"), - resource.TestCheckResourceAttr(resourceName, "global_modules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "global_modules.0", "RedisJSON"), - - resource.TestCheckResourceAttr(resourceName, "override_region.#", "1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.name", "us-east-1"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_data_persistence", "none"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_password", "password-updated"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_alert.#", "0"), - resource.TestCheckResourceAttr(resourceName, "override_region.0.override_global_source_ips.#", "0"), - ), - }, - // Test that that database is imported successfully - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabaseImport, subscriptionName, name), - ResourceName: "rediscloud_active_active_subscription_database.example", - ImportState: true, - ImportStateVerify: true, - // global and override attributes not supported as part of import - ImportStateVerifyIgnore: []string{ - "global_data_persistence", - "global_password", - "global_source_ips.#", - "global_source_ips.0", - "override_region.#", - "override_region.0.%", - "override_region.0.name", - "override_region.0.override_global_alert.#", - "override_region.0.override_global_alert.0.%", - "override_region.0.override_global_alert.0.name", - "override_region.0.override_global_alert.0.value", - "override_region.0.override_global_data_persistence", - "override_region.0.override_global_password", - }, - }, - }, - }) -} - -func TestAccResourceRedisCloudActiveActiveSubscriptionDatabase_optionalAttributes(t *testing.T) { - // Test that attributes can be optional, either by setting them or not having them set when compared to CRUDI test - subscriptionName := acctest.RandomWithPrefix(testResourcePrefix) + "-subscription" - name := acctest.RandomWithPrefix(testResourcePrefix) + "-database" - password := acctest.RandString(20) - resourceName := "rediscloud_active_active_subscription_database.example" - portNumber := 10101 - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckActiveActiveSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabaseOptionalAttributes, subscriptionName, name, password, portNumber), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "port", strconv.Itoa(portNumber)), - ), - }, - }, - }) -} - -func TestAccResourceRedisCloudActiveActiveSubscriptionDatabase_timeUtcRequiresValidInterval(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - password := acctest.RandString(20) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudActiveActiveSubscriptionDatabaseInvalidTimeUtc, testCloudAccountName, name, password), - ExpectError: regexp.MustCompile("unexpected value at override_region\\.\\d*\\.remote_backup\\.0\\.time_utc - time_utc can only be set when interval is either every-24-hours or every-12-hours"), - }, - }, - }) -} - -// Create and Read tests -// TF config for provisioning a new database -const testAccResourceRedisCloudActiveActiveSubscriptionDatabase = activeActiveSubscriptionBoilerplate + ` -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 3 - support_oss_cluster_api = false - external_endpoint_for_oss_cluster_api = false - enable_tls = false - - global_data_persistence = "none" - global_password = "%s" - global_source_ips = ["192.168.0.0/16", "192.170.0.0/16"] - global_alert { - name = "dataset-size" - value = 40 - } - global_modules = ["RedisJSON"] - override_region { - name = "us-east-1" - override_global_data_persistence = "aof-every-write" - override_global_source_ips = ["192.175.0.0/16"] - override_global_password = "region-specific-password" - override_global_alert { - name = "dataset-size" - value = 42 - } - } - override_region { - name = "us-east-2" - } - -} - -data "rediscloud_active_active_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = rediscloud_active_active_subscription_database.example.name -} -` - -// TF config for updating a database -const testAccResourceRedisCloudActiveActiveSubscriptionDatabaseUpdate = activeActiveSubscriptionBoilerplate + ` -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 1 - support_oss_cluster_api = true - external_endpoint_for_oss_cluster_api = true - - global_data_persistence = "aof-every-1-second" - global_password = "updated-password" - global_source_ips = ["192.170.0.0/16"] - global_alert { - name = "dataset-size" - value = 60 - } - global_modules = [] - - override_region { - name = "us-east-1" - override_global_data_persistence = "none" - override_global_password = "password-updated" - override_global_alert { - name = "dataset-size" - value = 41 - } - } -} - -data "rediscloud_active_active_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = rediscloud_active_active_subscription_database.example.name -} -` - -const testAccResourceRedisCloudActiveActiveSubscriptionDatabaseUpdateNoAlerts = activeActiveSubscriptionBoilerplate + ` -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 1 - support_oss_cluster_api = true - external_endpoint_for_oss_cluster_api = true - - global_data_persistence = "aof-every-1-second" - global_password = "updated-password" - global_source_ips = ["192.170.0.0/16"] - - global_modules = ["RedisJSON"] - - override_region { - name = "us-east-1" - override_global_data_persistence = "none" - override_global_password = "password-updated" - } -} -` - -// TF config for updating a database -const testAccResourceRedisCloudActiveActiveSubscriptionDatabaseImport = activeActiveSubscriptionBoilerplate + ` -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 1 -} -` - -const testAccResourceRedisCloudActiveActiveSubscriptionDatabaseOptionalAttributes = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -resource "rediscloud_active_active_subscription" "example" { - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - cloud_provider = "AWS" - redis_version = "latest" - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - region { - region = "us-east-1" - networking_deployment_cidr = "192.168.0.0/24" - write_operations_per_second = 1000 - read_operations_per_second = 1000 - } - region { - region = "us-east-2" - networking_deployment_cidr = "10.0.1.0/24" - write_operations_per_second = 1000 - read_operations_per_second = 1000 - } - } -} - -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 3 - support_oss_cluster_api = false - external_endpoint_for_oss_cluster_api = false - enable_tls = false - global_resp_version = "resp3" - - global_data_persistence = "none" - global_password = "%s" - global_source_ips = ["192.168.0.0/16", "192.170.0.0/16"] - global_alert { - name = "dataset-size" - value = 40 - } - override_region { - name = "us-east-1" - override_global_data_persistence = "aof-every-write" - override_global_source_ips = ["192.175.0.0/16"] - override_global_password = "region-specific-password" - override_global_alert { - name = "dataset-size" - value = 42 - } - } - override_region { - name = "us-east-2" - } - port = %d -} -` - -const testAccResourceRedisCloudActiveActiveSubscriptionDatabaseInvalidTimeUtc = activeActiveSubscriptionBoilerplate + ` -resource "rediscloud_active_active_subscription_database" "example" { - subscription_id = rediscloud_active_active_subscription.example.id - name = "%s" - memory_limit_in_gb = 3 - support_oss_cluster_api = false - external_endpoint_for_oss_cluster_api = false - enable_tls = false - - global_data_persistence = "none" - global_password = "%s" - global_source_ips = ["192.168.0.0/16", "192.170.0.0/16"] - global_alert { - name = "dataset-size" - value = 40 - } - override_region { - name = "us-east-1" - override_global_data_persistence = "aof-every-write" - override_global_source_ips = ["192.175.0.0/16"] - override_global_password = "region-specific-password" - override_global_alert { - name = "dataset-size" - value = 42 - } - remote_backup { - interval = "every-6-hours" - time_utc = "16:00" - storage_type = "aws-s3" - storage_path = "uri://interval.not.12.or.24.hours.test" - } - } - override_region { - name = "us-east-2" - } -} -` diff --git a/provider/resource_rediscloud_flexible_database.go b/provider/resource_rediscloud_flexible_database.go index 10f2a1fa..495bd0b7 100644 --- a/provider/resource_rediscloud_flexible_database.go +++ b/provider/resource_rediscloud_flexible_database.go @@ -473,7 +473,7 @@ func resourceRedisCloudFlexibleDatabaseCreate(ctx context.Context, d *schema.Res // 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, enableDefaultUser and so on. subscriptionMutex.Unlock(subId) - return resourceRedisCloudSubscriptionDatabaseUpdate(ctx, d, meta) + return resourceRedisCloudFlexibleDatabaseUpdate(ctx, d, meta) } func resourceRedisCloudFlexibleDatabaseRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -766,7 +766,7 @@ func resourceRedisCloudFlexibleDatabaseUpdate(ctx context.Context, d *schema.Res return diag.FromErr(err) } - return resourceRedisCloudSubscriptionDatabaseRead(ctx, d, meta) + return resourceRedisCloudFlexibleDatabaseRead(ctx, d, meta) } func buildBackupPlan(data interface{}, periodicBackupPath interface{}) *databases.DatabaseBackupConfig { diff --git a/provider/resource_rediscloud_flexible_database_test.go b/provider/resource_rediscloud_flexible_database_test.go index daaf90f0..ec5ab01d 100644 --- a/provider/resource_rediscloud_flexible_database_test.go +++ b/provider/resource_rediscloud_flexible_database_test.go @@ -29,7 +29,7 @@ func TestAccResourceRedisCloudFlexibleDatabase_CRUDI(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ // Test database and replica database creation { @@ -161,7 +161,7 @@ func TestAccResourceRedisCloudFlexibleDatabase_optionalAttributes(t *testing.T) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudFlexibleDatabaseOptionalAttributes, testCloudAccountName, name, portNumber), @@ -181,7 +181,7 @@ func TestAccResourceRedisCloudFlexibleDatabase_timeUtcRequiresValidInterval(t *t resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudFlexibleDatabaseInvalidTimeUtc, testCloudAccountName, name), @@ -201,7 +201,7 @@ func TestAccResourceRedisCloudFlexibleDatabase_MultiModules(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudFlexibleDatabaseMultiModules, testCloudAccountName, name, dbName), @@ -231,7 +231,7 @@ func TestAccResourceRedisCloudFlexibleDatabase_respversion(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudFlexibleDatabaseRespVersions, testCloudAccountName, name, portNumber, "resp2"), diff --git a/provider/resource_rediscloud_flexible_subscription_tls_test.go b/provider/resource_rediscloud_flexible_subscription_tls_test.go index c57905e9..c3e4759b 100644 --- a/provider/resource_rediscloud_flexible_subscription_tls_test.go +++ b/provider/resource_rediscloud_flexible_subscription_tls_test.go @@ -49,7 +49,7 @@ func TestAccResourceRedisCloudSubscription_createWithDatabaseWithEnabledTlsAndSs testAccTLSValidCertificatePreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionOneDbWithEnableTlsAndCert, testCloudAccountName, name, 1, password, clientSslCertificate), @@ -128,7 +128,7 @@ func TestAccResourceRedisCloudSubscription_createWithDatabaseWithEnabledTlsAndEm resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionOneDbWithEnableTlsAndWithoutCert, testCloudAccountName, name, 1, password), @@ -212,7 +212,7 @@ func TestAccResourceRedisCloudSubscription_createWithDatabaseWithEnabledTlsAndIn testAccTLSInvalidCertificatePreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionOneDbWithEnableTlsAndCert, testCloudAccountName, name, 1, password, invalidClientSslCertificate), @@ -242,7 +242,7 @@ func TestAccResourceRedisCloudSubscription_createWithDatabaseAndDisabledTlsAndIn testAccTLSInvalidCertificatePreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionOneDbWithoutEnableTlsAndWithCert, testCloudAccountName, name, 1, password, invalidClientSslCertificate), diff --git a/provider/resource_rediscloud_subscription_database_test.go b/provider/resource_rediscloud_subscription_database_test.go deleted file mode 100644 index 20d0d94d..00000000 --- a/provider/resource_rediscloud_subscription_database_test.go +++ /dev/null @@ -1,471 +0,0 @@ -package provider - -import ( - "context" - "fmt" - "os" - "regexp" - "strconv" - "testing" - - "github.com/RedisLabs/rediscloud-go-api/redis" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -// Checks CRUDI (CREATE,READ,UPDATE,IMPORT) operations on the database resource. -func TestAccResourceRedisCloudSubscriptionDatabase_CRUDI(t *testing.T) { - - name := acctest.RandomWithPrefix(testResourcePrefix) - password := acctest.RandString(20) - resourceName := "rediscloud_subscription_database.example" - subscriptionResourceName := "rediscloud_flexible_subscription.example" - replicaResourceName := "rediscloud_subscription_database.example_replica" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - var subId int - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - // Test database and replica database creation - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabase, testCloudAccountName, name, password) + testAccResourceRedisCloudSubscriptionDatabaseReplica, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", "example"), - resource.TestCheckResourceAttr(resourceName, "protocol", "redis"), - resource.TestCheckResourceAttr(resourceName, "memory_limit_in_gb", "3"), - resource.TestCheckResourceAttr(resourceName, "replication", "false"), - resource.TestCheckResourceAttr(resourceName, "support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "resp_version", "resp2"), - resource.TestCheckResourceAttr(resourceName, "throughput_measurement_by", "operations-per-second"), - resource.TestCheckResourceAttr(resourceName, "throughput_measurement_value", "1000"), - resource.TestCheckResourceAttr(resourceName, "data_persistence", "none"), - resource.TestCheckResourceAttr(resourceName, "data_eviction", "allkeys-random"), - resource.TestCheckResourceAttr(resourceName, "average_item_size_in_bytes", "0"), - resource.TestCheckResourceAttr(resourceName, "client_ssl_certificate", ""), - resource.TestCheckResourceAttr(resourceName, "periodic_backup_path", ""), - resource.TestCheckResourceAttr(resourceName, "external_endpoint_for_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "password", password), - resource.TestCheckResourceAttr(resourceName, "alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "alert.0.value", "40"), - resource.TestCheckResourceAttr(resourceName, "modules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "modules.0.name", "RedisBloom"), - resource.TestCheckResourceAttr(resourceName, "enable_default_user", "true"), - // Replica tests - resource.TestCheckResourceAttr(replicaResourceName, "name", "example-replica"), - // should be the value specified in the replica config, rather than the primary database - resource.TestCheckResourceAttr(replicaResourceName, "memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(replicaResourceName, "replica_of.#", "1"), - - // Test databases exist - func(s *terraform.State) error { - r := s.RootModule().Resources[subscriptionResourceName] - - var err error - subId, err = strconv.Atoi(r.Primary.ID) - if err != nil { - return fmt.Errorf("couldn't parse the subscription ID: %s", redis.StringValue(&r.Primary.ID)) - } - - client := testProvider.Meta().(*apiClient) - sub, err := client.client.Subscription.Get(context.TODO(), subId) - if err != nil { - return err - } - - if redis.StringValue(sub.Name) != name { - return fmt.Errorf("unexpected name value: %s", redis.StringValue(sub.Name)) - } - - listDb := client.client.Database.List(context.TODO(), subId) - if listDb.Next() != true { - return fmt.Errorf("no database found: %s", listDb.Err()) - } - if listDb.Err() != nil { - return listDb.Err() - } - - return nil - }, - ), - }, - // Test database is updated successfully - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseUpdate, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", "example-updated"), - resource.TestCheckResourceAttr(resourceName, "protocol", "redis"), - resource.TestCheckResourceAttr(resourceName, "memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(resourceName, "replication", "true"), - resource.TestCheckResourceAttr(resourceName, "support_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "resp_version", "resp2"), - resource.TestCheckResourceAttr(resourceName, "throughput_measurement_by", "operations-per-second"), - resource.TestCheckResourceAttr(resourceName, "throughput_measurement_value", "2000"), - resource.TestCheckResourceAttr(resourceName, "data_persistence", "aof-every-write"), - resource.TestCheckResourceAttr(resourceName, "data_eviction", "volatile-lru"), - resource.TestCheckResourceAttr(resourceName, "average_item_size_in_bytes", "0"), - resource.TestCheckResourceAttr(resourceName, "client_ssl_certificate", ""), - resource.TestCheckResourceAttr(resourceName, "periodic_backup_path", ""), - resource.TestCheckResourceAttr(resourceName, "external_endpoint_for_oss_cluster_api", "true"), - resource.TestCheckResourceAttr(resourceName, "password", "updated-password"), - resource.TestCheckResourceAttr(resourceName, "alert.#", "1"), - resource.TestCheckResourceAttr(resourceName, "alert.0.name", "dataset-size"), - resource.TestCheckResourceAttr(resourceName, "alert.0.value", "80"), - resource.TestCheckResourceAttr(resourceName, "modules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "modules.0.name", "RedisBloom"), - resource.TestCheckResourceAttr(resourceName, "enable_default_user", "true"), - ), - }, - // Test that Alerts are deleted - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseUpdateDestroyAlerts, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "alert.#", "0"), - ), - }, - // Test that a 32-character password is generated when no password is provided - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseNoPassword, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - func(s *terraform.State) error { - is := s.RootModule().Resources["rediscloud_subscription_database.no_password_database"].Primary - if len(is.Attributes["password"]) != 32 { - return fmt.Errorf("password should be set to a random 32-character string") - } - return nil - }, - ), - }, - // Test that that database is imported successfully - { - ResourceName: "rediscloud_subscription_database.no_password_database", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscriptionDatabase_optionalAttributes(t *testing.T) { - // Test that attributes can be optional, either by setting them or not having them set when compared to CRUDI test - name := acctest.RandomWithPrefix(testResourcePrefix) - resourceName := "rediscloud_subscription_database.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - portNumber := 10101 - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseOptionalAttributes, testCloudAccountName, name, portNumber), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "protocol", "redis"), - resource.TestCheckResourceAttr(resourceName, "port", strconv.Itoa(portNumber)), - ), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscriptionDatabase_timeUtcRequiresValidInterval(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseInvalidTimeUtc, testCloudAccountName, name), - ExpectError: regexp.MustCompile("unexpected value at remote_backup\\.0\\.time_utc - time_utc can only be set when interval is either every-24-hours or every-12-hours"), - }, - }, - }) -} - -// Tests the multi-modules feature in a database resource. -func TestAccResourceRedisCloudSubscriptionDatabase_MultiModules(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - dbName := "db-multi-modules" - resourceName := "rediscloud_subscription_database.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseMultiModules, testCloudAccountName, name, dbName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", dbName), - resource.TestCheckResourceAttr(resourceName, "modules.#", "2"), - resource.TestCheckResourceAttr(resourceName, "modules.0.name", "RedisBloom"), - resource.TestCheckResourceAttr(resourceName, "modules.1.name", "RedisJSON"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscriptionDatabase_respversion(t *testing.T) { - // Test that attributes can be optional, either by setting them or not having them set when compared to CRUDI test - name := acctest.RandomWithPrefix(testResourcePrefix) - resourceName := "rediscloud_subscription_database.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - portNumber := 10101 - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseRespVersions, testCloudAccountName, name, portNumber, "resp2"), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "resp_version", "resp2"), - ), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseRespVersions, testCloudAccountName, name, portNumber, "resp3"), - ExpectError: regexp.MustCompile("Selected RESP version is not supported for this database version\\.*"), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionDatabaseRespVersions, testCloudAccountName, name, portNumber, "best_resp_100"), - ExpectError: regexp.MustCompile("Bad Request: JSON parameter contains unsupported fields / values. JSON parse error: Cannot deserialize value of type `mappings.RespVersion` from String \"best_resp_100\": not one of the values accepted for Enum class: \\[resp2, resp3]"), - }, - }, - }) -} - -const multiModulesSubscriptionBoilerplate = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} -resource "rediscloud_flexible_subscription" "example" { - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication = false - support_oss_cluster_api = false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - modules = ["RedisJSON", "RedisBloom"] - } -} -` - -// Create and Read tests -// TF config for provisioning a new database -const testAccResourceRedisCloudSubscriptionDatabase = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example" - protocol = "redis" - memory_limit_in_gb = 3 - data_persistence = "none" - data_eviction = "allkeys-random" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - password = "%s" - support_oss_cluster_api = false - external_endpoint_for_oss_cluster_api = false - replication = false - average_item_size_in_bytes = 0 - client_ssl_certificate = "" - periodic_backup_path = "" - enable_default_user = true - - alert { - name = "dataset-size" - value = 40 - } - - modules = [ - { - name = "RedisBloom" - } - ] -} -` - -const testAccResourceRedisCloudSubscriptionDatabaseOptionalAttributes = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-no-protocol" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - port = %d -} -` - -const testAccResourceRedisCloudSubscriptionDatabaseInvalidTimeUtc = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-no-protocol" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - remote_backup { - interval = "every-6-hours" - time_utc = "16:00" - storage_type = "aws-s3" - storage_path = "uri://interval.not.12.or.24.hours.test" - } -} -` - -// TF config for provisioning a database where the password is not specified -const testAccResourceRedisCloudSubscriptionDatabaseNoPassword = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "no_password_database" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-no-password" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 -} -` - -// TF config for provisioning a database which is a replica of an existing database -const testAccResourceRedisCloudSubscriptionDatabaseReplica = ` -resource "rediscloud_subscription_database" "example_replica" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-replica" - protocol = "redis" - memory_limit_in_gb = 1 - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - replica_of = [format("redis://%s", rediscloud_subscription_database.example.public_endpoint)] -} -` - -// TF config for updating a database -const testAccResourceRedisCloudSubscriptionDatabaseUpdate = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-updated" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "aof-every-write" - data_eviction = "volatile-lru" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 2000 - password = "updated-password" - support_oss_cluster_api = true - external_endpoint_for_oss_cluster_api = true - replication = true - average_item_size_in_bytes = 0 - enable_default_user = true - - alert { - name = "dataset-size" - value = 80 - } - - modules = [ - { - name = "RedisBloom" - } - ] -} -` - -const testAccResourceRedisCloudSubscriptionDatabaseUpdateDestroyAlerts = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example-updated" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "aof-every-write" - data_eviction = "volatile-lru" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 2000 - password = "updated-password" - support_oss_cluster_api = true - external_endpoint_for_oss_cluster_api = true - replication = true - average_item_size_in_bytes = 0 - - modules = [ - { - name = "RedisBloom" - } - ] -} -` - -const testAccResourceRedisCloudSubscriptionDatabaseMultiModules = multiModulesSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "%s" - protocol = "redis" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - modules = [ - { - name = "RedisJSON" - }, - { - name = "RedisBloom" - } - ] - alert { - name = "latency" - value = 11 - } -} -` - -const testAccResourceRedisCloudSubscriptionDatabaseRespVersions = flexibleSubscriptionBoilerplate + ` -resource "rediscloud_subscription_database" "example" { - subscription_id = rediscloud_flexible_subscription.example.id - name = "example" - memory_limit_in_gb = 1 - data_persistence = "none" - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 1000 - port = %d - resp_version = "%s" -} -` diff --git a/provider/resource_rediscloud_subscription_peering_test.go b/provider/resource_rediscloud_subscription_peering_test.go index 290a8842..b2000fff 100644 --- a/provider/resource_rediscloud_subscription_peering_test.go +++ b/provider/resource_rediscloud_subscription_peering_test.go @@ -52,7 +52,7 @@ func TestAccResourceRedisCloudSubscriptionPeering_aws(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAwsPeeringPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: tf, @@ -87,7 +87,7 @@ func TestAccResourceRedisCloudSubscriptionPeering_gcp(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, + CheckDestroy: testAccCheckFlexibleSubscriptionDestroy, Steps: []resource.TestStep{ { Config: tf, diff --git a/provider/resource_rediscloud_subscription_test.go b/provider/resource_rediscloud_subscription_test.go deleted file mode 100644 index 2ba26d7a..00000000 --- a/provider/resource_rediscloud_subscription_test.go +++ /dev/null @@ -1,888 +0,0 @@ -package provider - -import ( - "context" - "fmt" - "os" - "regexp" - "strconv" - "testing" - - "github.com/RedisLabs/rediscloud-go-api/redis" - "github.com/RedisLabs/rediscloud-go-api/service/databases" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/stretchr/testify/assert" -) - -// Checks CRUDI (CREATE,READ,UPDATE,IMPORT) operations on the subscription resource. -func TestAccResourceRedisCloudSubscription_CRUDI(t *testing.T) { - - name := acctest.RandomWithPrefix(testResourcePrefix) - resourceName := "rediscloud_subscription.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - var subId int - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscription, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "payment_method", "credit-card"), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.provider", "AWS"), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.region.0.preferred_availability_zones.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "cloud_provider.0.region.0.networks.0.networking_subnet_id"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.#", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.average_item_size_in_bytes", "0"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.modules.#", "2"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.modules.0", "RedisJSON"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.modules.1", "RedisBloom"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.quantity", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.replication", "false"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.throughput_measurement_by", "operations-per-second"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.throughput_measurement_value", "10000"), - - resource.TestCheckResourceAttr(resourceName, "pricing.#", "0"), - - func(s *terraform.State) error { - r := s.RootModule().Resources[resourceName] - - var err error - subId, err = strconv.Atoi(r.Primary.ID) - if err != nil { - return err - } - - client := testProvider.Meta().(*apiClient) - sub, err := client.client.Subscription.Get(context.TODO(), subId) - if err != nil { - return err - } - - if redis.StringValue(sub.Name) != name { - return fmt.Errorf("unexpected name value: %s", redis.StringValue(sub.Name)) - } - return nil - }, - ), - }, - { - // Checks if the changes in the creation plan are ignored. - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionNoCreationPlan, testCloudAccountName, name, "ram"), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "creation_plan.#", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.average_item_size_in_bytes", "0"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.memory_limit_in_gb", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.quantity", "1"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.replication", "false"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.support_oss_cluster_api", "false"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.throughput_measurement_by", "operations-per-second"), - resource.TestCheckResourceAttr(resourceName, "creation_plan.0.throughput_measurement_value", "10000"), - ), - }, - { - // Checks if the changes to the payment_method are ignored. - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionChangedPaymentMethod, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "payment_method", "credit-card"), - ), - }, - { - // Checks if the payment_method and creation_plan block are ignored after the IMPORT operation. - ResourceName: resourceName, - ImportState: true, - ImportStateCheck: func(states []*terraform.InstanceState) error { - paymentMethod, ok := states[0].Attributes["payment_method"] - if ok && paymentMethod != "credit-card" { - return fmt.Errorf("Unexpected payment_method block. Should be 'credit-card', instead of %s", paymentMethod) - } - creationPlan, ok := states[0].Attributes["creation_plan.#"] - if ok && creationPlan != "0" { - return fmt.Errorf("Unexpected creation_plan block. Should be 0, instead of %s", creationPlan) - } - return nil - }, - }, - { - // Checks if an error is raised when a ForceNew attribute is changed and the creation_plan block is not defined. - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionNoCreationPlan, testCloudAccountName, name, "ram-and-flash"), - ResourceName: resourceName, - ExpectError: regexp.MustCompile(`Error: the "creation_plan" block is required`), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscription_preferredAZsModulesOptional(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - resourceName := "rediscloud_subscription.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionPreferredAZsModulesOptional, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.region.0.preferred_availability_zones.#", "1"), - ), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscription_createUpdateContractPayment(t *testing.T) { - - if !*contractFlag { - t.Skip("The '-contract' parameter wasn't provided in the test command.") - } - - name := acctest.RandomWithPrefix(testResourcePrefix) - updatedName := fmt.Sprintf("%v-updatedName", name) - resourceName := "rediscloud_subscription.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionContractPayment, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.provider", "AWS"), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.region.0.preferred_availability_zones.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "cloud_provider.0.region.0.networks.0.networking_subnet_id"), - resource.TestCheckResourceAttrSet(resourceName, "payment_method_id"), - ), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionContractPayment, testCloudAccountName, updatedName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(resourceName, "payment_method_id"), - resource.TestCheckResourceAttr(resourceName, "name", updatedName), - ), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscription_createUpdateMarketplacePayment(t *testing.T) { - - if !*marketplaceFlag { - t.Skip("The '-marketplace' parameter wasn't provided in the test command.") - } - - name := acctest.RandomWithPrefix(testResourcePrefix) - updatedName := fmt.Sprintf("%v-updatedName", name) - resourceName := "rediscloud_subscription.example" - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionMarketplacePayment, testCloudAccountName, name), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.provider", "AWS"), - resource.TestCheckResourceAttr(resourceName, "cloud_provider.0.region.0.preferred_availability_zones.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "cloud_provider.0.region.0.networks.0.networking_subnet_id"), - ), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionMarketplacePayment, testCloudAccountName, updatedName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", updatedName), - ), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscription_SearchModuleIncompatibleWithOperationsPerSecond(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionWithSearch, testCloudAccountName, name), - ExpectError: regexp.MustCompile("subscription could not be created: throughput may not be measured by `operations-per-second` while the `RediSearch` module is active"), - }, - }, - }) -} - -func TestAccResourceRedisCloudSubscription_RedisVersion(t *testing.T) { - name := acctest.RandomWithPrefix(testResourcePrefix) - testCloudAccountName := os.Getenv("AWS_TEST_CLOUD_ACCOUNT_NAME") - - identifier := "" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccAwsPreExistingCloudAccountPreCheck(t) }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckSubscriptionDestroy, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionWithRedisVersion, testCloudAccountName, name, ""), - Check: resource.ComposeTestCheckFunc( - // Take a snapshot of the ID - func(s *terraform.State) error { - r := s.RootModule().Resources["rediscloud_subscription.test"] - identifier = r.Primary.ID - return nil - }, - ), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionWithRedisVersion, testCloudAccountName, name, "redis_version = \"latest\""), - Check: resource.ComposeTestCheckFunc( - // Take a snapshot of the ID - func(s *terraform.State) error { - r := s.RootModule().Resources["rediscloud_subscription.test"] - if r.Primary.ID == identifier { - return fmt.Errorf("entity should have a different identifier, but was still %s", identifier) - } - return nil - }, - ), - }, - { - Config: fmt.Sprintf(testAccResourceRedisCloudSubscriptionWithRedisVersion, testCloudAccountName, name, ""), - ResourceName: "rediscloud_subscription.test", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"creation_plan", "redis_version"}, - }, - }, - }) -} - -// Checks that modules are allocated correctly into each creation-plan db if there are multiple modules, including "RedisGraph" and the number of databases is one. -func TestModulesAllocationWhenGraphAndQuantityIsOne(t *testing.T) { - numDatabases := 1 - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 1000, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisJSON", "RedisGraph", "RedisBloom"}, - "quantity": numDatabases, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 10000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRamAndFlash, planMap) - assert.Empty(t, diags) - otherDatabases := 0 - graphDatabases := 0 - for _, createDb := range createDbs { - var modules []string - for _, module := range createDb.Modules { - modules = append(modules, *module.Name) - } - if len(modules) == 1 && modules[0] == "RedisGraph" { - graphDatabases++ - } - if len(modules) == 2 { - assert.ElementsMatch(t, modules, []string{"RedisJSON", "RedisBloom"}) - otherDatabases++ - } - } - assert.Len(t, createDbs, 2) - assert.True(t, graphDatabases == 1) - assert.True(t, otherDatabases == 1) -} - -// Checks that modules are allocated correctly into each creation-plan db if there are multiple modules, including "RedisGraph" and the number of databases is greater than one. -func TestModulesAllocationWhenGraphAndQuantityMoreThanOne(t *testing.T) { - numDatabases := 5 - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisJSON", "RedisGraph", "RedisBloom"}, - "quantity": numDatabases, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 10000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Empty(t, diags) - graphDatabases := 0 - otherDatabases := 0 - for _, createDb := range createDbs { - var modules []string - for _, module := range createDb.Modules { - modules = append(modules, *module.Name) - } - if len(modules) == 1 && modules[0] == "RedisGraph" { - graphDatabases++ - } - if len(modules) == 2 { - assert.ElementsMatch(t, modules, []interface{}{"RedisJSON", "RedisBloom"}) - otherDatabases++ - } - } - assert.True(t, graphDatabases == 1) - assert.True(t, otherDatabases == numDatabases-1) -} - -// Checks that modules are allocated correctly into each creation-plan db if the only module is "RedisGraph". -func TestModulesAllocationWhenOnlyGraphModule(t *testing.T) { - numDatabases := 5 - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisGraph"}, - "quantity": numDatabases, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 10000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Len(t, createDbs, numDatabases) - assert.Empty(t, diags) - for _, createDb := range createDbs { - modules := createDb.Modules - assert.True(t, len(modules) == 1 && *modules[0].Name == "RedisGraph") - } -} - -// Checks that modules are allocated correctly into the creation-plan dbs if "RedisGraph" is not included -func TestModulesAllocationWhenNoGraph(t *testing.T) { - numDatabases := 5 - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisJSON", "RediSearch", "RedisBloom"}, - "quantity": numDatabases, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "number-of-shards", - "throughput_measurement_value": 2, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Len(t, createDbs, numDatabases) - assert.Empty(t, diags) - for _, createDb := range createDbs { - var modules []string - for _, module := range createDb.Modules { - modules = append(modules, *module.Name) - } - assert.Len(t, modules, 3) - assert.ElementsMatch(t, modules, []interface{}{"RedisJSON", "RedisBloom", "RediSearch"}) - } -} - -func TestNoModulesInCreatePlanDatabases(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{}, - "quantity": 2, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 10000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Len(t, createDbs, 2) - assert.Empty(t, diags) - for _, createDb := range createDbs { - modules := createDb.Modules - assert.Len(t, modules, 0) - } -} - -func TestNoAverageItemSizeInBytes(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, // 0 is the value that is returned when the field is not present - "memory_limit_in_gb": float64(1), - "modules": []interface{}{}, - "quantity": 2, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 10000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Len(t, createDbs, 2) - assert.Empty(t, diags) - for _, createDb := range createDbs { - assert.Nil(t, createDb.AverageItemSizeInBytes) - } -} - -func TestRediSearchThroughputMeasurementWhenReplicationIsFalse(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RediSearch"}, - "quantity": 2, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "number-of-shards", - "throughput_measurement_value": 2, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Empty(t, diags) - createDb := createDbs[0] - assert.Equal(t, "number-of-shards", *createDb.ThroughputMeasurement.By) - assert.Equal(t, 2, *createDb.ThroughputMeasurement.Value) -} - -func TestRediSearchThroughputMeasurementWhenReplicationIsTrue(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RediSearch"}, - "quantity": 2, - "replication": true, - "support_oss_cluster_api": false, - "throughput_measurement_by": "number-of-shards", - "throughput_measurement_value": 2, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Empty(t, diags) - createDb := createDbs[0] - assert.Equal(t, "number-of-shards", *createDb.ThroughputMeasurement.By) - assert.Equal(t, 2, *createDb.ThroughputMeasurement.Value) -} - -func TestRediSearchIncompatibleWithOperationsPerSec(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RediSearch"}, - "quantity": 2, - "replication": true, - "support_oss_cluster_api": false, - "throughput_measurement_by": "operations-per-second", - "throughput_measurement_value": 12000, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Nil(t, createDbs) - assert.NotEmpty(t, diags) - assert.Len(t, diags, 1, "Error should be reported when using search with throughput_measurement_by=operations-per-second") - assert.Equal(t, diag.Error, diags[0].Severity) -} - -func TestRedisGraphThroughputMeasurementWhenReplicationIsFalse(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 0, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisGraph"}, - "quantity": 2, - "replication": false, - "support_oss_cluster_api": false, - "throughput_measurement_by": "number-of-shards", - "throughput_measurement_value": 2, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Empty(t, diags) - createDb := createDbs[0] - assert.Equal(t, "operations-per-second", *createDb.ThroughputMeasurement.By) - assert.Equal(t, 2*250, *createDb.ThroughputMeasurement.Value) -} - -func TestRedisGraphThroughputMeasurementWhenReplicationIsTrue(t *testing.T) { - planMap := map[string]interface{}{ - "average_item_size_in_bytes": 1000, - "memory_limit_in_gb": float64(1), - "modules": []interface{}{"RedisGraph"}, - "quantity": 2, - "replication": true, - "support_oss_cluster_api": false, - "throughput_measurement_by": "number-of-shards", - "throughput_measurement_value": 2, - } - createDbs, diags := buildSubscriptionCreatePlanDatabases(databases.MemoryStorageRam, planMap) - assert.Len(t, diags, 1, "Warning should be reported when storage was ram and using `average_item_size_in_bytes`") - assert.Equal(t, diag.Warning, diags[0].Severity) - createDb := createDbs[0] - assert.Equal(t, "operations-per-second", *createDb.ThroughputMeasurement.By) - assert.Equal(t, 2*500, *createDb.ThroughputMeasurement.Value) -} - -func testAccCheckSubscriptionDestroy(s *terraform.State) error { - client := testProvider.Meta().(*apiClient) - - for _, r := range s.RootModule().Resources { - if r.Type != "rediscloud_subscription" { - continue - } - - subId, err := strconv.Atoi(r.Primary.ID) - if err != nil { - return err - } - - subs, err := client.client.Subscription.List(context.TODO()) - if err != nil { - return err - } - - for _, sub := range subs { - if redis.IntValue(sub.ID) == subId { - return fmt.Errorf("subscription %d still exists", subId) - } - } - } - - return nil -} - -// TF config for provisioning a new subscription. -const testAccResourceRedisCloudSubscription = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method = "credit-card" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = ["RedisJSON", "RedisBloom"] - } -} -` - -const testAccResourceRedisCloudSubscriptionWithSearch = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = ["RedisJSON", "RedisBloom", "RediSearch"] - } -} -` - -const testAccResourceRedisCloudSubscriptionWithRedisVersion = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "test" { - - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - # redis_version here - %s - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = [] - } -} -` - -const testAccResourceRedisCloudSubscriptionPreferredAZsModulesOptional = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "ram" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - } -} -` - -// TF config for provisioning a subscription without the creation_plan block. -const testAccResourceRedisCloudSubscriptionNoCreationPlan = ` -data "rediscloud_payment_method" "card" { - card_type = "Visa" -} - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method_id = data.rediscloud_payment_method.card.id - memory_storage = "%s" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } -} -` - -const testAccResourceRedisCloudSubscriptionChangedPaymentMethod = ` -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - payment_method = "marketplace" - memory_storage = "ram" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 1 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = ["RedisJSON", "RedisBloom"] - } -} -` - -const testAccResourceRedisCloudSubscriptionContractPayment = ` - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - memory_storage = "ram" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 2 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = [] - } -} -` - -const testAccResourceRedisCloudSubscriptionMarketplacePayment = ` - -data "rediscloud_cloud_account" "account" { - exclude_internal_account = true - provider_type = "AWS" - name = "%s" -} - -resource "rediscloud_subscription" "example" { - - name = "%s" - memory_storage = "ram" - payment_method = "marketplace" - - allowlist { - cidrs = ["192.168.0.0/16"] - security_group_ids = [] - } - - cloud_provider { - provider = data.rediscloud_cloud_account.account.provider_type - cloud_account_id = data.rediscloud_cloud_account.account.id - region { - region = "eu-west-1" - networking_deployment_cidr = "10.0.0.0/24" - preferred_availability_zones = ["eu-west-1a"] - } - } - - creation_plan { - memory_limit_in_gb = 2 - quantity = 1 - replication=false - support_oss_cluster_api=false - throughput_measurement_by = "operations-per-second" - throughput_measurement_value = 10000 - modules = [] - } -} -`