Skip to content

Commit

Permalink
Add region type filtering for regions (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
emerkle826 authored May 16, 2024
1 parent f4853d5 commit 6af6ee3
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 12 deletions.
44 changes: 43 additions & 1 deletion docs/data-sources/available_regions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 generated by tfplugindocs -->
## 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.
Expand All @@ -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)
35 changes: 34 additions & 1 deletion examples/data-sources/astra_available_regions/data-source.tf
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
67 changes: 62 additions & 5 deletions internal/provider/data_source_available_regions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,44 @@ 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",

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.",
Expand All @@ -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,
},
},
},
},
Expand All @@ -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 = &regionType
}
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 {
Expand All @@ -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(&region))
}

Expand All @@ -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,
}
}
28 changes: 28 additions & 0 deletions internal/provider/data_source_available_regions_test.go
Original file line number Diff line number Diff line change
@@ -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" {
}
`)
}
9 changes: 7 additions & 2 deletions internal/provider/resource_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 = &regionType
}
regionsResp, err := client.ListServerlessRegionsWithResponse(ctx, params)
if err != nil {
return diag.FromErr(err)
} else if regionsResp.StatusCode() != http.StatusOK {
Expand Down

0 comments on commit 6af6ee3

Please sign in to comment.