Skip to content

Commit

Permalink
resiliency for keyspace additions
Browse files Browse the repository at this point in the history
  • Loading branch information
phact committed Sep 7, 2021
1 parent a1a190a commit f705379
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 7 deletions.
54 changes: 47 additions & 7 deletions internal/provider/resource_keyspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"strings"

"github.com/datastax/astra-client-go/v2/astra"
Expand Down Expand Up @@ -49,17 +50,56 @@ func resourceKeyspaceCreate(ctx context.Context, d *schema.ResourceData, meta in
databaseID := d.Get("database_id").(string)
keyspaceName := d.Get("name").(string)

resp, err := client.AddKeyspaceWithResponse(ctx, astra.DatabaseIdParam(databaseID), astra.KeyspaceNameParam(keyspaceName))
if err != nil {
return diag.FromErr(err)
} else if resp.StatusCode() >= 400 {
return diag.Errorf("error adding keyspace to database: %s", string(resp.Body))
}
//Wait for DB to be in Active status
if err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
res, err := client.GetDatabaseWithResponse(ctx, astra.DatabaseIdParam(databaseID))
// Errors sending request should be retried and are assumed to be transient
if err != nil {
return resource.RetryableError(err)
}

// Status code >=5xx are assumed to be transient
if res.StatusCode() >= 500 {
return resource.RetryableError(fmt.Errorf("error while fetching database: %s", string(res.Body)))
}

// Status code > 200 NOT retried
if res.StatusCode() > 200 || res.JSON200 == nil {
return resource.NonRetryableError(fmt.Errorf("unexpected response fetching database: %s", string(res.Body)))
}

// Success fetching database
db := res.JSON200
switch db.Status {
case astra.StatusEnumERROR, astra.StatusEnumTERMINATED, astra.StatusEnumTERMINATING:
// If the database reached a terminal state it will never become active
return resource.NonRetryableError(fmt.Errorf("database failed to reach active status: status=%s", db.Status))
case astra.StatusEnumACTIVE:
resp, err := client.AddKeyspaceWithResponse(ctx, astra.DatabaseIdParam(databaseID), astra.KeyspaceNameParam(keyspaceName))
if err != nil {
return resource.NonRetryableError(fmt.Errorf("Error calling add keyspace (not retrying) %s", err))
} else if resp.StatusCode() == 409 {
// DevOps API returns 409 for concurrent modifications, these need to be retried.
return resource.RetryableError(fmt.Errorf("error adding keyspace to database (retrying): %s", string(resp.Body)))
}else if resp.StatusCode() >= 400 {
return resource.NonRetryableError(fmt.Errorf("error adding keyspace to database (not retrying): %s", string(resp.Body)))
}

if err := setKeyspaceResourceData(d, databaseID, keyspaceName); err != nil {
if err := setKeyspaceResourceData(d, databaseID, keyspaceName); err != nil {
return resource.NonRetryableError(fmt.Errorf("Error setting keyspace data (not retrying) %s", err))
}

return nil
default:
return resource.RetryableError(fmt.Errorf("expected database to be active but is %s", db.Status))
}
}); err != nil {
return diag.FromErr(err)
}




return nil
}

Expand Down
55 changes: 55 additions & 0 deletions internal/provider/resource_keyspace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package provider

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"testing"
)

func TestKeyspace(t *testing.T){
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccKeyspaceConfiguration(),
},
},
})
}

//https://www.terraform.io/docs/extend/testing/acceptance-tests/index.html
func testAccKeyspaceConfiguration() string {
return fmt.Sprintf(`
resource "astra_database" "dev" {
name = "puppies"
keyspace = "puppies"
cloud_provider = "gcp"
region = "us-east1"
}
resource "astra_keyspace" "keyspace-1" {
name = "1"
database_id = astra_database.dev.id
}
resource "astra_keyspace" "keyspace-2" {
name = "2"
database_id = astra_database.dev.id
}
resource "astra_keyspace" "keyspace-3" {
name = "3"
database_id = astra_database.dev.id
}
resource "astra_keyspace" "keyspace-4" {
name = "4"
database_id = astra_database.dev.id
}
`)
}

0 comments on commit f705379

Please sign in to comment.