Skip to content

Commit 9da8119

Browse files
Add new Firestore index and database options (#13600) (#9750)
[upstream:3275fb5894398769f2cb388675df7eb4b88afdb3] Signed-off-by: Modular Magician <[email protected]>
1 parent 07f7ef0 commit 9da8119

9 files changed

+357
-7
lines changed

.changelog/13600.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
```release-note:enhancement
2+
firestore: added `density` and `multikey` fields to `google_firestore_index` resource
3+
```
4+
```release-note:enhancement
5+
firestore: added `MONGODB_COMPATIBLE_API` enum option to `apiScope` field of `google_firestore_index` resource
6+
```
7+
```release-note:enhancement
8+
firestore: added `databaseEdition` field to `google_firestore_database` resource
9+
```

google-beta/services/firestore/resource_firestore_database.go

+25
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ The expected format is
141141
ValidateFunc: verify.ValidateEnum([]string{"OPTIMISTIC", "PESSIMISTIC", "OPTIMISTIC_WITH_ENTITY_GROUPS", ""}),
142142
Description: `The concurrency control mode to use for this database. Possible values: ["OPTIMISTIC", "PESSIMISTIC", "OPTIMISTIC_WITH_ENTITY_GROUPS"]`,
143143
},
144+
"database_edition": {
145+
Type: schema.TypeString,
146+
Computed: true,
147+
Optional: true,
148+
ForceNew: true,
149+
ValidateFunc: verify.ValidateEnum([]string{"STANDARD", "ENTERPRISE", ""}),
150+
Description: `The database edition. Possible values: ["STANDARD", "ENTERPRISE"]`,
151+
},
144152
"delete_protection_state": {
145153
Type: schema.TypeString,
146154
Computed: true,
@@ -254,6 +262,12 @@ func resourceFirestoreDatabaseCreate(d *schema.ResourceData, meta interface{}) e
254262
} else if v, ok := d.GetOkExists("type"); !tpgresource.IsEmptyValue(reflect.ValueOf(typeProp)) && (ok || !reflect.DeepEqual(v, typeProp)) {
255263
obj["type"] = typeProp
256264
}
265+
databaseEditionProp, err := expandFirestoreDatabaseDatabaseEdition(d.Get("database_edition"), d, config)
266+
if err != nil {
267+
return err
268+
} else if v, ok := d.GetOkExists("database_edition"); !tpgresource.IsEmptyValue(reflect.ValueOf(databaseEditionProp)) && (ok || !reflect.DeepEqual(v, databaseEditionProp)) {
269+
obj["databaseEdition"] = databaseEditionProp
270+
}
257271
concurrencyModeProp, err := expandFirestoreDatabaseConcurrencyMode(d.Get("concurrency_mode"), d, config)
258272
if err != nil {
259273
return err
@@ -418,6 +432,9 @@ func resourceFirestoreDatabaseRead(d *schema.ResourceData, meta interface{}) err
418432
if err := d.Set("type", flattenFirestoreDatabaseType(res["type"], d, config)); err != nil {
419433
return fmt.Errorf("Error reading Database: %s", err)
420434
}
435+
if err := d.Set("database_edition", flattenFirestoreDatabaseDatabaseEdition(res["databaseEdition"], d, config)); err != nil {
436+
return fmt.Errorf("Error reading Database: %s", err)
437+
}
421438
if err := d.Set("concurrency_mode", flattenFirestoreDatabaseConcurrencyMode(res["concurrencyMode"], d, config)); err != nil {
422439
return fmt.Errorf("Error reading Database: %s", err)
423440
}
@@ -681,6 +698,10 @@ func flattenFirestoreDatabaseType(v interface{}, d *schema.ResourceData, config
681698
return v
682699
}
683700

701+
func flattenFirestoreDatabaseDatabaseEdition(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
702+
return v
703+
}
704+
684705
func flattenFirestoreDatabaseConcurrencyMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
685706
return v
686707
}
@@ -760,6 +781,10 @@ func expandFirestoreDatabaseType(v interface{}, d tpgresource.TerraformResourceD
760781
return v, nil
761782
}
762783

784+
func expandFirestoreDatabaseDatabaseEdition(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
785+
return v, nil
786+
}
787+
763788
func expandFirestoreDatabaseConcurrencyMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
764789
return v, nil
765790
}

google-beta/services/firestore/resource_firestore_database_generated_meta.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ fields:
1010
- field: 'cmek_config.kms_key_name'
1111
- field: 'concurrency_mode'
1212
- field: 'create_time'
13+
- field: 'database_edition'
1314
- field: 'delete_protection_state'
1415
- field: 'deletion_policy'
1516
provider_only: true

