Skip to content

Commit

Permalink
Support secure connect bundle for mult-dc (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
emerkle826 authored Nov 29, 2022
1 parent db9c1d1 commit 3811424
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 29 deletions.
54 changes: 53 additions & 1 deletion docs/data-sources/secure_connect_bundle_url.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,57 @@ description: |-
## Example Usage

```terraform
data "astra_secure_connect_bundle_url" "dev" {
// For single DC databases, or to just get the primary datacenter Secure Connect Bundle
data "astra_secure_connect_bundle_url" "scb" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
}
// For mult-DC databases, specify the datacenter ID
// Example 1: Hard-coded IDs
// Primary datacenter SCB
data "astra_secure_connect_bundle_url" "scb1" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-1" // for the primary dataceneter, the datacenter ID is not required
}
// Second datacenter SCB
data "astra_secure_connect_bundle_url" "scb2" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-2"
}
// Third datacenter SCB
data "astra_secure_connect_bundle_url" "scb3" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-3"
}
// Example 2: Referenced IDs
// Database example for referencing
resource astra_database "mydb" {
name = "dbname"
keyspace = "testks"
cloud_provider = "gcp"
regions = ["us-west4", "us-east4", "us-central1"]
timeouts {
create = "45m"
delete = "45m"
update = "45m"
}
}
// Primary datacenter SCB (GCP.us-west4)
data "astra_secure_connect_bundle_url" "scb1" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[0]}"] // for the primary dataceneter, the datacenter ID is not required
}
// Second datacenter SCB (GCP.us-east4)
data "astra_secure_connect_bundle_url" "scb2" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[1]}"]
}
// Third datacenter SCB (GCP.us-central1)
data "astra_secure_connect_bundle_url" "scb3" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[2]}"]
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -25,6 +73,10 @@ data "astra_secure_connect_bundle_url" "dev" {

- `database_id` (String) The ID of the Astra database.

### Optional

- `datacenter_id` (String) The ID of the Astra datacenter. If omitted, only the primary datacenter will be used.

### Read-Only

- `id` (String) The ID of this resource.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
data "astra_secure_connect_bundle_url" "dev" {
// For single DC databases, or to just get the primary datacenter Secure Connect Bundle
data "astra_secure_connect_bundle_url" "scb" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
}
}

// For mult-DC databases, specify the datacenter ID
// Example 1: Hard-coded IDs
// Primary datacenter SCB
data "astra_secure_connect_bundle_url" "scb1" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-1" // for the primary dataceneter, the datacenter ID is not required
}
// Second datacenter SCB
data "astra_secure_connect_bundle_url" "scb2" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-2"
}
// Third datacenter SCB
data "astra_secure_connect_bundle_url" "scb3" {
database_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73"
datacenter_id = "f9f4b1e0-4c05-451e-9bba-d631295a7f73-3"
}

// Example 2: Referenced IDs
// Database example for referencing
resource astra_database "mydb" {
name = "dbname"
keyspace = "testks"
cloud_provider = "gcp"
regions = ["us-west4", "us-east4", "us-central1"]
timeouts {
create = "45m"
delete = "45m"
update = "45m"
}
}
// Primary datacenter SCB (GCP.us-west4)
data "astra_secure_connect_bundle_url" "scb1" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[0]}"] // for the primary dataceneter, the datacenter ID is not required
}
// Second datacenter SCB (GCP.us-east4)
data "astra_secure_connect_bundle_url" "scb2" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[1]}"]
}
// Third datacenter SCB (GCP.us-central1)
data "astra_secure_connect_bundle_url" "scb3" {
database_id = astra_database.mydb.id
datacenter_id = astra_database.mydb.datacenters["${astra_database.mydb.cloud_provider}.${astra_database.mydb.regions[2]}"]
}
60 changes: 34 additions & 26 deletions internal/provider/data_source_secure_connect_bundle_url.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package provider
import (
"context"
"fmt"
"time"
"net/http"

"github.com/datastax/astra-client-go/v2/astra"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
Expand All @@ -26,7 +26,12 @@ func dataSourceSecureConnectBundleURL() *schema.Resource {
Required: true,
ValidateFunc: validation.IsUUID,
},

// Optional inputs
"datacenter_id": {
Description: "The ID of the Astra datacenter. If omitted, only the primary datacenter will be used.",
Type: schema.TypeString,
Optional: true,
},
// Computed
"url": {
Description: "The temporary download url to the secure connect bundle zip file.",
Expand All @@ -42,8 +47,9 @@ func dataSourceSecureConnectBundleURLRead(ctx context.Context, d *schema.Resourc


databaseID := d.Get("database_id").(string)
datacenterID := d.Get("datacenter_id").(string)

credsURL, err := generateSecureBundleURL(ctx, time.Minute, client, databaseID)
credsURL, err := getSecureConnectBundleURL(ctx, client, databaseID, datacenterID)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -53,34 +59,36 @@ func dataSourceSecureConnectBundleURLRead(ctx context.Context, d *schema.Resourc
return nil
}

func generateSecureBundleURL(ctx context.Context, timeout time.Duration, client astra.ClientWithResponsesInterface, databaseID string) (*astra.CredsURL, error) {
func getSecureConnectBundleURL(ctx context.Context, client astra.ClientWithResponsesInterface, databaseID, datacenterID string) (*astra.CredsURL, error) {
var credsURL *astra.CredsURL
if err := resource.RetryContext(ctx, timeout, func() *resource.RetryError {
resp, err := client.GenerateSecureBundleURLWithResponse(ctx, astra.DatabaseIdParam(databaseID))
if err != nil || resp.StatusCode() >= 500 {
return resource.RetryableError(err)
}

// 409 Conflict can be returned if the database is not yet ready
if resp.JSON409 != nil {
return resource.RetryableError(fmt.Errorf("cannot create secure bundle url: %s", string(resp.Body)))
}
// fetch dataceneters for the specified DB ID
datacenterResp, err := client.ListDatacentersWithResponse(ctx, databaseID, &astra.ListDatacentersParams{})
if err != nil {
return nil, err
}
if datacenterResp.StatusCode() > http.StatusOK {
return nil, fmt.Errorf("Failed to retrieve datacenters for Database with ID: %s. Response code: %d, msg = %s", databaseID, datacenterResp.StatusCode(), string(datacenterResp.Body))
}

// Any other 400 status code is not retried
if resp.StatusCode() >= 400 {
return resource.NonRetryableError(fmt.Errorf("error trying to create secure bundle url: %s", string(resp.Body)))
}
// if no datacenter ID specified, then use the primary datacenter ID, should be <dbid-1>
if datacenterID == "" {
datacenterID = databaseID+"-1"
}

// Any response other than 200 is unexpected
credsURL = resp.JSON200
if credsURL == nil {
return resource.NonRetryableError(fmt.Errorf("unexpected response creating secure bundle url: %s", string(resp.Body)))
// find the URL for the datacenter ID
for _, dc := range *datacenterResp.JSON200 {
if datacenterID == *dc.Id {
return &astra.CredsURL{
DownloadURL: *dc.SecureBundleUrl,
DownloadURLInternal: dc.SecureBundleInternalUrl,
DownloadURLMigrationProxy: dc.SecureBundleMigrationProxyUrl,
DownloadURLMigrationProxyInternal: dc.SecureBundleMigrationProxyInternalUrl,
}, nil
}

return nil
}); err != nil {
return nil, err
}

tflog.Error(ctx, fmt.Sprintf("Could not find Datacenter with ID: %s", databaseID))
return credsURL, nil
}

0 comments on commit 3811424

Please sign in to comment.