Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add deletion_protection field for bigtable instance #3450

Merged
merged 3 commits into from
May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions products/bigtable/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
instance_name: "bt-instance"
app_profile_name: "bt-profile"
deletion_protection: "true"
test_vars_overrides:
deletion_protection: "false"
oics_vars_overrides:
deletion_protection: "false"
ignore_read_extra:
- "ignore_warnings"
- !ruby/object:Provider::Terraform::Examples
Expand All @@ -36,6 +41,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
instance_name: "bt-instance"
app_profile_name: "bt-profile"
deletion_protection: "true"
test_vars_overrides:
deletion_protection: "false"
oics_vars_overrides:
deletion_protection: "false"
ignore_read_extra:
- "ignore_warnings"
properties:
Expand Down
10 changes: 9 additions & 1 deletion provider/terraform/examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class Examples < Api::Object
# }
attr_reader :test_vars_overrides

# Hash to provider custom override values for generating oics config
# See test_vars_overrides for more details
attr_reader :oics_vars_overrides

# The version name of of the example's version if it's different than the
# resource version, eg. `beta`
#
Expand Down Expand Up @@ -193,10 +197,14 @@ def config_test_body

def config_example
@vars ||= []
@oics_vars_overrides ||= {}

rand_vars = vars.map { |k, str| [k, "#{str}-${local.name_suffix}"] }.to_h

# Examples with test_env_vars are skipped elsewhere
body = lines(compile_file(
{
vars: vars.map { |k, str| [k, "#{str}-${local.name_suffix}"] }.to_h,
vars: rand_vars.merge(oics_vars_overrides),
primary_resource_id: primary_resource_id
},
config_path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}

deletion_protection = "<%= ctx[:vars]['deletion_protection'] %>"
}

resource "google_bigtable_app_profile" "ap" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}

deletion_protection = "<%= ctx[:vars]['deletion_protection'] %>"
}

resource "google_bigtable_app_profile" "ap" {
Expand Down
18 changes: 18 additions & 0 deletions third_party/terraform/resources/resource_bigtable_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ func resourceBigtableInstance() *schema.Resource {
resourceBigtableInstanceClusterReorderTypeList,
),

SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceBigtableInstanceResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: resourceBigtableInstanceUpgradeV0,
Version: 0,
},
},

// ----------------------------------------------------------------------
// IMPORTANT: Do not add any additional ForceNew fields to this resource.
// Destroying/recreating instances can lead to data loss for users.
Expand Down Expand Up @@ -82,6 +91,12 @@ func resourceBigtableInstance() *schema.Resource {
ValidateFunc: validation.StringInSlice([]string{"DEVELOPMENT", "PRODUCTION"}, false),
},

"deletion_protection": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},

"project": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -235,6 +250,9 @@ func resourceBigtableInstanceUpdate(d *schema.ResourceData, meta interface{}) er
}

func resourceBigtableInstanceDestroy(d *schema.ResourceData, meta interface{}) error {
if d.Get("deletion_protection").(bool) {
return fmt.Errorf("cannot destroy instance without setting deletion_protection=false and running `terraform apply`")
}
config := meta.(*Config)
ctx := context.Background()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package google

import (
"log"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func resourceBigtableInstanceResourceV0() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"cluster": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cluster_id": {
Type: schema.TypeString,
Required: true,
},
"zone": {
Type: schema.TypeString,
Required: true,
},
"num_nodes": {
Type: schema.TypeInt,
Optional: true,
// DEVELOPMENT instances could get returned with either zero or one node,
// so mark as computed.
Computed: true,
ValidateFunc: validation.IntAtLeast(1),
},
"storage_type": {
Type: schema.TypeString,
Optional: true,
Default: "SSD",
ValidateFunc: validation.StringInSlice([]string{"SSD", "HDD"}, false),
},
},
},
},
"display_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"instance_type": {
Type: schema.TypeString,
Optional: true,
Default: "PRODUCTION",
ValidateFunc: validation.StringInSlice([]string{"DEVELOPMENT", "PRODUCTION"}, false),
},

"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}

