diff --git a/docs/data-sources/available_regions.md b/docs/data-sources/available_regions.md index 06326bd3..151910e0 100644 --- a/docs/data-sources/available_regions.md +++ b/docs/data-sources/available_regions.md @@ -13,13 +13,52 @@ Retrieve a list of available cloud regions in Astra ## Example Usage ```terraform -data "astra_available_regions" "regions" { +# Get all available "serverless" regions. With no filtering only "serverless" regions are returned. +data "astra_available_regions" "serverless_regions" { +} + +# Get all available "serverless" regions, with explicit filtering for "serverless" +data "astra_available_regions" "serverless_regions" { + region_type = "serverless" +} + +# Get all available "vector" regions +data "astra_available_regions" "vector_regions" { + region_type = "vector" +} + +# Get all available regions, regardless of type +data "astra_available_regions" "all_regions" { + region_type = "all" +} + +# Filter regions by cloud provider (one of "aws", "azure", "gcp") +data "astra_available_regions" "aws_serverless_regions" { + cloud_provider = "aws" +} + +# Filter regions by enabled status +data "astra_available_regions" "enabled_regions" { + only_enabled = true +} + +# Filter only enabled regions in GCP for vector +data "astra_available_regions" "gcp_vector_regions" { + region_type = "vector" + cloud_provider = "gcp" + only_enabled = true } ``` ## Schema +### Optional + +- `cloud_provider` (String) The cloud provider to filter by +- `only_enabled` (Boolean) Whether to filter by enabled regions. If 'false' or omitted, all regions are returned, enabled or not +- `region_type` (String) The region type to filter by (currently either 'serverless', 'vector' or 'all'). If omitted, the default is 'serverless' + ### Read-Only - `id` (String) The ID of this resource. @@ -32,5 +71,8 @@ Read-Only: - `cloud_provider` (String) - `display_name` (String) +- `enabled` (Boolean) - `region` (String) +- `region_type` (String) +- `reserved_for_qualified_users` (Boolean) - `zone` (String) diff --git a/examples/data-sources/astra_available_regions/data-source.tf b/examples/data-sources/astra_available_regions/data-source.tf index 3cf56b8e..97c68b8e 100644 --- a/examples/data-sources/astra_available_regions/data-source.tf +++ b/examples/data-sources/astra_available_regions/data-source.tf @@ -1,2 +1,35 @@ -data "astra_available_regions" "regions" { +# Get all available "serverless" regions. With no filtering only "serverless" regions are returned. +data "astra_available_regions" "serverless_regions" { +} + +# Get all available "serverless" regions, with explicit filtering for "serverless" +data "astra_available_regions" "serverless_regions" { + region_type = "serverless" +} + +# Get all available "vector" regions +data "astra_available_regions" "vector_regions" { + region_type = "vector" +} + +# Get all available regions, regardless of type +data "astra_available_regions" "all_regions" { + region_type = "all" +} + +# Filter regions by cloud provider (one of "aws", "azure", "gcp") +data "astra_available_regions" "aws_serverless_regions" { + cloud_provider = "aws" +} + +# Filter regions by enabled status +data "astra_available_regions" "enabled_regions" { + only_enabled = true +} + +# Filter only enabled regions in GCP for vector +data "astra_available_regions" "gcp_vector_regions" { + region_type = "vector" + cloud_provider = "gcp" + only_enabled = true } diff --git a/go.mod b/go.mod index 3a1c0441..295ba7ce 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 toolchain go1.22.0 require ( - github.com/datastax/astra-client-go/v2 v2.2.52 + github.com/datastax/astra-client-go/v2 v2.2.53 github.com/datastax/pulsar-admin-client-go v0.0.0-20230707040954-1a4745e07587 github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 diff --git a/go.sum b/go.sum index 8e228f2a..6cb38578 100644 --- a/go.sum +++ b/go.sum @@ -101,8 +101,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/datastax/astra-client-go/v2 v2.2.52 h1:gpW7tRA3FvTX55SNeKbgOz+67T9XYm5OIvjLguhQzJw= -github.com/datastax/astra-client-go/v2 v2.2.52/go.mod h1:zxXWuqDkYia7PzFIL3T7RmjChc9LN81UnfI2yB4kE7M= +github.com/datastax/astra-client-go/v2 v2.2.53 h1:qWCBksV9rWi9WmSBW71IGhy3mL/QwkEw1BMG42ph540= +github.com/datastax/astra-client-go/v2 v2.2.53/go.mod h1:zxXWuqDkYia7PzFIL3T7RmjChc9LN81UnfI2yB4kE7M= github.com/datastax/pulsar-admin-client-go v0.0.0-20230707040954-1a4745e07587 h1:3jv+O0hWcz3oj3sZ9/Ov9/m1Vaqx8Ql8jp5ZeA13O5A= github.com/datastax/pulsar-admin-client-go v0.0.0-20230707040954-1a4745e07587/go.mod h1:guL8YZ5gJINN+h5Kmja1AnuzhxLU3sHQL8o/8HYLtqk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/internal/provider/data_source_available_regions.go b/internal/provider/data_source_available_regions.go index 6020ad4a..837cb362 100644 --- a/internal/provider/data_source_available_regions.go +++ b/internal/provider/data_source_available_regions.go @@ -2,13 +2,17 @@ package provider import ( "context" + "strings" "github.com/datastax/astra-client-go/v2/astra" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) +var regionTypes = []string{"serverless", "vector", "all"} + func dataSourceAvailableRegions() *schema.Resource { return &schema.Resource{ Description: "Retrieve a list of available cloud regions in Astra", @@ -16,6 +20,26 @@ func dataSourceAvailableRegions() *schema.Resource { ReadContext: dataSourceRegionsRead, Schema: map[string]*schema.Schema{ + "cloud_provider": { + Type: schema.TypeString, + Description: "The cloud provider to filter by", + Optional: true, + ValidateFunc: validation.StringInSlice(availableCloudProviders, true), + DiffSuppressFunc: ignoreCase, + }, + "region_type": { + Type: schema.TypeString, + Description: "The region type to filter by (currently either 'serverless', 'vector' or 'all'). If omitted, the default is 'serverless'", + Optional: true, + ValidateFunc: validation.StringInSlice(regionTypes, true), + DiffSuppressFunc: ignoreCase, + }, + "only_enabled": { + Type: schema.TypeBool, + Description: "Whether to filter by enabled regions. If 'false' or omitted, all regions are returned, enabled or not", + Optional: true, + Default: false, + }, "results": { Type: schema.TypeList, Description: "The list of supported Astra regions by cloud provider and tier.", @@ -42,6 +66,21 @@ func dataSourceAvailableRegions() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "region_type": { + Description: "The region type, either serverless or vector", + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Description: "Whether the region is enabled", + Type: schema.TypeBool, + Computed: true, + }, + "reserved_for_qualified_users": { + Description: "Whether the region is reserved for qualified users", + Type: schema.TypeBool, + Computed: true, + }, }, }, }, @@ -52,7 +91,14 @@ func dataSourceAvailableRegions() *schema.Resource { func dataSourceRegionsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(astraClients).astraClient.(*astra.ClientWithResponses) - regionsResp, err := client.ListServerlessRegionsWithResponse(ctx) + params := &astra.ListServerlessRegionsParams{} + if d, ok := d.GetOk("region_type"); ok { + regionType := d.(string) + params.RegionType = ®ionType + } + cloud_provider := d.Get("cloud_provider").(string) + enabled := d.Get("only_enabled").(bool) + regionsResp, err := client.ListServerlessRegionsWithResponse(ctx, params) if err != nil { return diag.FromErr(err) } else if regionsResp.StatusCode() != 200 { @@ -66,6 +112,14 @@ func dataSourceRegionsRead(ctx context.Context, d *schema.ResourceData, meta int regions := *regionsResp.JSON200 flatRegions := make([]map[string]interface{}, 0, len(regions)) for _, region := range regions { + if cloud_provider != "" && !strings.EqualFold(string(region.CloudProvider), cloud_provider) { + // skip + continue + } + if enabled && !*region.Enabled { + // skip + continue + } flatRegions = append(flatRegions, flattenRegion(®ion)) } @@ -79,9 +133,12 @@ func dataSourceRegionsRead(ctx context.Context, d *schema.ResourceData, meta int func flattenRegion(region *astra.ServerlessRegion) map[string]interface{} { return map[string]interface{}{ - "cloud_provider": region.CloudProvider, - "region": region.Name, - "zone": region.Zone, - "display_name": region.DisplayName, + "cloud_provider": region.CloudProvider, + "region": region.Name, + "zone": region.Zone, + "display_name": region.DisplayName, + "region_type": region.RegionType, + "enabled": region.Enabled, + "reserved_for_qualified_users": region.ReservedForQualifiedUsers, } } diff --git a/internal/provider/data_source_available_regions_test.go b/internal/provider/data_source_available_regions_test.go new file mode 100644 index 00000000..516d13fc --- /dev/null +++ b/internal/provider/data_source_available_regions_test.go @@ -0,0 +1,28 @@ +package provider + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAvailableRegionsDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccAvailableRegionsDataSource(), + }, + }, + }) +} + +// https://www.terraform.io/docs/extend/testing/acceptance-tests/index.html +func testAccAvailableRegionsDataSource() string { + return fmt.Sprintf(` +data "astra_available_regions" "dev" { +} +`) +} diff --git a/internal/provider/resource_database.go b/internal/provider/resource_database.go index df4b3c02..835ca724 100644 --- a/internal/provider/resource_database.go +++ b/internal/provider/resource_database.go @@ -596,8 +596,13 @@ func flattenDatabase(db *astra.Database) map[string]interface{} { } func ensureValidRegions(ctx context.Context, client *astra.ClientWithResponses, resourceData *schema.ResourceData) diag.Diagnostics { - // get the list of serveless regions - regionsResp, err := client.ListServerlessRegionsWithResponse(ctx) + params := &astra.ListServerlessRegionsParams{} + // get the list of regions + if resourceData.Get("db_type").(string) == "vector" { + regionType := "vector" + params.RegionType = ®ionType + } + regionsResp, err := client.ListServerlessRegionsWithResponse(ctx, params) if err != nil { return diag.FromErr(err) } else if regionsResp.StatusCode() != http.StatusOK {