google-beta/services/firestore/resource_firestore_database_generated_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,45 @@ resource "google_kms_crypto_key_iam_binding" "firestore_cmek_keyuser" {
263263
`, context)
264264
}
265265

266+
func TestAccFirestoreDatabase_firestoreDatabaseEnterpriseExample(t *testing.T) {
267+
t.Parallel()
268+
269+
context := map[string]interface{}{
270+
"project_id": envvar.GetTestProjectFromEnv(),
271+
"random_suffix": acctest.RandString(t, 10),
272+
}
273+
274+
acctest.VcrTest(t, resource.TestCase{
275+
PreCheck: func() { acctest.AccTestPreCheck(t) },
276+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
277+
CheckDestroy: testAccCheckFirestoreDatabaseDestroyProducer(t),
278+
Steps: []resource.TestStep{
279+
{
280+
Config: testAccFirestoreDatabase_firestoreDatabaseEnterpriseExample(context),
281+
},
282+
{
283+
ResourceName: "google_firestore_database.enterprise-db",
284+
ImportState: true,
285+
ImportStateVerify: true,
286+
ImportStateVerifyIgnore: []string{"deletion_policy", "etag", "project"},
287+
},
288+
},
289+
})
290+
}
291+
292+
func testAccFirestoreDatabase_firestoreDatabaseEnterpriseExample(context map[string]interface{}) string {
293+
return acctest.Nprintf(`
294+
resource "google_firestore_database" "enterprise-db" {
295+
project = "%{project_id}"
296+
name = "tf-test-database-id%{random_suffix}"
297+
location_id = "nam5"
298+
type = "FIRESTORE_NATIVE"
299+
database_edition = "ENTERPRISE"
300+
deletion_policy = "DELETE"
301+
}
302+
`, context)
303+
}
304+
266305
func testAccCheckFirestoreDatabaseDestroyProducer(t *testing.T) func(s *terraform.State) error {
267306
return func(s *terraform.State) error {
268307
for name, rs := range s.RootModule().Resources {

google-beta/services/firestore/resource_firestore_index.go

+51-2
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ with the same dimension.`,
170170
Type: schema.TypeString,
171171
Optional: true,
172172
ForceNew: true,
173-
ValidateFunc: verify.ValidateEnum([]string{"ANY_API", "DATASTORE_MODE_API", ""}),
174-
Description: `The API scope at which a query is run. Default value: "ANY_API" Possible values: ["ANY_API", "DATASTORE_MODE_API"]`,
173+
ValidateFunc: verify.ValidateEnum([]string{"ANY_API", "DATASTORE_MODE_API", "MONGODB_COMPATIBLE_API", ""}),
174+
Description: `The API scope at which a query is run. Default value: "ANY_API" Possible values: ["ANY_API", "DATASTORE_MODE_API", "MONGODB_COMPATIBLE_API"]`,
175175
Default: "ANY_API",
176176
},
177177
"database": {
@@ -181,6 +181,21 @@ with the same dimension.`,
181181
Description: `The Firestore database id. Defaults to '"(default)"'.`,
182182
Default: "(default)",
183183
},
184+
"density": {
185+
Type: schema.TypeString,
186+
Computed: true,
187+
Optional: true,
188+
ForceNew: true,
189+
ValidateFunc: verify.ValidateEnum([]string{"SPARSE_ALL", "SPARSE_ANY", "DENSE", ""}),
190+
Description: `The density configuration for this index. Possible values: ["SPARSE_ALL", "SPARSE_ANY", "DENSE"]`,
191+
},
192+
"multikey": {
193+
Type: schema.TypeBool,
194+
Optional: true,
195+
ForceNew: true,
196+
Description: `Optional. Whether the index is multikey. By default, the index is not multikey. For non-multikey indexes, none of the paths in the index definition reach or traverse an array, except via an explicit array index. For multikey indexes, at most one of the paths in the index definition reach or traverse an array, except via an explicit array index. Violations will result in errors. Note this field only applies to indexes with MONGODB_COMPATIBLE_API ApiScope.`,
197+
Default: false,
198+
},
184199
"query_scope": {
185200
Type: schema.TypeString,
186201
Optional: true,
@@ -238,6 +253,18 @@ func resourceFirestoreIndexCreate(d *schema.ResourceData, meta interface{}) erro
238253
} else if v, ok := d.GetOkExists("api_scope"); !tpgresource.IsEmptyValue(reflect.ValueOf(apiScopeProp)) && (ok || !reflect.DeepEqual(v, apiScopeProp)) {
239254
obj["apiScope"] = apiScopeProp
240255
}
256+
densityProp, err := expandFirestoreIndexDensity(d.Get("density"), d, config)
257+
if err != nil {
258+
return err
259+
} else if v, ok := d.GetOkExists("density"); !tpgresource.IsEmptyValue(reflect.ValueOf(densityProp)) && (ok || !reflect.DeepEqual(v, densityProp)) {
260+
obj["density"] = densityProp
261+
}
262+
multikeyProp, err := expandFirestoreIndexMultikey(d.Get("multikey"), d, config)
263+
if err != nil {
264+
return err
265+
} else if v, ok := d.GetOkExists("multikey"); !tpgresource.IsEmptyValue(reflect.ValueOf(multikeyProp)) && (ok || !reflect.DeepEqual(v, multikeyProp)) {
266+
obj["multikey"] = multikeyProp
267+
}
241268
fieldsProp, err := expandFirestoreIndexFields(d.Get("fields"), d, config)
242269
if err != nil {
243270
return err
@@ -383,6 +410,12 @@ func resourceFirestoreIndexRead(d *schema.ResourceData, meta interface{}) error
383410
if err := d.Set("api_scope", flattenFirestoreIndexApiScope(res["apiScope"], d, config)); err != nil {
384411
return fmt.Errorf("Error reading Index: %s", err)
385412
}
413+
if err := d.Set("density", flattenFirestoreIndexDensity(res["density"], d, config)); err != nil {
414+
return fmt.Errorf("Error reading Index: %s", err)
415+
}
416+
if err := d.Set("multikey", flattenFirestoreIndexMultikey(res["multikey"], d, config)); err != nil {
417+
return fmt.Errorf("Error reading Index: %s", err)
418+
}
386419
if err := d.Set("fields", flattenFirestoreIndexFields(res["fields"], d, config)); err != nil {
387420
return fmt.Errorf("Error reading Index: %s", err)
388421
}
@@ -493,6 +526,14 @@ func flattenFirestoreIndexApiScope(v interface{}, d *schema.ResourceData, config
493526
return v
494527
}
495528

529+
func flattenFirestoreIndexDensity(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
530+
return v
531+
}
532+
533+
func flattenFirestoreIndexMultikey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
534+
return v
535+
}
536+
496537
func flattenFirestoreIndexFields(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
497538
if v == nil {
498539
return v
@@ -582,6 +623,14 @@ func expandFirestoreIndexApiScope(v interface{}, d tpgresource.TerraformResource
582623
return v, nil
583624
}
584625

626+
func expandFirestoreIndexDensity(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
627+
return v, nil
628+
}
629+
630+
func expandFirestoreIndexMultikey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
631+
return v, nil
632+
}
633+
585634
func expandFirestoreIndexFields(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
586635
l := v.([]interface{})
587636
req := make([]interface{}, 0, len(l))

google-beta/services/firestore/resource_firestore_index_generated_meta.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ fields:
88
- field: 'api_scope'
99
- field: 'collection'
1010
- field: 'database'
11+
- field: 'density'
1112
- field: 'fields.array_config'
1213
- field: 'fields.field_path'
1314
- field: 'fields.order'
1415
- field: 'fields.vector_config.dimension'
1516
- field: 'fields.vector_config.flat'
17+
- field: 'multikey'
1618
- field: 'name'
1719
- field: 'query_scope'

google-beta/services/firestore/resource_firestore_index_generated_test.go

+127-2
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,13 @@ resource "google_firestore_database" "database" {
130130
}
131131
132132
resource "google_firestore_index" "my-index" {
133-
project = "%{project_id}"
133+
project = "%{project_id}"
134134
database = google_firestore_database.database.name
135135
collection = "atestcollection"
136136
137137
query_scope = "COLLECTION_RECURSIVE"
138-
api_scope = "DATASTORE_MODE_API"
138+
api_scope = "DATASTORE_MODE_API"
139+
density = "SPARSE_ALL"
139140
140141
fields {
141142
field_path = "name"
@@ -265,6 +266,130 @@ resource "google_firestore_index" "my-index" {
265266
`, context)
266267
}
267268

