Skip to content

Add index_configs field to log bucket configuration #16437

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

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
6 changes: 6 additions & 0 deletions .changelog/9109.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```release-note:enhancement
logging: added `index_configs` field to `logging_bucket_config` resource
```
```release-note:enhancement
logging: added `index_configs` field to `logging_project_bucket_config` resource
```
73 changes: 73 additions & 0 deletions google/services/logging/resource_logging_bucket_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ See [Enabling CMEK for Logging Buckets](https://cloud.google.com/logging/docs/ro
},
},
},
"index_configs": {
Type: schema.TypeSet,
MaxItems: 20,
Optional: true,
Description: `A list of indexed fields and related configuration data.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"field_path": {
Type: schema.TypeString,
Required: true,
Description: `The LogEntry field path to index.`,
},
"type": {
Type: schema.TypeString,
Required: true,
Description: `The type of data in this index
Note that some paths are automatically indexed, and other paths are not eligible for indexing. See [indexing documentation]( https://cloud.google.com/logging/docs/view/advanced-queries#indexed-fields) for details.
For example: jsonPayload.request.status`,
},
},
},
},
}

type loggingBucketConfigIDFunc func(d *schema.ResourceData, config *transport_tpg.Config) (string, error)
Expand Down Expand Up @@ -209,6 +231,7 @@ func resourceLoggingBucketConfigCreate(d *schema.ResourceData, meta interface{},
obj["description"] = d.Get("description")
obj["retentionDays"] = d.Get("retention_days")
obj["cmekSettings"] = expandCmekSettings(d.Get("cmek_settings"))
obj["indexConfigs"] = expandIndexConfigs(d.Get("index_configs"))

url, err := tpgresource.ReplaceVars(d, config, "{{LoggingBasePath}}projects/{{project}}/locations/{{location}}/buckets?bucketId={{bucket_id}}")
if err != nil {
Expand Down Expand Up @@ -293,6 +316,10 @@ func resourceLoggingBucketConfigRead(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error setting cmek_settings: %s", err)
}

if err := d.Set("index_configs", flattenIndexConfigs(res["indexConfigs"])); err != nil {
return fmt.Errorf("Error setting index_configs: %s", err)
}

return nil
}

Expand All @@ -313,6 +340,7 @@ func resourceLoggingBucketConfigUpdate(d *schema.ResourceData, meta interface{})
obj["retentionDays"] = d.Get("retention_days")
obj["description"] = d.Get("description")
obj["cmekSettings"] = expandCmekSettings(d.Get("cmek_settings"))
obj["indexConfigs"] = expandIndexConfigs(d.Get("index_configs"))

updateMask := []string{}
if d.HasChange("retention_days") {
Expand All @@ -324,6 +352,10 @@ func resourceLoggingBucketConfigUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("cmek_settings") {
updateMask = append(updateMask, "cmekSettings")
}
if d.HasChange("index_configs") {
updateMask = append(updateMask, "indexConfigs")
}

url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
Expand Down Expand Up @@ -411,3 +443,44 @@ func flattenCmekSettings(cmekSettings interface{}) []map[string]interface{} {

return []map[string]interface{}{data}
}

func expandIndexConfigs(maybeIndexConfigs interface{}) []map[string]interface{} {
if maybeIndexConfigs == nil {
return nil
}

indexConfigs := maybeIndexConfigs.(*schema.Set).List()
transformedIndexConfigs := make([]map[string]interface{}, 0, len(indexConfigs))

for _, entry := range indexConfigs {
original := entry.(map[string]interface{})

transformed := map[string]interface{}{
"fieldPath": original["field_path"],
"type": original["type"],
}
transformedIndexConfigs = append(transformedIndexConfigs, transformed)
}
return transformedIndexConfigs
}

func flattenIndexConfigs(maybeIndexConfigs interface{}) []map[string]interface{} {
if maybeIndexConfigs == nil {
return nil
}

indexConfigs := maybeIndexConfigs.([]interface{})
flattenedIndexConfigs := make([]map[string]interface{}, 0, len(indexConfigs))

for _, entry := range indexConfigs {
indexConfig := entry.(map[string]interface{})
if len(indexConfig) < 1 {
continue
}
flattenedIndexConfigs = append(flattenedIndexConfigs, map[string]interface{}{
"field_path": indexConfig["fieldPath"],
"type": indexConfig["type"],
})
}
return flattenedIndexConfigs
}
126 changes: 126 additions & 0 deletions google/services/logging/resource_logging_bucket_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,129 @@ func getLoggingBucketConfigs(context map[string]interface{}) map[string]string {
}

}

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

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

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccLoggingBucketConfigOrganization_indexConfigs(context, "INDEX_TYPE_STRING", "INDEX_TYPE_STRING"),
},
{
ResourceName: "google_logging_organization_bucket_config.basic",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"organization"},
},
{
Config: testAccLoggingBucketConfigOrganization_indexConfigs(context, "INDEX_TYPE_STRING", "INDEX_TYPE_INTEGER"),
},
{
ResourceName: "google_logging_organization_bucket_config.basic",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"organization"},
},
},
})
}

func testAccLoggingBucketConfigOrganization_indexConfigs(context map[string]interface{}, urlIndexType, statusIndexType string) string {
return fmt.Sprintf(acctest.Nprintf(`
data "google_organization" "default" {
organization = "%{org_id}"
}

resource "google_logging_organization_bucket_config" "basic" {
organization = data.google_organization.default.organization
location = "global"
retention_days = 30
description = "retention test 30 days"
bucket_id = "_Default"

index_configs {
field_path = "jsonPayload.request.url"
type = "%s"
}

index_configs {
field_path = "jsonPayload.response.status"
type = "%s"
}
}
`, context), urlIndexType, statusIndexType)
}

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

context := map[string]interface{}{
"project_name": "tf-test-" + acctest.RandString(t, 10),
"org_id": envvar.GetTestOrgFromEnv(t),
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
"bucket_id": "tf-test-bucket-" + acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccLoggingBucketConfigProject_indexConfigs(context, "INDEX_TYPE_STRING", "INDEX_TYPE_STRING"),
},
{
ResourceName: "google_logging_project_bucket_config.basic",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"project"},
},
{
Config: testAccLoggingBucketConfigProject_indexConfigs(context, "INDEX_TYPE_STRING", "INDEX_TYPE_INTEGER"),
},
{
ResourceName: "google_logging_project_bucket_config.basic",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"project"},
},
},
})
}

func testAccLoggingBucketConfigProject_indexConfigs(context map[string]interface{}, urlIndexType, statusIndexType string) string {
return fmt.Sprintf(acctest.Nprintf(`

resource "google_project" "default" {
project_id = "%{project_name}"
name = "%{project_name}"
org_id = "%{org_id}"
billing_account = "%{billing_account}"
}

resource "google_logging_project_bucket_config" "basic" {
project = google_project.default.name
location = "us-east1"
retention_days = 30
description = "retention test 30 days"
bucket_id = "%{bucket_id}"

index_configs {
field_path = "jsonPayload.request.url"
type = "%s"
}

index_configs {
field_path = "jsonPayload.response.status"
type = "%s"
}
}
`, context), urlIndexType, statusIndexType)
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ See [Enabling CMEK for Logging Buckets](https://cloud.google.com/logging/docs/ro
},
},
},
"index_configs": {
Type: schema.TypeSet,
MaxItems: 20,
Optional: true,
Description: `A list of indexed fields and related configuration data.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"field_path": {
Type: schema.TypeString,
Required: true,
Description: `The LogEntry field path to index.`,
},
"type": {
Type: schema.TypeString,
Required: true,
Description: `The type of data in this index
Note that some paths are automatically indexed, and other paths are not eligible for indexing. See [indexing documentation]( https://cloud.google.com/logging/docs/view/advanced-queries#indexed-fields) for details.
For example: jsonPayload.request.status`,
},
},
},
},
}