func resourceBigtableInstanceUpgradeV0(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
log.Printf("[DEBUG] Attributes before migration: %#v", rawState)

rawState["deletion_protection"] = true

log.Printf("[DEBUG] Attributes after migration: %#v", rawState)
return rawState, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}

deletion_protection = false
}

resource "google_bigtable_app_profile" "ap" {
Expand All @@ -71,6 +73,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}

deletion_protection = false
}

resource "google_bigtable_app_profile" "ap" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ resource "google_bigtable_instance" "instance" {
}

instance_type = "DEVELOPMENT"
deletion_protection = false
}

resource "google_bigtable_table" "table" {
Expand Down Expand Up @@ -170,6 +171,7 @@ resource "google_bigtable_instance" "instance" {
}

instance_type = "DEVELOPMENT"
deletion_protection = false
}

resource "google_bigtable_table" "table" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,7 @@ resource "google_bigtable_instance" "instance" {
zone = "us-central1-b"
storage_type = "HDD"
}

deletion_protection = false
}
`
71 changes: 64 additions & 7 deletions third_party/terraform/tests/resource_bigtable_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestAccBigtableInstance_basic(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
{
Config: testAccBigtableInstance(instanceName, 4),
Expand All @@ -40,7 +40,7 @@ func TestAccBigtableInstance_basic(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
},
})
Expand All @@ -67,7 +67,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
{
Config: testAccBigtableInstance_clusterReordered(instanceName, 5),
Expand All @@ -76,7 +76,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
{
Config: testAccBigtableInstance_clusterModified(instanceName, 5),
Expand All @@ -85,7 +85,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
{
Config: testAccBigtableInstance_clusterReordered(instanceName, 5),
Expand All @@ -94,7 +94,7 @@ func TestAccBigtableInstance_cluster(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
},
})
Expand All @@ -117,7 +117,38 @@ func TestAccBigtableInstance_development(t *testing.T) {
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type"}, // we don't read instance type back
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
},
})
}

func TestAccBigtableInstance_allowDestroy(t *testing.T) {
t.Parallel()

instanceName := fmt.Sprintf("tf-test-%s", randString(t, 10))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckBigtableInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccBigtableInstance_noAllowDestroy(instanceName, 3),
},
{
ResourceName: "google_bigtable_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back
},
{
Config: testAccBigtableInstance_noAllowDestroy(instanceName, 3),
Destroy: true,
ExpectError: regexp.MustCompile("deletion_protection"),
},
{
Config: testAccBigtableInstance(instanceName, 3),
},
},
})
Expand Down Expand Up @@ -159,6 +190,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = %d
storage_type = "HDD"
}

deletion_protection = false
}
`, instanceName, instanceName, numNodes)
}
Expand Down Expand Up @@ -199,6 +232,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = %d
storage_type = "HDD"
}

deletion_protection = false
}
`, instanceName, instanceName, numNodes, instanceName, numNodes, instanceName, numNodes, instanceName, numNodes)
}
Expand Down Expand Up @@ -237,6 +272,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}

deletion_protection = false
}
`, instanceName, instanceName, instanceName, instanceName, instanceName, instanceName)
}
Expand Down Expand Up @@ -269,6 +306,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = %d
storage_type = "HDD"
}

deletion_protection = false
}
`, instanceName, instanceName, numNodes, instanceName, numNodes, instanceName, numNodes, instanceName, numNodes)
}
Expand All @@ -295,6 +334,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = %d
storage_type = "HDD"
}

deletion_protection = false
}
`, instanceName, instanceName, numNodes, instanceName, numNodes, instanceName, numNodes)
}
Expand All @@ -308,6 +349,22 @@ resource "google_bigtable_instance" "instance" {
zone = "us-central1-b"
}
instance_type = "DEVELOPMENT"

deletion_protection = false
}
`, instanceName, instanceName)
}

func testAccBigtableInstance_noAllowDestroy(instanceName string, numNodes int) string {
return fmt.Sprintf(`
resource "google_bigtable_instance" "instance" {
name = "%s"
cluster {
cluster_id = "%s"
zone = "us-central1-b"
num_nodes = %d
storage_type = "HDD"
}
}
`, instanceName, instanceName, numNodes)
}
Loading