269+
func TestAccFirestoreIndex_firestoreIndexMongodbCompatibleScopeExample(t *testing.T) {
270+
t.Parallel()
271+
272+
context := map[string]interface{}{
273+
"project_id": envvar.GetTestProjectFromEnv(),
274+
"random_suffix": acctest.RandString(t, 10),
275+
}
276+
277+
acctest.VcrTest(t, resource.TestCase{
278+
PreCheck: func() { acctest.AccTestPreCheck(t) },
279+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
280+
CheckDestroy: testAccCheckFirestoreIndexDestroyProducer(t),
281+
Steps: []resource.TestStep{
282+
{
283+
Config: testAccFirestoreIndex_firestoreIndexMongodbCompatibleScopeExample(context),
284+
},
285+
{
286+
ResourceName: "google_firestore_index.my-index",
287+
ImportState: true,
288+
ImportStateVerify: true,
289+
ImportStateVerifyIgnore: []string{"collection", "database"},
290+
},
291+
},
292+
})
293+
}
294+
295+
func testAccFirestoreIndex_firestoreIndexMongodbCompatibleScopeExample(context map[string]interface{}) string {
296+
return acctest.Nprintf(`
297+
resource "google_firestore_database" "database" {
298+
project = "%{project_id}"
299+
name = "tf-test-database-id-mongodb-compatible%{random_suffix}"
300+
location_id = "nam5"
301+
type = "FIRESTORE_NATIVE"
302+
database_edition = "ENTERPRISE"
303+
304+
delete_protection_state = "DELETE_PROTECTION_DISABLED"
305+
deletion_policy = "DELETE"
306+
}
307+
308+
resource "google_firestore_index" "my-index" {
309+
project = "%{project_id}"
310+
database = google_firestore_database.database.name
311+
collection = "atestcollection"
312+
313+
api_scope = "MONGODB_COMPATIBLE_API"
314+
query_scope = "COLLECTION_GROUP"
315+
multikey = true
316+
density = "DENSE"
317+
318+
fields {
319+
field_path = "name"
320+
order = "ASCENDING"
321+
}
322+
323+
fields {
324+
field_path = "description"
325+
order = "DESCENDING"
326+
}
327+
}
328+
`, context)
329+
}
330+
331+
func TestAccFirestoreIndex_firestoreIndexSparseAnyExample(t *testing.T) {
332+
t.Parallel()
333+
334+
context := map[string]interface{}{
335+
"project_id": envvar.GetTestProjectFromEnv(),
336+
"random_suffix": acctest.RandString(t, 10),
337+
}
338+
339+
acctest.VcrTest(t, resource.TestCase{
340+
PreCheck: func() { acctest.AccTestPreCheck(t) },
341+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
342+
CheckDestroy: testAccCheckFirestoreIndexDestroyProducer(t),
343+
Steps: []resource.TestStep{
344+
{
345+
Config: testAccFirestoreIndex_firestoreIndexSparseAnyExample(context),
346+
},
347+
{
348+
ResourceName: "google_firestore_index.my-index",
349+
ImportState: true,
350+
ImportStateVerify: true,
351+
ImportStateVerifyIgnore: []string{"collection", "database"},
352+
},
353+
},
354+
})
355+
}
356+
357+
func testAccFirestoreIndex_firestoreIndexSparseAnyExample(context map[string]interface{}) string {
358+
return acctest.Nprintf(`
359+
resource "google_firestore_database" "database" {
360+
project = "%{project_id}"
361+
name = "tf-test-database-id-sparse-any%{random_suffix}"
362+
location_id = "nam5"
363+
type = "FIRESTORE_NATIVE"
364+
database_edition = "ENTERPRISE"
365+
366+
delete_protection_state = "DELETE_PROTECTION_DISABLED"
367+
deletion_policy = "DELETE"
368+
}
369+
370+
resource "google_firestore_index" "my-index" {
371+
project = "%{project_id}"
372+
database = google_firestore_database.database.name
373+
collection = "atestcollection"
374+
375+
api_scope = "MONGODB_COMPATIBLE_API"
376+
query_scope = "COLLECTION_GROUP"
377+
multikey = true
378+
density = "SPARSE_ANY"
379+
380+
fields {
381+
field_path = "name"
382+
order = "ASCENDING"
383+
}
384+
385+
fields {
386+
field_path = "description"
387+
order = "DESCENDING"
388+
}
389+
}
390+
`, context)
391+
}
392+
268393
func testAccCheckFirestoreIndexDestroyProducer(t *testing.T) func(s *terraform.State) error {
269394
return func(s *terraform.State) error {
270395
for name, rs := range s.RootModule().Resources {

0 commit comments

Comments
 (0)