func projectBucketConfigID(d *schema.ResourceData, config *transport_tpg.Config) (string, error) {
Expand Down Expand Up @@ -194,6 +216,7 @@ func resourceLoggingProjectBucketConfigCreate(d *schema.ResourceData, meta inter
obj["retentionDays"] = d.Get("retention_days")
obj["analyticsEnabled"] = d.Get("enable_analytics")
obj["cmekSettings"] = expandCmekSettings(d.Get("cmek_settings"))
obj["indexConfigs"] = expandIndexConfigs(d.Get("index_configs"))

url, err := tpgresource.ReplaceVars(d, config, "{{LoggingBasePath}}projects/{{project}}/locations/{{location}}/buckets?bucketId={{bucket_id}}")
if err != nil {
Expand Down Expand Up @@ -284,6 +307,10 @@ func resourceLoggingProjectBucketConfigRead(d *schema.ResourceData, meta interfa
return fmt.Errorf("Error setting cmek_settings: %s", err)
}

if err := d.Set("index_configs", flattenIndexConfigs(res["indexConfigs"])); err != nil {
return fmt.Errorf("Error setting index_configs: %s", err)
}

return nil
}

Expand Down Expand Up @@ -327,6 +354,8 @@ func resourceLoggingProjectBucketConfigUpdate(d *schema.ResourceData, meta inter
obj["retentionDays"] = d.Get("retention_days")
obj["description"] = d.Get("description")
obj["cmekSettings"] = expandCmekSettings(d.Get("cmek_settings"))
obj["indexConfigs"] = expandIndexConfigs(d.Get("index_configs"))

updateMask := []string{}
if d.HasChange("retention_days") {
updateMask = append(updateMask, "retentionDays")
Expand All @@ -337,6 +366,10 @@ func resourceLoggingProjectBucketConfigUpdate(d *schema.ResourceData, meta inter
if d.HasChange("cmek_settings") {
updateMask = append(updateMask, "cmekSettings")
}
if d.HasChange("index_configs") {
updateMask = append(updateMask, "indexConfigs")
}

url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,30 @@ Manages a billing account level logging bucket config. For more information see

```hcl
data "google_billing_account" "default" {
billing_account = "00AA00-000AAA-00AA0A"
billing_account = "00AA00-000AAA-00AA0A"
}

resource "google_logging_billing_account_bucket_config" "basic" {
billing_account = data.google_billing_account.default.billing_account
location = "global"
retention_days = 30
bucket_id = "_Default"
billing_account = data.google_billing_account.default.billing_account
location = "global"
retention_days = 30
bucket_id = "_Default"
}
```

Create logging bucket with index configs

```hcl
resource "google_logging_billing_account_bucket_config" "example-billing-account-bucket-index-configs" {
folder = data.google_billing_account.default.billing_account
location = "global"
retention_days = 30
bucket_id = "_Default"

index_configs = {
file_path = "jsonPayload.request.status"
type = "INDEX_TYPE_STRING"
}
}
```

Expand All @@ -41,6 +57,15 @@ The following arguments are supported:

* `retention_days` - (Optional) Logs will be retained by default for this amount of time, after which they will automatically be deleted. The minimum retention period is 1 day. If this value is set to zero at bucket creation time, the default time of 30 days will be used. Bucket retention can not be increased on buckets outside of projects.

* `index_configs` - (Optional) A list of indexed fields and related configuration data. Structure is [documented below](#nested_index_configs).

<a name="nested_index_configs"></a>The `index_configs` block supports:

* `field_path` - The LogEntry field path to index.
Note that some paths are automatically indexed, and other paths are not eligible for indexing. See [indexing documentation]( https://cloud.google.com/logging/docs/view/advanced-queries#indexed-fields) for details.

* `type` - The type of data in this index. Allowed types include `INDEX_TYPE_UNSPECIFIED`, `INDEX_TYPE_STRING` and `INDEX_TYPE_INTEGER`.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
Expand Down
Loading