main
py 352 lines 12.6 KB
Raw
1 from typing import List
2 from typing import Tuple
3
4 from fastapi import HTTPException
5 from loguru import logger
6
7 from app.connectors.graylog.schema.collector import ConfiguredInput
8 from app.connectors.graylog.schema.collector import ConfiguredInputsResponse
9 from app.connectors.graylog.schema.collector import GraylogIndexItem
10 from app.connectors.graylog.schema.collector import GraylogIndicesResponse
11 from app.connectors.graylog.schema.collector import GraylogInputsResponse
12 from app.connectors.graylog.schema.collector import RunningInput
13 from app.connectors.graylog.schema.collector import RunningInputsResponse
14 from app.connectors.graylog.schema.management import UrlWhitelistEntryResponse
15 from app.connectors.graylog.utils.universal import send_get_request
16
17 # async def get_indices_full() -> GraylogIndicesResponse:
18 # """Get indices from Graylog.
19
20 # Returns:
21 # GraylogIndicesResponse: The response object containing the collected indices.
22
23 # Raises:
24 # HTTPException: If there is an error collecting the indices.
25 # """
26 # logger.info("Getting indices from Graylog")
27 # indices_collected = await send_get_request(endpoint="/api/system/indexer/indices")
28 # if indices_collected["success"]:
29 # try:
30 # indices_data = indices_collected["data"]["all"]["indices"]
31 # except KeyError:
32 # raise HTTPException(status_code=500, detail="Failed to collect indices key")
33
34 # # Convert the dictionary to a list of GraylogIndexItem
35 # indices_list = [GraylogIndexItem(index_name=name, index_info=info) for name, info in indices_data.items()]
36
37 # return GraylogIndicesResponse(
38 # indices=indices_list,
39 # success=True,
40 # message="Indices collected successfully",
41 # )
42 # else:
43 # return GraylogIndicesResponse(
44 # indices=[],
45 # success=False,
46 # message="Failed to collect indices",
47 # )
48
49
50 async def get_indices_full() -> GraylogIndicesResponse:
51 """Get indices from Graylog.
52
53 Returns:
54 GraylogIndicesResponse: The response object containing the collected indices.
55
56 Raises:
57 HTTPException: If there is an error collecting the indices.
58 """
59 logger.info("Getting indices from Graylog")
60 indices_collected = await send_get_request(endpoint="/api/system/indexer/indices")
61 if indices_collected["success"]:
62 try:
63 indices_data = indices_collected["data"]["all"]["indices"]
64 except KeyError:
65 raise HTTPException(status_code=500, detail="Failed to collect indices key")
66
67 # Check if indices_data is a dictionary or a list and process accordingly
68 if isinstance(indices_data, dict):
69 indices_list = [GraylogIndexItem(index_name=name, index_info=info) for name, info in indices_data.items()]
70 elif isinstance(indices_data, list):
71 indices_list = [GraylogIndexItem(index_name=index["index_name"], index_info=index) for index in indices_data]
72 else:
73 raise HTTPException(status_code=500, detail="Unexpected format for indices data")
74
75 return GraylogIndicesResponse(
76 indices=indices_list,
77 success=True,
78 message="Indices collected successfully",
79 )
80 else:
81 return GraylogIndicesResponse(
82 indices=[],
83 success=False,
84 message="Failed to collect indices",
85 )
86
87
88 async def fetch_configured_inputs() -> Tuple[bool, List[ConfiguredInput]]:
89 """
90 Fetches the configured inputs from the Graylog server.
91
92 Returns:
93 A tuple containing a boolean indicating the success of the request and a list of ConfiguredInput objects.
94 """
95 configured_inputs_collected = await send_get_request(endpoint="/api/system/inputs")
96 success = configured_inputs_collected.get("success", False)
97
98 if success:
99 return True, [ConfiguredInput(**input_data) for input_data in configured_inputs_collected["data"]["inputs"]]
100 else:
101 logger.error("Failed to fetch configured inputs")
102 return False, []
103
104
105 async def fetch_running_inputs() -> Tuple[bool, List[RunningInput]]:
106 """
107 Fetches the running inputs from the Graylog API.
108
109 Returns:
110 A tuple containing a boolean indicating the success of the request and a list of RunningInput objects.
111 """
112 running_inputs_collected = await send_get_request(
113 endpoint="/api/system/inputstates",
114 )
115 success = running_inputs_collected.get("success", False)
116
117 if success:
118 return True, [RunningInput(**input_data) for input_data in running_inputs_collected["data"]["states"]]
119 else:
120 logger.error("Failed to fetch running inputs")
121 return False, []
122
123
124 async def get_inputs() -> GraylogInputsResponse:
125 """Get inputs from Graylog.
126
127 This function retrieves both configured and running inputs from Graylog.
128 It first fetches the configured inputs using the `fetch_configured_inputs` function,
129 and then fetches the running inputs using the `fetch_running_inputs` function.
130 If both fetch operations are successful, it returns a `GraylogInputsResponse` object
131 containing the configured and running inputs, along with a success message.
132 If either of the fetch operations fails, it returns a `GraylogInputsResponse` object
133 with empty input lists and a failure message.
134
135 Returns:
136 GraylogInputsResponse: An object containing the configured and running inputs,
137 along with a success or failure message.
138 """
139 logger.info("Getting inputs from Graylog")
140
141 config_success, configured_inputs_list = await fetch_configured_inputs()
142 run_success, running_inputs_list = await fetch_running_inputs()
143
144 if config_success and run_success:
145 logger.info("Successfully fetched both configured and running inputs")
146 return GraylogInputsResponse(
147 configured_inputs=configured_inputs_list,
148 running_inputs=running_inputs_list,
149 success=True,
150 message="Successfully retrieved inputs",
151 )
152 else:
153 logger.error("Failed to fetch one or both types of inputs")
154 return GraylogInputsResponse(
155 configured_inputs=[],
156 running_inputs=[],
157 success=False,
158 message="Failed to collect inputs",
159 )
160
161
162 async def get_inputs_running() -> RunningInputsResponse:
163 """Get running inputs from Graylog.
164
165 Returns:
166 RunningInputsResponse: The response object containing the running inputs, success status, and message.
167 """
168 logger.info("Getting running inputs from Graylog")
169 run_success, running_inputs_list = await fetch_running_inputs()
170 if run_success:
171 return RunningInputsResponse(
172 running_inputs=running_inputs_list,
173 success=True,
174 message="Successfully retrieved running inputs",
175 )
176
177
178 async def get_inputs_configured() -> ConfiguredInputsResponse:
179 """Get configured inputs from Graylog.
180
181 Returns:
182 ConfiguredInputsResponse: The response object containing the configured inputs, success status, and message.
183 """
184 logger.info("Getting configured inputs from Graylog")
185 config_success, configured_inputs_list = await fetch_configured_inputs()
186 if config_success:
187 return ConfiguredInputsResponse(
188 configured_inputs=configured_inputs_list,
189 success=True,
190 message="Successfully retrieved configured inputs",
191 )
192
193
194 async def get_index_names() -> List[str]:
195 """
196 Gets the names of all the indices in Graylog.
197
198 Returns:
199 List[str]: A list of all the index names.
200 """
201 logger.info("Getting index names from Graylog")
202
203 indices_collected = await get_indices_full()
204
205 if indices_collected.success:
206 # Access the index_name attribute directly
207 return [index.index_name for index in indices_collected.indices]
208 else:
209 return []
210
211
212 async def get_input_ids() -> List[str]:
213 """
214 Gets the IDs of all the inputs in Graylog.
215
216 Returns:
217 List[str]: A list of all the input IDs.
218 """
219 logger.info("Getting input IDs from Graylog")
220
221 success, inputs_collected = await fetch_configured_inputs()
222
223 if success:
224 # Access the input_id attribute directly
225 return [input.id for input in inputs_collected]
226 else:
227 return []
228
229
230 async def get_url_whitelist_entries() -> UrlWhitelistEntryResponse:
231 """
232 Retrieves the URL whitelist entries from Graylog.
233
234 Returns:
235 UrlWhitelistEntryResponse: The response object containing the URL whitelist entries.
236 """
237 logger.info("Getting URL whitelist entries from Graylog")
238 # Graylog 7.0 renamed urlwhitelist -> urlallowlist. Try the 7.x path first and
239 # fall back to the 6.x path so both server versions are supported. GET is
240 # idempotent, so the fallback is safe.
241 try:
242 response = await send_get_request(endpoint="/api/system/urlallowlist")
243 except HTTPException:
244 logger.info("urlallowlist endpoint unavailable, falling back to legacy urlwhitelist (Graylog < 7.0)")
245 response = await send_get_request(endpoint="/api/system/urlwhitelist")
246 logger.info(f"URL whitelist entries response: {response}")
247 if response["success"]:
248 try:
249 url_whitelist_entries = response["data"]
250 except KeyError:
251 raise HTTPException(
252 status_code=500,
253 detail="Failed to collect URL whitelist entries",
254 )
255 return UrlWhitelistEntryResponse(
256 url_whitelist_entries=url_whitelist_entries,
257 success=True,
258 message="URL whitelist entries collected successfully",
259 )
260 else:
261 return UrlWhitelistEntryResponse(
262 url_whitelist_entries=[],
263 success=False,
264 message="Failed to collect URL whitelist entries",
265 )
266
267
268 async def get_stream_id_by_stream_name(stream_name: str) -> str:
269 """Get stream ID from Graylog by stream name.
270
271 Args:
272 stream_name (str): The name of the stream.
273
274 Returns:
275 str: The ID of the stream.
276
277 Raises:
278 HTTPException: If there is an error collecting the stream ID.
279 """
280 logger.info(f"Getting stream ID from Graylog for stream {stream_name}")
281 streams_collected = await send_get_request(endpoint="/api/streams")
282 try:
283 if streams_collected["success"]:
284 for stream in streams_collected["data"]["streams"]:
285 if stream["title"] == stream_name:
286 return stream["id"]
287 else:
288 return ""
289 except KeyError as e:
290 logger.error(f"Failed to collect stream ID key: {e}")
291 raise HTTPException(
292 status_code=500,
293 detail=f"Failed to collect stream ID key: {e}",
294 )
295
296
297 async def get_input_id_by_input_name(input_name: str) -> str:
298 """Get input ID from Graylog by input name.
299
300 Args:
301 input_name (str): The name of the input.
302
303 Returns:
304 str: The ID of the input.
305
306 Raises:
307 HTTPException: If there is an error collecting the input ID.
308 """
309 logger.info(f"Getting input ID from Graylog for input {input_name}")
310 inputs_collected = await send_get_request(endpoint="/api/system/inputs")
311 try:
312 if inputs_collected["success"]:
313 for input in inputs_collected["data"]["inputs"]:
314 if input["title"] == input_name:
315 return input["id"]
316 else:
317 return ""
318 except KeyError as e:
319 logger.error(f"Failed to collect input ID key: {e}")
320 raise HTTPException(
321 status_code=500,
322 detail=f"Failed to collect input ID key: {e}",
323 )
324
325
326 async def get_content_pack_id_by_content_pack_name(content_pack_name: str) -> str:
327 """Get content pack ID from Graylog by content pack name.
328
329 Args:
330 content_pack_name (str): The name of the content pack.
331
332 Returns:
333 str: The ID of the content pack.
334
335 Raises:
336 HTTPException: If there is an error collecting the content pack ID.
337 """
338 logger.info(f"Getting content pack ID from Graylog for content pack {content_pack_name}")
339 content_packs_collected = await send_get_request(endpoint="/api/system/content_packs")
340 try:
341 if content_packs_collected["success"]:
342 for content_pack in content_packs_collected["data"]["content_packs"]:
343 if content_pack["name"] == content_pack_name:
344 return content_pack["id"]
345 else:
346 return ""
347 except KeyError as e:
348 logger.error(f"Failed to collect content pack ID key: {e}")
349 raise HTTPException(
350 status_code=500,
351 detail=f"Failed to collect content pack ID key: {e}",
352 )