@@ -3,6 +3,7 @@ package google
33import (
44 "context"
55 "fmt"
6+ "regexp"
67 "testing"
78
89 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -86,6 +87,125 @@ func TestAccBigtableTable_family(t *testing.T) {
8687 })
8788}
8889
90+ func TestAccBigtableTable_deletion_protection_protected (t * testing.T ) {
91+ // bigtable instance does not use the shared HTTP client, this test creates an instance
92+ skipIfVcr (t )
93+ t .Parallel ()
94+
95+ instanceName := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
96+ tableName := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
97+ family := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
98+
99+ vcrTest (t , resource.TestCase {
100+ PreCheck : func () { testAccPreCheck (t ) },
101+ Providers : testAccProviders ,
102+ CheckDestroy : testAccCheckBigtableTableDestroyProducer (t ),
103+ Steps : []resource.TestStep {
104+ // creating a table with a column family and deletion protection equals to protected
105+ {
106+ Config : testAccBigtableTable_deletion_protection (instanceName , tableName , "PROTECTED" , family ),
107+ },
108+ {
109+ ResourceName : "google_bigtable_table.table" ,
110+ ImportState : true ,
111+ ImportStateVerify : true ,
112+ },
113+ // it is not possible to delete column families in the table with deletion protection equals to protected
114+ {
115+ Config : testAccBigtableTable (instanceName , tableName ),
116+ ExpectError : regexp .MustCompile (".*deletion protection field is set to true.*" ),
117+ },
118+ // it is not possible to delete the table because of deletion protection equals to protected
119+ {
120+ Config : testAccBigtableTable_destroyTable (instanceName ),
121+ ExpectError : regexp .MustCompile (".*deletion protection field is set to true.*" ),
122+ },
123+ // changing deletion protection field to unprotected without changing the column families
124+ // checking if the table and the column family exists
125+ {
126+ Config : testAccBigtableTable_deletion_protection (instanceName , tableName , "UNPROTECTED" , family ),
127+ Check : resource .ComposeTestCheckFunc (
128+ testAccBigtableColumnFamilyExists (t , "google_bigtable_table.table" , family ),
129+ ),
130+ },
131+ {
132+ ResourceName : "google_bigtable_table.table" ,
133+ ImportState : true ,
134+ ImportStateVerify : true ,
135+ },
136+ // destroying the table is possible when deletion protection is equals to unprotected
137+ {
138+ Config : testAccBigtableTable_destroyTable (instanceName ),
139+ },
140+ {
141+ ResourceName : "google_bigtable_instance.instance" ,
142+ ImportState : true ,
143+ ImportStateVerify : true ,
144+ ImportStateVerifyIgnore : []string {"deletion_protection" , "instance_type" },
145+ },
146+ },
147+ })
148+ }
149+
150+ func TestAccBigtableTable_deletion_protection_unprotected (t * testing.T ) {
151+ // bigtable instance does not use the shared HTTP client, this test creates an instance
152+ skipIfVcr (t )
153+ t .Parallel ()
154+
155+ instanceName := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
156+ tableName := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
157+ family := fmt .Sprintf ("tf-test-%s" , randString (t , 10 ))
158+
159+ vcrTest (t , resource.TestCase {
160+ PreCheck : func () { testAccPreCheck (t ) },
161+ Providers : testAccProviders ,
162+ CheckDestroy : testAccCheckBigtableTableDestroyProducer (t ),
163+ Steps : []resource.TestStep {
164+ // creating a table with a column family and deletion protection equals to unprotected
165+ {
166+ Config : testAccBigtableTable_deletion_protection (instanceName , tableName , "UNPROTECTED" , family ),
167+ },
168+ {
169+ ResourceName : "google_bigtable_table.table" ,
170+ ImportState : true ,
171+ ImportStateVerify : true ,
172+ },
173+ // removing the column family is possible because the deletion protection field is unprotected
174+ {
175+ Config : testAccBigtableTable (instanceName , tableName ),
176+ },
177+ {
178+ ResourceName : "google_bigtable_table.table" ,
179+ ImportState : true ,
180+ ImportStateVerify : true ,
181+ },
182+ // changing the deletion protection field to protected
183+ {
184+ Config : testAccBigtableTable_deletion_protection (instanceName , tableName , "PROTECTED" , family ),
185+ },
186+ {
187+ ResourceName : "google_bigtable_table.table" ,
188+ ImportState : true ,
189+ ImportStateVerify : true ,
190+ },
191+ // it is not possible to delete the table because of deletion protection equals to protected
192+ {
193+ Config : testAccBigtableTable_destroyTable (instanceName ),
194+ ExpectError : regexp .MustCompile (".*deletion protection field is set to true.*" ),
195+ },
196+ // changing the deletion protection field to unprotected so that the sources can properly be destroyed
197+ {
198+ Config : testAccBigtableTable_deletion_protection (instanceName , tableName , "UNPROTECTED" , family ),
199+ },
200+ {
201+ ResourceName : "google_bigtable_table.table" ,
202+ ImportState : true ,
203+ ImportStateVerify : true ,
204+ },
205+ },
206+ })
207+ }
208+
89209func TestAccBigtableTable_familyMany (t * testing.T ) {
90210 // bigtable instance does not use the shared HTTP client, this test creates an instance
91211 skipIfVcr (t )
@@ -173,6 +293,36 @@ func testAccCheckBigtableTableDestroyProducer(t *testing.T) func(s *terraform.St
173293 }
174294}
175295
296+ func testAccBigtableColumnFamilyExists (t * testing.T , table_name_space , family string ) resource.TestCheckFunc {
297+ var ctx = context .Background ()
298+ return func (s * terraform.State ) error {
299+ rs , ok := s .RootModule ().Resources [table_name_space ]
300+ if ! ok {
301+ return fmt .Errorf ("Table not found: %s" , table_name_space )
302+ }
303+
304+ config := googleProviderConfig (t )
305+ c , err := config .BigTableClientFactory (config .userAgent ).NewAdminClient (config .Project , rs .Primary .Attributes ["instance_name" ])
306+ if err != nil {
307+ return fmt .Errorf ("Error starting admin client. %s" , err )
308+ }
309+
310+ defer c .Close ()
311+
312+ table , err := c .TableInfo (ctx , rs .Primary .Attributes ["name" ])
313+ if err != nil {
314+ return fmt .Errorf ("Error retrieving table. Could not find %s in %s." , rs .Primary .Attributes ["name" ], rs .Primary .Attributes ["instance_name" ])
315+ }
316+ for _ , data := range flattenColumnFamily (table .Families ) {
317+ if data ["family" ] != family {
318+ return fmt .Errorf ("Error checking column family. Could not find column family %s in %s." , family , rs .Primary .Attributes ["name" ])
319+ }
320+ }
321+
322+ return nil
323+ }
324+ }
325+
176326func testAccBigtableTable (instanceName , tableName string ) string {
177327 return fmt .Sprintf (`
178328resource "google_bigtable_instance" "instance" {
@@ -239,6 +389,32 @@ resource "google_bigtable_table" "table" {
239389` , instanceName , instanceName , tableName , family )
240390}
241391
392+ func testAccBigtableTable_deletion_protection (instanceName , tableName , deletionProtection , family string ) string {
393+ return fmt .Sprintf (`
394+ resource "google_bigtable_instance" "instance" {
395+ name = "%s"
396+
397+ cluster {
398+ cluster_id = "%s"
399+ zone = "us-central1-b"
400+ }
401+
402+ instance_type = "DEVELOPMENT"
403+ deletion_protection = false
404+ }
405+
406+ resource "google_bigtable_table" "table" {
407+ name = "%s"
408+ instance_name = google_bigtable_instance.instance.name
409+ deletion_protection = "%s"
410+
411+ column_family {
412+ family = "%s"
413+ }
414+ }
415+ ` , instanceName , instanceName , tableName , deletionProtection , family )
416+ }
417+
242418func testAccBigtableTable_familyMany (instanceName , tableName , family string ) string {
243419 return fmt .Sprintf (`
244420resource "google_bigtable_instance" "instance" {
@@ -300,3 +476,19 @@ resource "google_bigtable_table" "table" {
300476}
301477` , instanceName , instanceName , tableName , family , family , family )
302478}
479+
480+ func testAccBigtableTable_destroyTable (instanceName string ) string {
481+ return fmt .Sprintf (`
482+ resource "google_bigtable_instance" "instance" {
483+ name = "%s"
484+
485+ cluster {
486+ cluster_id = "%s"
487+ zone = "us-central1-b"
488+ }
489+
490+ instance_type = "DEVELOPMENT"
491+ deletion_protection = false
492+ }
493+ ` , instanceName , instanceName )
494+ }
0 commit comments