Skip to content

Commit efde6b5

Browse files
dandyecopybara-github
authored andcommitted
v1alpha sample to search alerts
PiperOrigin-RevId: 735842055
1 parent a92b7c2 commit efde6b5

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2024 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
r"""Executable sample for getting a list of generated alerts.
18+
19+
Sample Command (run from api_samples_python dir):
20+
python3 -m detect.v1alpha.search_rules_alerts \
21+
--region=$REGION \
22+
--project_id=$PROJECT_ID \
23+
--project_instance=$PROJECT_INSTANCE \
24+
--credentials_file=$CREDENTIALS_FILE \
25+
--start_time="2024-11-11T13:37:32Z" \
26+
--start_time="2024-11-19T13:37:32Z" \
27+
--rule_status=ALL \
28+
--page_size=10
29+
30+
API reference:
31+
https://cloud.google.com/chronicle/docs/reference/rest/v1alpha/projects.locations.instances.legacy/legacySearchRulesAlerts
32+
"""
33+
import argparse
34+
import datetime
35+
import json
36+
from typing import Any, Mapping
37+
from common import chronicle_auth
38+
from common import project_id
39+
from common import project_instance
40+
from common import regions
41+
from google.auth.transport import requests
42+
43+
CHRONICLE_API_BASE_URL = "https://chronicle.googleapis.com"
44+
45+
SCOPES = [
46+
"https://www.googleapis.com/auth/cloud-platform",
47+
]
48+
49+
RULE_STATUS = (
50+
"ACTIVE",
51+
"ARCHIVED",
52+
"ALL",
53+
)
54+
55+
56+
def search_rules_alerts(
57+
http_session: requests.AuthorizedSession,
58+
proj_region: str,
59+
proj_id: str,
60+
proj_instance: str,
61+
start_time: str,
62+
end_time: str,
63+
rule_status: str | None = None,
64+
page_size: int | None = None,
65+
) -> Mapping[str, Any]:
66+
"""...
67+
68+
Args:
69+
http_session: Authorized session for HTTP requests.
70+
proj_region: region in which the target project is located
71+
proj_id: GCP project id or number which the target instance belongs to
72+
proj_instance: uuid of the instance (with dashes)
73+
start_time: A timestamp in RFC3339 UTC "Zulu" format, with nanosecond
74+
resolution and up to nine fractional digits.
75+
end_time: A timestamp in RFC3339 UTC "Zulu" format, with nanosecond
76+
resolution and up to nine fractional digits.
77+
rule_status: if provided, limit the alerts to ACTIVE | ARCHIVED | ALL
78+
page_size: if provided, limit the number of alerts returned
79+
80+
Returns:
81+
a list of detections
82+
83+
Raises:
84+
requests.exceptions.HTTPError: HTTP request resulted in an error
85+
(response.status_code >= 400).
86+
"""
87+
base_url_with_region = regions.url_always_prepend_region(
88+
CHRONICLE_API_BASE_URL, args.region
89+
)
90+
# pylint: disable-next=line-too-long
91+
instance = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}"
92+
url = f"{base_url_with_region}/v1alpha/{instance}/legacy:legacySearchRulesAlerts"
93+
params = {"timeRange.start_time": start_time, "timeRange.end_time": end_time}
94+
if rule_status:
95+
if rule_status not in RULE_STATUS:
96+
raise ValueError(
97+
f"rule_status must be one of {RULE_STATUS}, got {rule_status}"
98+
)
99+
params["ruleStatus"] = rule_status
100+
if page_size:
101+
params["maxNumAlertsToReturn"] = page_size
102+
103+
# See API reference links at top of this file, for response format.
104+
response = http_session.request("GET", url, params=params)
105+
if response.status_code >= 400:
106+
print(response.text)
107+
response.raise_for_status()
108+
return response.json()
109+
110+
111+
if __name__ == "__main__":
112+
now = datetime.datetime.now()
113+
yesterday = now - datetime.timedelta(hours=24)
114+
# Format the datetime object into the desired string
115+
start_time_string = yesterday.strftime("%Y-%m-%dT%H:%M:%SZ")
116+
117+
parser = argparse.ArgumentParser()
118+
chronicle_auth.add_argument_credentials_file(parser)
119+
regions.add_argument_region(parser)
120+
project_instance.add_argument_project_instance(parser)
121+
project_id.add_argument_project_id(parser)
122+
parser.add_argument(
123+
"--start_time",
124+
type=str,
125+
required=False,
126+
default=start_time_string,
127+
)
128+
parser.add_argument(
129+
"--end_time",
130+
type=str,
131+
required=False,
132+
default=now.strftime("%Y-%m-%dT%H:%M:%SZ"),
133+
)
134+
parser.add_argument(
135+
"--rule_status",
136+
choices=RULE_STATUS,
137+
required=False,
138+
default="ALL",
139+
)
140+
parser.add_argument(
141+
"--page_size",
142+
type=int,
143+
required=False,
144+
default=10,
145+
)
146+
args = parser.parse_args()
147+
auth_session = chronicle_auth.initialize_http_session(
148+
args.credentials_file, SCOPES
149+
)
150+
print(
151+
json.dumps(
152+
search_rules_alerts(
153+
auth_session,
154+
args.region,
155+
args.project_id,
156+
args.project_instance,
157+
args.start_time,
158+
args.end_time,
159+
args.rule_status,
160+
args.page_size,
161+
),
162+
indent=2,
163+
)
164+
)

0 commit comments

Comments
 (0)