Skip to content

Commit

Permalink
feat: Firestore datastore mode index support (#8713) (#6424)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
Co-authored-by: Felipe Gonçalves de Castro <[email protected]>
  • Loading branch information
modular-magician and felipegc authored Oct 2, 2023
1 parent e067af4 commit 53eebe8
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .changelog/8713.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
firestore: added `api_scope` field to `google_firestore_index` resource
```
33 changes: 31 additions & 2 deletions google-beta/services/firestore/resource_firestore_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ Only one of 'order' and 'arrayConfig' can be specified. Possible values: ["ASCEN
},
},
},
"api_scope": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: verify.ValidateEnum([]string{"ANY_API", "DATASTORE_MODE_API", ""}),
Description: `The API scope at which a query is run. Default value: "ANY_API" Possible values: ["ANY_API", "DATASTORE_MODE_API"]`,
Default: "ANY_API",
},
"database": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -145,8 +153,8 @@ Only one of 'order' and 'arrayConfig' can be specified. Possible values: ["ASCEN
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: verify.ValidateEnum([]string{"COLLECTION", "COLLECTION_GROUP", ""}),
Description: `The scope at which a query is run. Default value: "COLLECTION" Possible values: ["COLLECTION", "COLLECTION_GROUP"]`,
ValidateFunc: verify.ValidateEnum([]string{"COLLECTION", "COLLECTION_GROUP", "COLLECTION_RECURSIVE", ""}),
Description: `The scope at which a query is run. Default value: "COLLECTION" Possible values: ["COLLECTION", "COLLECTION_GROUP", "COLLECTION_RECURSIVE"]`,
Default: "COLLECTION",
},
"name": {
Expand Down Expand Up @@ -192,6 +200,12 @@ func resourceFirestoreIndexCreate(d *schema.ResourceData, meta interface{}) erro
} else if v, ok := d.GetOkExists("query_scope"); !tpgresource.IsEmptyValue(reflect.ValueOf(queryScopeProp)) && (ok || !reflect.DeepEqual(v, queryScopeProp)) {
obj["queryScope"] = queryScopeProp
}
apiScopeProp, err := expandFirestoreIndexApiScope(d.Get("api_scope"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("api_scope"); !tpgresource.IsEmptyValue(reflect.ValueOf(apiScopeProp)) && (ok || !reflect.DeepEqual(v, apiScopeProp)) {
obj["apiScope"] = apiScopeProp
}
fieldsProp, err := expandFirestoreIndexFields(d.Get("fields"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -328,6 +342,9 @@ func resourceFirestoreIndexRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("query_scope", flattenFirestoreIndexQueryScope(res["queryScope"], d, config)); err != nil {
return fmt.Errorf("Error reading Index: %s", err)
}
if err := d.Set("api_scope", flattenFirestoreIndexApiScope(res["apiScope"], d, config)); err != nil {
return fmt.Errorf("Error reading Index: %s", err)
}
if err := d.Set("fields", flattenFirestoreIndexFields(res["fields"], d, config)); err != nil {
return fmt.Errorf("Error reading Index: %s", err)
}
Expand Down Expand Up @@ -426,6 +443,14 @@ func flattenFirestoreIndexQueryScope(v interface{}, d *schema.ResourceData, conf
return v
}

func flattenFirestoreIndexApiScope(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil || tpgresource.IsEmptyValue(reflect.ValueOf(v)) {
return "ANY_API"
}

return v
}

func flattenFirestoreIndexFields(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -470,6 +495,10 @@ func expandFirestoreIndexQueryScope(v interface{}, d tpgresource.TerraformResour
return v, nil
}

func expandFirestoreIndexApiScope(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandFirestoreIndexFields(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,56 @@ resource "google_firestore_index" "my-index" {
`, context)
}

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

context := map[string]interface{}{
"project_id": envvar.GetTestFirestoreProjectFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckFirestoreIndexDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccFirestoreIndex_firestoreIndexDatastoreModeExample(context),
},
{
ResourceName: "google_firestore_index.my-datastore-mode-index",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"database", "collection"},
},
},
})
}

func testAccFirestoreIndex_firestoreIndexDatastoreModeExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_firestore_index" "my-datastore-mode-index" {
project = "%{project_id}"
collection = "chatrooms"
query_scope = "COLLECTION_RECURSIVE"
api_scope = "DATASTORE_MODE_API"
fields {
field_path = "name"
order = "ASCENDING"
}
fields {
field_path = "description"
order = "DESCENDING"
}
}
`, context)
}

func testAccCheckFirestoreIndexDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
Expand Down
43 changes: 36 additions & 7 deletions website/docs/r/firestore_index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ To get more information about Index, see:

~> **Warning:** This resource creates a Firestore Index on a project that already has
a Firestore database. If you haven't already created it, you may
create a `google_firestore_database` resource with `type` set to
`"FIRESTORE_NATIVE"` and `location_id` set to your chosen location.
If you wish to use App Engine, you may instead create a
`google_app_engine_application` resource with `database_type` set to
`"CLOUD_FIRESTORE"`. Your Firestore location will be the same as
the App Engine location specified.
create a `google_firestore_database` resource and `location_id` set
to your chosen location. If you wish to use App Engine, you may
instead create a `google_app_engine_application` resource with
`database_type` set to `"CLOUD_FIRESTORE"`. Your Firestore location
will be the same as the App Engine location specified.

## Example Usage - Firestore Index Basic

Expand All @@ -58,6 +57,30 @@ resource "google_firestore_index" "my-index" {
order = "DESCENDING"
}
}
```
## Example Usage - Firestore Index Datastore Mode


```hcl
resource "google_firestore_index" "my-datastore-mode-index" {
project = "my-project-name"
collection = "chatrooms"
query_scope = "COLLECTION_RECURSIVE"
api_scope = "DATASTORE_MODE_API"
fields {
field_path = "name"
order = "ASCENDING"
}
fields {
field_path = "description"
order = "DESCENDING"
}
}
```

Expand Down Expand Up @@ -110,7 +133,13 @@ The following arguments are supported:
(Optional)
The scope at which a query is run.
Default value is `COLLECTION`.
Possible values are: `COLLECTION`, `COLLECTION_GROUP`.
Possible values are: `COLLECTION`, `COLLECTION_GROUP`, `COLLECTION_RECURSIVE`.

* `api_scope` -
(Optional)
The API scope at which a query is run.
Default value is `ANY_API`.
Possible values are: `ANY_API`, `DATASTORE_MODE_API`.

* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.
Expand Down

0 comments on commit 53eebe8

Please sign in to comment.