From 4368509cfed80cb19552d719920e7ec488e25e18 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Fri, 9 Dec 2022 19:27:59 +0000 Subject: [PATCH] [#13139] Add bucket_name argument to logging metric resource (#6887) Co-authored-by: Shuya Ma <87669292+shuyama1@users.noreply.github.com> Co-authored-by: Luca Prete resolve https://github.com/hashicorp/terraform-provider-google/issues/13139 Signed-off-by: Modular Magician --- .changelog/6887.txt | 3 + google/resource_logging_metric.go | 29 +++++++ .../resource_logging_metric_generated_test.go | 47 +++++++++++ google/resource_logging_metric_test.go | 79 ++++++++++++++++++- website/docs/r/logging_metric.html.markdown | 27 +++++++ 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 .changelog/6887.txt diff --git a/.changelog/6887.txt b/.changelog/6887.txt new file mode 100644 index 00000000000..f4443772532 --- /dev/null +++ b/.changelog/6887.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +logging: added `bucket_name` argument to `google_logging_metric` +``` diff --git a/google/resource_logging_metric.go b/google/resource_logging_metric.go index 311032843d8..247e4177447 100644 --- a/google/resource_logging_metric.go +++ b/google/resource_logging_metric.go @@ -106,6 +106,12 @@ Metric identifiers are limited to 100 characters and can include only the follow characters A-Z, a-z, 0-9, and the special characters _-.,+!*',()%/. The forward-slash character (/) denotes a hierarchy of name pieces, and it cannot be the first character of the name.`, + }, + "bucket_name": { + Type: schema.TypeString, + Optional: true, + Description: `The resource name of the Log Bucket that owns the Log Metric. Only Log Buckets in projects +are supported. The bucket has to be in the same project as the metric.`, }, "bucket_options": { Type: schema.TypeList, @@ -280,6 +286,12 @@ func resourceLoggingMetricCreate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } + bucketNameProp, err := expandLoggingMetricBucketName(d.Get("bucket_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bucket_name"); !isEmptyValue(reflect.ValueOf(bucketNameProp)) && (ok || !reflect.DeepEqual(v, bucketNameProp)) { + obj["bucketName"] = bucketNameProp + } filterProp, err := expandLoggingMetricFilter(d.Get("filter"), d, config) if err != nil { return err @@ -412,6 +424,9 @@ func resourceLoggingMetricRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("description", flattenLoggingMetricDescription(res["description"], d, config)); err != nil { return fmt.Errorf("Error reading Metric: %s", err) } + if err := d.Set("bucket_name", flattenLoggingMetricBucketName(res["bucketName"], d, config)); err != nil { + return fmt.Errorf("Error reading Metric: %s", err) + } if err := d.Set("filter", flattenLoggingMetricFilter(res["filter"], d, config)); err != nil { return fmt.Errorf("Error reading Metric: %s", err) } @@ -459,6 +474,12 @@ func resourceLoggingMetricUpdate(d *schema.ResourceData, meta interface{}) error } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { obj["description"] = descriptionProp } + bucketNameProp, err := expandLoggingMetricBucketName(d.Get("bucket_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bucket_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, bucketNameProp)) { + obj["bucketName"] = bucketNameProp + } filterProp, err := expandLoggingMetricFilter(d.Get("filter"), d, config) if err != nil { return err @@ -584,6 +605,10 @@ func flattenLoggingMetricDescription(v interface{}, d *schema.ResourceData, conf return v } +func flattenLoggingMetricBucketName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + func flattenLoggingMetricFilter(v interface{}, d *schema.ResourceData, config *Config) interface{} { return v } @@ -795,6 +820,10 @@ func expandLoggingMetricDescription(v interface{}, d TerraformResourceData, conf return v, nil } +func expandLoggingMetricBucketName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandLoggingMetricFilter(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } diff --git a/google/resource_logging_metric_generated_test.go b/google/resource_logging_metric_generated_test.go index 15aff0f1e79..d1b8179b499 100644 --- a/google/resource_logging_metric_generated_test.go +++ b/google/resource_logging_metric_generated_test.go @@ -166,6 +166,53 @@ resource "google_logging_metric" "logging_metric" { `, context) } +func TestAccLoggingMetric_loggingMetricLoggingBucketExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project": getTestProjectFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLoggingMetricDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingMetric_loggingMetricLoggingBucketExample(context), + }, + { + ResourceName: "google_logging_metric.logging_metric", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccLoggingMetric_loggingMetricLoggingBucketExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_logging_project_bucket_config" "logging_metric" { + location = "global" + project = "%{project}" + bucket_id = "_Default" +} + +resource "google_logging_metric" "logging_metric" { + name = "tf-test-my-(custom)/metric%{random_suffix}" + filter = "resource.type=gae_app AND severity>=ERROR" + bucket_name = google_logging_project_bucket_config.logging_metric.id + + metric_descriptor { + metric_kind = "DELTA" + value_type = "INT64" + unit = "1" + } +} +`, context) +} + func testAccCheckLoggingMetricDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { for name, rs := range s.RootModule().Resources { diff --git a/google/resource_logging_metric_test.go b/google/resource_logging_metric_test.go index 8281366c5c2..d42cfe153f9 100644 --- a/google/resource_logging_metric_test.go +++ b/google/resource_logging_metric_test.go @@ -62,6 +62,46 @@ func TestAccLoggingMetric_explicitBucket(t *testing.T) { }) } +func TestAccLoggingMetric_loggingBucket(t *testing.T) { + t.Parallel() + + filter := "resource.type=gae_app AND severity>=ERROR" + project_id := getTestProjectFromEnv() + suffix := randString(t, 10) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLoggingMetricDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccLoggingMetric_loggingBucketBase(suffix, filter), + }, + { + ResourceName: "google_logging_metric.logging_metric", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccLoggingMetric_loggingBucket(suffix, filter, project_id), + }, + { + ResourceName: "google_logging_metric.logging_metric", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccLoggingMetric_loggingBucketBase(suffix, filter), + }, + { + ResourceName: "google_logging_metric.logging_metric", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccLoggingMetric_descriptionUpdated(t *testing.T) { t.Parallel() @@ -128,11 +168,48 @@ resource "google_logging_metric" "logging_metric" { `, suffix, filter) } +func testAccLoggingMetric_loggingBucketBase(suffix string, filter string) string { + return fmt.Sprintf(` +resource "google_logging_metric" "logging_metric" { + name = "my-custom-metric-%s" + filter = "%s" + + metric_descriptor { + metric_kind = "DELTA" + unit = "1" + value_type = "INT64" + } +} +`, suffix, filter) +} + +func testAccLoggingMetric_loggingBucket(suffix string, filter string, project_id string) string { + return fmt.Sprintf(` +resource "google_logging_project_bucket_config" "logging_bucket" { + location = "global" + project = "%s" + bucket_id = "_Default" +} + +resource "google_logging_metric" "logging_metric" { + name = "my-custom-metric-%s" + bucket_name = google_logging_project_bucket_config.logging_bucket.id + filter = "%s" + + metric_descriptor { + metric_kind = "DELTA" + unit = "1" + value_type = "INT64" + } +} +`, project_id, suffix, filter) +} + func testAccLoggingMetric_descriptionUpdated(suffix, description string) string { return fmt.Sprintf(` resource "google_logging_metric" "logging_metric" { name = "my-custom-metric-%s" - description = "Counter for VM instances that have hostError's" + description = "Counter for VM instances that have hostError's" filter = "resource.type=gce_instance AND protoPayload.methodName=compute.instances.hostError" metric_descriptor { metric_kind = "DELTA" diff --git a/website/docs/r/logging_metric.html.markdown b/website/docs/r/logging_metric.html.markdown index a052df4bc60..5062573e47e 100644 --- a/website/docs/r/logging_metric.html.markdown +++ b/website/docs/r/logging_metric.html.markdown @@ -118,6 +118,28 @@ resource "google_logging_metric" "logging_metric" { } } ``` +## Example Usage - Logging Metric Logging Bucket + + +```hcl +resource "google_logging_project_bucket_config" "logging_metric" { + location = "global" + project = "my-project-name" + bucket_id = "_Default" +} + +resource "google_logging_metric" "logging_metric" { + name = "my-(custom)/metric" + filter = "resource.type=gae_app AND severity>=ERROR" + bucket_name = google_logging_project_bucket_config.logging_metric.id + + metric_descriptor { + metric_kind = "DELTA" + value_type = "INT64" + unit = "1" + } +} +``` ## Argument Reference @@ -204,6 +226,11 @@ The following arguments are supported: A description of this metric, which is used in documentation. The maximum length of the description is 8000 characters. +* `bucket_name` - + (Optional) + The resource name of the Log Bucket that owns the Log Metric. Only Log Buckets in projects + are supported. The bucket has to be in the same project as the metric. + * `label_extractors` - (Optional) A map from a label key string to an extractor expression which is used to extract data from a log