From d64cd90b50c3b4d350cf288159e4c9c0837ed76c Mon Sep 17 00:00:00 2001 From: The Magician Date: Fri, 17 Jan 2025 14:05:07 -0800 Subject: [PATCH] Add google_chronicle_retrohunt resource to chronicle (#12776) (#20962) [upstream:f26eca6e692fe0f20a2aa596c0d8efca8d224831] Signed-off-by: Modular Magician --- .changelog/12776.txt | 3 + .../services/chronicle/chronicle_operation.go | 74 +++++++ .../docs/r/chronicle_retrohunt.html.markdown | 189 ++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 .changelog/12776.txt create mode 100644 google/services/chronicle/chronicle_operation.go create mode 100644 website/docs/r/chronicle_retrohunt.html.markdown diff --git a/.changelog/12776.txt b/.changelog/12776.txt new file mode 100644 index 00000000000..5cd9f68a1ce --- /dev/null +++ b/.changelog/12776.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +`google_chronicle_retrohunt` +``` \ No newline at end of file diff --git a/google/services/chronicle/chronicle_operation.go b/google/services/chronicle/chronicle_operation.go new file mode 100644 index 00000000000..4838982f5a5 --- /dev/null +++ b/google/services/chronicle/chronicle_operation.go @@ -0,0 +1,74 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package chronicle + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +type ChronicleOperationWaiter struct { + Config *transport_tpg.Config + UserAgent string + Project string + tpgresource.CommonOperationWaiter +} + +func (w *ChronicleOperationWaiter) QueryOp() (interface{}, error) { + if w == nil { + return nil, fmt.Errorf("Cannot query operation, it's unset or nil.") + } + + region := tpgresource.GetRegionFromRegionalSelfLink(w.CommonOperationWaiter.Op.Name) + + // Returns the proper get. + url := fmt.Sprintf("https://%s-chronicle.googleapis.com/v1beta/%s", region, w.CommonOperationWaiter.Op.Name) + + return transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: w.Config, + Method: "GET", + Project: w.Project, + RawURL: url, + UserAgent: w.UserAgent, + }) +} + +func createChronicleWaiter(config *transport_tpg.Config, op map[string]interface{}, project, activity, userAgent string) (*ChronicleOperationWaiter, error) { + w := &ChronicleOperationWaiter{ + Config: config, + UserAgent: userAgent, + Project: project, + } + if err := w.CommonOperationWaiter.SetOp(op); err != nil { + return nil, err + } + return w, nil +} + +func ChronicleOperationWaitTimeWithResponse(config *transport_tpg.Config, op map[string]interface{}, response *map[string]interface{}, project, activity, userAgent string, timeout time.Duration) error { + w, err := createChronicleWaiter(config, op, project, activity, userAgent) + if err != nil { + return err + } + if err := tpgresource.OperationWait(w, activity, timeout, config.PollInterval); err != nil { + return err + } + return json.Unmarshal([]byte(w.CommonOperationWaiter.Op.Response), response) +} + +func ChronicleOperationWaitTime(config *transport_tpg.Config, op map[string]interface{}, project, activity, userAgent string, timeout time.Duration) error { + if val, ok := op["name"]; !ok || val == "" { + // This was a synchronous call - there is no operation to wait for. + return nil + } + w, err := createChronicleWaiter(config, op, project, activity, userAgent) + if err != nil { + // If w is nil, the op was synchronous. + return err + } + return tpgresource.OperationWait(w, activity, timeout, config.PollInterval) +} diff --git a/website/docs/r/chronicle_retrohunt.html.markdown b/website/docs/r/chronicle_retrohunt.html.markdown new file mode 100644 index 00000000000..a749f1e6912 --- /dev/null +++ b/website/docs/r/chronicle_retrohunt.html.markdown @@ -0,0 +1,189 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Chronicle" +description: |- + Retrohunt is an execution of a Rule over a time range in the past. +--- + +# google_chronicle_retrohunt + +Retrohunt is an execution of a Rule over a time range in the past. + + +To get more information about Retrohunt, see: + +* [API documentation](https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.rules.retrohunts) +* How-to Guides + * [Google SecOps Guides](https://cloud.google.com/chronicle/docs/secops/secops-overview) + +## Example Usage - Chronicle Retrohunt Basic + + +```hcl +resource "google_chronicle_rule" "my-rule" { + provider = "google-beta" + location = "us" + instance = "00000000-0000-0000-0000-000000000000" + deletion_policy = "FORCE" + text = <<-EOT + rule test_rule { meta: events: $userid = $e.principal.user.userid match: $userid over 10m condition: $e } + EOT +} + +resource "google_chronicle_retrohunt" "example" { + provider = "google-beta" + location = "us" + instance = "00000000-0000-0000-0000-000000000000" + rule = element(split("/", resource.google_chronicle_rule.my-rule.name), length(split("/", resource.google_chronicle_rule.my-rule.name)) - 1) + process_interval { + start_time = "2025-01-01T00:00:00Z" + end_time = "2025-01-01T12:00:00Z" + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `process_interval` - + (Required) + Represents a time interval, encoded as a Timestamp start (inclusive) and a + Timestamp end (exclusive). + The start must be less than or equal to the end. + When the start equals the end, the interval is empty (matches no time). + When both start and end are unspecified, the interval matches any time. + Structure is [documented below](#nested_process_interval). + +* `location` - + (Required) + The location of the resource. This is the geographical region where the Chronicle instance resides, such as "us" or "europe-west2". + +* `instance` - + (Required) + The unique identifier for the Chronicle instance, which is the same as the customer ID. + +* `rule` - + (Required) + The Rule ID of the rule. + + +The `process_interval` block supports: + +* `start_time` - + (Required) + Inclusive start of the interval. + +* `end_time` - + (Required) + Exclusive end of the interval. + +- - - + + +* `retrohunt` - + (Optional) + The retrohunt ID of the Retrohunt. A retrohunt is an execution of a Rule over a time range in the past. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/instances/{{instance}}/rules/{{rule}}/retrohunts/{{retrohunt}}` + +* `progress_percentage` - + Output only. Percent progress of the retrohunt towards completion, from 0.00 to 100.00. + +* `name` - + The resource name of the retrohunt. + Retrohunt is the child of a rule revision. {rule} in the format below is + structured as {rule_id@revision_id}. + Format: + projects/{project}/locations/{location}/instances/{instance}/rules/{rule}/retrohunts/{retrohunt} + +* `execution_interval` - + Represents a time interval, encoded as a Timestamp start (inclusive) and a + Timestamp end (exclusive). + The start must be less than or equal to the end. + When the start equals the end, the interval is empty (matches no time). + When both start and end are unspecified, the interval matches any time. + Structure is [documented below](#nested_execution_interval). + +* `state` - + Output only. The state of the retrohunt. + Possible values: + RUNNING + DONE + CANCELLED + FAILED + + +The `execution_interval` block contains: + +* `end_time` - + (Optional) + Optional. Exclusive end of the interval. + If specified, a Timestamp matching this interval will have to be before the + end. + +* `start_time` - + (Optional) + Optional. Inclusive start of the interval. + If specified, a Timestamp matching this interval will have to be the same + or after the start. + +## Timeouts + +This resource provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +Retrohunt can be imported using any of these accepted formats: + +* `projects/{{project}}/locations/{{location}}/instances/{{instance}}/rules/{{rule}}/retrohunts/{{retrohunt}}` +* `{{project}}/{{location}}/{{instance}}/{{rule}}/{{retrohunt}}` +* `{{location}}/{{instance}}/{{rule}}/{{retrohunt}}` + + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Retrohunt using one of the formats above. For example: + +```tf +import { + id = "projects/{{project}}/locations/{{location}}/instances/{{instance}}/rules/{{rule}}/retrohunts/{{retrohunt}}" + to = google_chronicle_retrohunt.default +} +``` + +When using the [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import), Retrohunt can be imported using one of the formats above. For example: + +``` +$ terraform import google_chronicle_retrohunt.default projects/{{project}}/locations/{{location}}/instances/{{instance}}/rules/{{rule}}/retrohunts/{{retrohunt}} +$ terraform import google_chronicle_retrohunt.default {{project}}/{{location}}/{{instance}}/{{rule}}/{{retrohunt}} +$ terraform import google_chronicle_retrohunt.default {{location}}/{{instance}}/{{rule}}/{{retrohunt}} +``` + +## User Project Overrides + +This resource supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override).