Skip to content
This repository has been archived by the owner on Jul 21, 2020. It is now read-only.

Commit

Permalink
Implement locking for DB and LBs
Browse files Browse the repository at this point in the history
  • Loading branch information
NeilW committed May 20, 2020
1 parent 48fad05 commit 9e5babb
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 12 deletions.
29 changes: 24 additions & 5 deletions brightbox/resource_brightbox_database_server.go
Expand Up @@ -124,7 +124,8 @@ func resourceBrightboxDatabaseServer() *schema.Resource {
"locked": {
Description: "Initial password required to login, only available at creation or following a password reset request",
Type: schema.TypeBool,
Computed: true,
Optional: true,
Default: false,
},
},
}
Expand Down Expand Up @@ -181,7 +182,7 @@ func resourceBrightboxDatabaseServerCreate(
}
databaseServerOpts := getBlankDatabaseServerOpts()
databaseServerOpts.AllowAccess = map_from_string_set(d, "allow_access")
return updateDatabaseServerAttributes(d, client, databaseServerOpts)
return updateDatabaseServerAttributes(d, meta, client, databaseServerOpts)
}

func createDatabaseServer(d *schema.ResourceData, client *brightbox.Client) error {
Expand Down Expand Up @@ -209,11 +210,19 @@ func createDatabaseServer(d *schema.ResourceData, client *brightbox.Client) erro
}

d.SetId(databaseServer.Id)

if databaseServer.AdminPassword == "" {
log.Printf("[WARN] No password returned for Cloud SQL server %s", databaseServer.Id)
} else {
d.Set("admin_password", databaseServer.AdminPassword)
}

locked := d.Get("locked").(bool)
log.Printf("[INFO] Setting lock state to %v", locked)
if err := setLockState(client, locked, databaseServer); err != nil {
return err
}

