-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
v1alpha samples for: Create Ref List, Rule, UDM Event
PiperOrigin-RevId: 599597439
- Loading branch information
1 parent
ec94275
commit dd41593
Showing
6 changed files
with
544 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
"""Support for Project ID for v1alpha Chronicle API calls.""" | ||
import argparse | ||
|
||
|
||
def add_argument_project_id(parser: argparse.ArgumentParser): | ||
"""Adds a shared command-line argument to all the sample modules.""" | ||
parser.add_argument( | ||
"-p", "--project_id", type=str, required=True, | ||
help="Your BYOP, project id", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
"""Support for Project INSTANCE for v1alpha Chronicle API calls.""" | ||
|
||
import argparse | ||
|
||
|
||
def add_argument_project_instance(parser: argparse.ArgumentParser): | ||
"""Adds a shared command-line argument to all the sample modules.""" | ||
parser.add_argument( | ||
"-i", | ||
"--project_instance", | ||
type=str, | ||
required=True, | ||
help="Customer ID for Chronicle instance", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
r"""Executable and reusable sample for creating a detection rule. | ||
HTTP request | ||
POST https://chronicle.googleapis.com/v1alpha/{parent}/rules | ||
python3 -m detect.v1alpha.create_rule \ | ||
--project_instance $project_instance \ | ||
--project_id $PROJECT_ID \ | ||
--rule_file=./ip_in_abuseipdb_blocklist.yaral | ||
Requires the following IAM permission on the parent resource: | ||
chronicle.rules.create | ||
API reference: | ||
https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.rules/create | ||
https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.rules#Rule | ||
""" | ||
|
||
import argparse | ||
import json | ||
from typing import Any, Mapping | ||
|
||
from google.auth.transport import requests | ||
|
||
from common import chronicle_auth | ||
from common import project_id | ||
from common import project_instance | ||
from common import regions | ||
|
||
SCOPES = [ | ||
"https://www.googleapis.com/auth/cloud-platform", | ||
] | ||
|
||
|
||
def create_rule( | ||
http_session: requests.AuthorizedSession, | ||
proj_id: str, | ||
proj_instance: str, | ||
proj_region: str, | ||
rule_file_path: str, | ||
) -> Mapping[str, Any]: | ||
"""Creates a new detection rule to find matches in logs. | ||
Args: | ||
http_session: Authorized session for HTTP requests. | ||
proj_id: GCP project id or number to which the target instance belongs. | ||
proj_instance: | ||
uuid of the instance whose feeds are being listed (with dashes). | ||
proj_region: region in which the target project is located. | ||
rule_file_path: Content of the new detection rule, used to evaluate logs. | ||
Returns: | ||
New detection rule. | ||
Raises: | ||
requests.exceptions.HTTPError: HTTP request resulted in an error | ||
(response.status_code >= 400). | ||
""" | ||
# pylint: disable-next=line-too-long | ||
parent = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}" | ||
url = f"https://{proj_region}-chronicle.googleapis.com/v1alpha/{parent}/rules" | ||
body = { | ||
"text": rule_file_path.read(), | ||
} | ||
response = http_session.request("POST", url, json=body) | ||
# Expected server response: | ||
# { | ||
# # pylint: disable=line-too-long | ||
# "name": "projects/{project}/locations/{location}/instances/{instance}/rules/{rule_id}", | ||
# "revisionId": "v_{10_digits}_{9_digits}", | ||
# "displayName": "{rule_name}", | ||
# "text": "{rule_content}", | ||
# "author": str, | ||
# "severity": { | ||
# "displayName": str | ||
# }, | ||
# "metadata": { | ||
# "{key_1}": "{value_1}", | ||
# ... | ||
# }, | ||
# "createTime": "yyyy-MM-ddThh:mm:ss.ssssssZ", | ||
# "revisionCreateTime": "yyyy-MM-ddThh:mm:ss.ssssssZ" | ||
# "compilationState": "SUCCEEDED", | ||
# "type": "{{SINGLE,MULTI}_EVENT,RULE_TYPE_UNSPECIFIED}", | ||
# "referenceLists": [str], | ||
# "allowedRunFrequencies": [ | ||
# str, | ||
# ... | ||
# ], | ||
# "etag": str | ||
# } | ||
if response.status_code >= 400: | ||
print(response.text) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser() | ||
# common | ||
chronicle_auth.add_argument_credentials_file(parser) | ||
project_instance.add_argument_project_instance(parser) | ||
project_id.add_argument_project_id(parser) | ||
regions.add_argument_region(parser) | ||
# local | ||
parser.add_argument( | ||
"-f", | ||
"--rule_file", | ||
type=argparse.FileType("r"), | ||
required=True, | ||
# File example: python3 create_rule.py -f <path> | ||
# STDIN example: cat rule.txt | python3 create_rule.py -f - | ||
help="path of a file with the desired rule's content, or - for STDIN", | ||
) | ||
args = parser.parse_args() | ||
|
||
auth_session = chronicle_auth.initialize_http_session( | ||
args.credentials_file, | ||
SCOPES | ||
) | ||
new_rule = create_rule(auth_session, | ||
args.project_id, | ||
args.project_instance, | ||
args.region, | ||
args.rule_file) | ||
print(json.dumps(new_rule, indent=2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
"""Executable and reusable sample for retrieving a list of rules.""" | ||
|
||
import argparse | ||
import json | ||
from typing import Mapping, Any | ||
|
||
from google.auth.transport import requests | ||
|
||
from common import chronicle_auth | ||
from common import project_id | ||
from common import project_instance | ||
from common import regions | ||
|
||
SCOPES = [ | ||
"https://www.googleapis.com/auth/cloud-platform", | ||
] | ||
|
||
|
||
def list_rules( | ||
http_session: requests.AuthorizedSession, | ||
proj_id: str, | ||
proj_instance: str, | ||
proj_region: str, | ||
) -> Mapping[str, Any]: | ||
"""Gets a list of rules. | ||
Args: | ||
http_session: Authorized session for HTTP requests. | ||
proj_id: GCP project id or number to which the target instance belongs. | ||
proj_instance: | ||
uuid of the instance whose feeds are being listed (with dashes). | ||
proj_region: region in which the target project is located. | ||
Returns: | ||
Array containing information about rules. | ||
Raises: | ||
requests.exceptions.HTTPError: HTTP request resulted in an error | ||
(response.status_code >= 400). | ||
""" | ||
# pylint: disable-next=line-too-long | ||
parent = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}" | ||
url = f"https://{proj_region}-chronicle.googleapis.com/v1alpha/{parent}/rules" | ||
|
||
response = http_session.request("GET", url) | ||
if response.status_code >= 400: | ||
print(response.text) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser() | ||
chronicle_auth.add_argument_credentials_file(parser) | ||
project_instance.add_argument_project_instance(parser) | ||
project_id.add_argument_project_id(parser) | ||
regions.add_argument_region(parser) | ||
args = parser.parse_args() | ||
session = chronicle_auth.initialize_http_session( | ||
args.credentials_file, | ||
SCOPES | ||
) | ||
rules = list_rules( | ||
session, | ||
args.project_id, | ||
args.project_instance, | ||
args.region | ||
) | ||
print(json.dumps(rules, indent=2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# pylint: disable=line-too-long | ||
r"""Executable and reusable v1alpha API sample for getting a UDM event by ID. | ||
API reference: | ||
https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.events/get | ||
""" | ||
# pylint: enable=line-too-long | ||
|
||
import argparse | ||
import json | ||
|
||
from google.auth.transport import requests | ||
|
||
from common import chronicle_auth | ||
from common import project_id | ||
from common import project_instance | ||
from common import regions | ||
|
||
SCOPES = [ | ||
"https://www.googleapis.com/auth/cloud-platform", | ||
] | ||
|
||
|
||
def get_udm_event( | ||
http_session: requests.AuthorizedSession, | ||
proj_id: str, | ||
proj_instance: str, | ||
proj_region: str, | ||
event_id: str): | ||
"""Get a UDM event by metadata.id. | ||
A Unified Data Model (UDM) event is a structured representation of an event | ||
regardless of the log source. | ||
Args: | ||
http_session: Authorized session for HTTP requests. | ||
proj_id: GCP project id or number to which the target instance belongs. | ||
proj_instance: | ||
uuid of the instance whose feeds are being listed (with dashes). | ||
proj_region: region in which the target project is located. | ||
event_id: URL-encoded Base64 for the UDM Event ID. | ||
Returns: | ||
dict/json respresentation of UDM Event | ||
Raises: | ||
requests.exceptions.HTTPError: HTTP request resulted in an error | ||
(response.status_code >= 400). | ||
Requires the following IAM permission on the parent resource: | ||
chronicle.events.get | ||
https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.events/get | ||
""" | ||
# pylint: disable=line-too-long | ||
parent = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}" | ||
url = f"https://{proj_region}-chronicle.googleapis.com/v1alpha/{parent}/events/{event_id}" | ||
# pylint: enable=line-too-long | ||
|
||
response = http_session.request("GET", url) | ||
if response.status_code >= 400: | ||
print(response.text) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser() | ||
# common | ||
chronicle_auth.add_argument_credentials_file(parser) | ||
project_instance.add_argument_project_instance(parser) | ||
project_id.add_argument_project_id(parser) | ||
regions.add_argument_region(parser) | ||
# local | ||
parser.add_argument( | ||
"--event_id", | ||
type=str, | ||
required=True, | ||
help=("URL-encoded Base64 ID of the Event"), | ||
) | ||
args = parser.parse_args() | ||
|
||
auth_session = chronicle_auth.initialize_http_session( | ||
args.credentials_file, | ||
SCOPES, | ||
) | ||
event = get_udm_event( | ||
auth_session, | ||
args.project_id, | ||
args.project_instance, | ||
args.region, | ||
args.event_id) | ||
print(json.dumps(event, indent=2)) |
Oops, something went wrong.