log.Printf("[INFO] Waiting for Database Server (%s) to become available", d.Id())
stateConf := resource.StateChangeConf{
Pending: []string{"creating"},
Expand Down Expand Up @@ -246,7 +255,7 @@ func resourceBrightboxDatabaseServerUpdate(
assign_string_set(d, &databaseServerOpts.AllowAccess, "allow_access")
log.Printf("[DEBUG] Database Server update configuration %#v", databaseServerOpts)
outputDatabaseServerOptions(databaseServerOpts)
return updateDatabaseServerAttributes(d, client, databaseServerOpts)
return updateDatabaseServerAttributes(d, meta, client, databaseServerOpts)
}

func updateDatabaseServer(
Expand All @@ -269,18 +278,28 @@ func getBlankDatabaseServerOpts() *brightbox.DatabaseServerOptions {

func updateDatabaseServerAttributes(
d *schema.ResourceData,
meta interface{},
client *brightbox.Client,
databaseServerOpts *brightbox.DatabaseServerOptions,
) error {
if cmp.Equal(*databaseServerOpts, blankDatabaseServerOpts) {
// Shouldn't ever get here
if cmp.Equal(*databaseServerOpts, blankDatabaseServerOpts) && !d.HasChange("locked") {
return fmt.Errorf("[ERROR] No database update changes detected for %s", d.Id())
}
databaseServerOpts.Id = d.Id()
databaseServer, err := updateDatabaseServer(client, databaseServerOpts)
if err != nil {
return err
}

if d.HasChange("locked") {
locked := d.Get("locked").(bool)
log.Printf("[INFO] Setting lock state to %v", locked)
if err := setLockState(client, locked, databaseServer); err != nil {
return err
}
return resourceBrightboxDatabaseServerRead(d, meta)
}

setDatabaseServerAttributes(d, databaseServer)
return setAllowAccessAttribute(d, databaseServer)
}
Expand Down
49 changes: 47 additions & 2 deletions brightbox/resource_brightbox_database_server_test.go
Expand Up @@ -28,10 +28,11 @@ func TestAccBrightboxDatabaseServer_BasicUpdates(t *testing.T) {
CheckDestroy: testAccCheckBrightboxDatabaseServerAndOthersDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckBrightboxDatabaseServerConfig_basic(name),
Config: testAccCheckBrightboxDatabaseServerConfig_locked(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxDatabaseServerExists(resourceName, &databaseServer),
testAccCheckBrightboxEmptyDatabaseServerAttributes(&databaseServer, name),
resource.TestCheckResourceAttr(
resourceName, "locked", "true"),
resource.TestCheckResourceAttr(
resourceName, "name", name),
resource.TestCheckResourceAttr(
Expand All @@ -48,10 +49,29 @@ func TestAccBrightboxDatabaseServer_BasicUpdates(t *testing.T) {
resourceName, "allow_access.#", "1"),
),
},
{
Config: testAccCheckBrightboxDatabaseServerConfig_basic(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxDatabaseServerExists(resourceName, &databaseServer),
testAccCheckBrightboxEmptyDatabaseServerAttributes(&databaseServer, name),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
),
},
{
Config: testAccCheckBrightboxDatabaseServerConfig_locked(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxDatabaseServerExists(resourceName, &databaseServer),
resource.TestCheckResourceAttr(
resourceName, "locked", "true"),
),
},
{
Config: testAccCheckBrightboxDatabaseServerConfig_clear_names,
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxDatabaseServerExists(resourceName, &databaseServer),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
resource.TestCheckResourceAttr(
resourceName, "name", ""),
resource.TestCheckResourceAttr(
Expand Down Expand Up @@ -298,6 +318,28 @@ data "brightbox_database_type" "foobar" {

var testAccCheckBrightboxDatabaseServerConfig_clear_names = testAccCheckBrightboxDatabaseServerConfig_basic("")

func testAccCheckBrightboxDatabaseServerConfig_locked(name string) string {
return fmt.Sprintf(`
resource "brightbox_database_server" "default" {
name = "%s"
description = "%s"
database_engine = "mysql"
database_version = "8.0"
database_type = "${data.brightbox_database_type.foobar.id}"
maintenance_weekday = 6
maintenance_hour = 6
allow_access = [ "${data.brightbox_server_group.default.id}" ]
locked = true
}
data "brightbox_database_type" "foobar" {
name = "^SSD 4GB$"
}
%s
`, name, name, TestAccBrightboxDataServerGroupConfig_default)
}

func testAccCheckBrightboxDatabaseServerConfig_update_maintenance(name string) string {
return fmt.Sprintf(`
Expand Down Expand Up @@ -380,6 +422,9 @@ func init() {
}
if isTestName(object.Name) {
log.Printf("[INFO] removing %s named %s", object.Id, object.Name)
if err := setLockState(client.APIClient, false, brightbox.DatabaseServer{Id: object.Id}); err != nil {
log.Printf("error unlocking %s during sweep: %s", object.Id, err)
}
if err := client.APIClient.DestroyDatabaseServer(object.Id); err != nil {
log.Printf("error destroying %s during sweep: %s", object.Id, err)
}
Expand Down
17 changes: 16 additions & 1 deletion brightbox/resource_brightbox_load_balancer.go
Expand Up @@ -66,7 +66,8 @@ func resourceBrightboxLoadBalancer() *schema.Resource {
"locked": {
Description: "Is true if resource has been set as locked and can not be deleted",
Type: schema.TypeBool,
Computed: true,
Optional: true,
Default: false,
},
"buffer_size": {
Description: "Buffer size in bytes",
Expand Down Expand Up @@ -283,6 +284,12 @@ func resourceBrightboxLoadBalancerCreate(

d.SetId(loadBalancer.Id)

locked := d.Get("locked").(bool)
log.Printf("[INFO] Setting lock state to %v", locked)
if err := setLockState(client, locked, loadBalancer); err != nil {
return err
}

log.Printf("[INFO] Waiting for Load Balancer (%s) to become available", d.Id())

stateConf := resource.StateChangeConf{
Expand Down Expand Up @@ -345,6 +352,14 @@ func resourceBrightboxLoadBalancerUpdate(
return fmt.Errorf("Error updating loadBalancer: %s", err)
}

if d.HasChange("locked") {
locked := d.Get("locked").(bool)
log.Printf("[INFO] Setting lock state to %v", locked)
if err := setLockState(client, locked, loadBalancer); err != nil {
return err
}
return resourceBrightboxLoadBalancerRead(d, meta)
}
return setLoadBalancerAttributes(d, loadBalancer)
}

Expand Down
70 changes: 68 additions & 2 deletions brightbox/resource_brightbox_load_balancer_test.go
Expand Up @@ -22,10 +22,11 @@ func TestAccBrightboxLoadBalancer_BasicUpdates(t *testing.T) {
CheckDestroy: testAccCheckBrightboxLoadBalancerAndServerDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckBrightboxLoadBalancerConfig_basic,
Config: testAccCheckBrightboxLoadBalancerConfig_locked,
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxLoadBalancerExists(resourceName, &loadBalancer),
testAccCheckBrightboxEmptyLoadBalancerAttributes(&loadBalancer),
resource.TestCheckResourceAttr(
resourceName, "locked", "true"),
resource.TestCheckResourceAttr(
resourceName, "healthcheck.0.request", "/"),
resource.TestCheckResourceAttr(
Expand All @@ -40,6 +41,31 @@ func TestAccBrightboxLoadBalancer_BasicUpdates(t *testing.T) {
resourceName, "nodes.#", "1"),
),
},
{
Config: testAccCheckBrightboxLoadBalancerConfig_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxLoadBalancerExists(resourceName, &loadBalancer),
testAccCheckBrightboxEmptyLoadBalancerAttributes(&loadBalancer),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
),
},
{
Config: testAccCheckBrightboxLoadBalancerConfig_locked,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "locked", "true"),
),
},
{
Config: testAccCheckBrightboxLoadBalancerConfig_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxLoadBalancerExists(resourceName, &loadBalancer),
testAccCheckBrightboxEmptyLoadBalancerAttributes(&loadBalancer),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
),
},
{
ResourceName: resourceName,
ImportState: true,
Expand All @@ -49,6 +75,8 @@ func TestAccBrightboxLoadBalancer_BasicUpdates(t *testing.T) {
Config: testAccCheckBrightboxLoadBalancerConfig_new_timeout,
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxLoadBalancerExists(resourceName, &loadBalancer),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
resource.TestCheckResourceAttr(
resourceName, "listener.3297149260.timeout", "10000"),
resource.TestCheckResourceAttr(
Expand Down Expand Up @@ -234,6 +262,41 @@ resource "brightbox_server" "foobar" {
}
%s%s`, TestAccBrightboxImageDataSourceConfig_blank_disk,
TestAccBrightboxDataServerGroupConfig_default)

var testAccCheckBrightboxLoadBalancerConfig_locked = fmt.Sprintf(`
resource "brightbox_load_balancer" "default" {
name = "foo-20200513"
locked = true
listener {
protocol = "http"
in = 80
out = 8080
}
listener {
protocol = "http+ws"
in = 81
out = 81
timeout = 10000
}
healthcheck {
type = "http"
port = 8080
}
nodes = ["${brightbox_server.foobar.id}"]
}
resource "brightbox_server" "foobar" {
image = "${data.brightbox_image.foobar.id}"
name = "foo-20200426"
type = "1gb.ssd"
server_groups = ["${data.brightbox_server_group.default.id}"]
}
%s%s`, TestAccBrightboxImageDataSourceConfig_blank_disk,
TestAccBrightboxDataServerGroupConfig_default)

Expand Down Expand Up @@ -453,6 +516,9 @@ func init() {
}
if isTestName(object.Name) {
log.Printf("[INFO] removing %s named %s", object.Id, object.Name)
if err := setLockState(client.APIClient, false, brightbox.LoadBalancer{Id: object.Id}); err != nil {
log.Printf("error unlocking %s during sweep: %s", object.Id, err)
}
if err := client.APIClient.DestroyLoadBalancer(object.Id); err != nil {
log.Printf("error destroying %s during sweep: %s", object.Id, err)
}
Expand Down
28 changes: 26 additions & 2 deletions brightbox/resource_brightbox_server_test.go
Expand Up @@ -27,12 +27,12 @@ func TestAccBrightboxServer_Basic(t *testing.T) {
CheckDestroy: testAccCheckBrightboxServerDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckBrightboxServerConfig_basic(rInt),
Config: testAccCheckBrightboxServerConfig_locked(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckBrightboxServerExists(resourceName, &server),
testAccCheckBrightboxServerAttributes(&server),
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
resourceName, "locked", "true"),
resource.TestMatchResourceAttr(
resourceName, "image", imageRe),
resource.TestCheckResourceAttr(
Expand All @@ -45,6 +45,27 @@ func TestAccBrightboxServer_Basic(t *testing.T) {
resourceName, "user_data", "3dc39dda39be1205215e776bad998da361a5955d"),
),
},
{
Config: testAccCheckBrightboxServerConfig_basic(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
),
},
{
Config: testAccCheckBrightboxServerConfig_locked(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "locked", "true"),
),
},
{
Config: testAccCheckBrightboxServerConfig_basic(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
resourceName, "locked", "false"),
),
},
{
ResourceName: resourceName,
ImportState: true,
Expand Down Expand Up @@ -585,6 +606,9 @@ func init() {
}
if isTestName(object.Name) {
log.Printf("[INFO] removing %s named %s", object.Id, object.Name)
if err := setLockState(client.APIClient, false, brightbox.Server{Id: object.Id}); err != nil {
log.Printf("error unlocking %s during sweep: %s", object.Id, err)
}
if err := client.APIClient.DestroyServer(object.Id); err != nil {
log.Printf("error destroying %s during sweep: %s", object.Id, err)
}
Expand Down

0 comments on commit 9e5babb

Please sign in to comment.