main
py 798 lines 28.7 KB
Raw
1 import asyncio
2 import json
3 from dataclasses import dataclass
4 from datetime import datetime
5 from datetime import timedelta
6 from typing import Any
7 from typing import Dict
8 from typing import Optional
9
10 import requests
11 from loguru import logger
12
13 from app.connectors.utils import get_connector_info_from_db
14 from app.db.db_session import AsyncSessionLocal
15 from app.db.db_session import get_db_session
16
17 # =============================================================================
18 # Token Cache Implementation
19 # =============================================================================
20
21
22 @dataclass
23 class CachedToken:
24 """Cached authentication token with expiration"""
25
26 token: str
27 expires_at: datetime
28 connector_url: str
29
30
31 class WazuhTokenCache:
32 """
33 Thread-safe cache for Wazuh Manager authentication tokens.
34
35 Caches tokens per connector name to support multiple Wazuh Manager instances.
36 Default TTL is 10 minutes (Wazuh tokens typically expire after 15-30 minutes).
37 """
38
39 def __init__(self, default_ttl_minutes: int = 10):
40 self._cache: Dict[str, CachedToken] = {}
41 self._lock = asyncio.Lock()
42 self._default_ttl = timedelta(minutes=default_ttl_minutes)
43
44 async def get(self, connector_name: str) -> Optional[Dict[str, str]]:
45 """
46 Get cached token headers if valid.
47
48 Returns:
49 Dict with Authorization header if token is valid, None otherwise
50 """
51 async with self._lock:
52 if connector_name not in self._cache:
53 return None
54
55 cached = self._cache[connector_name]
56
57 # Check if token is expired (with 30 second buffer)
58 if datetime.utcnow() >= (cached.expires_at - timedelta(seconds=30)):
59 logger.debug(f"Cached token for {connector_name} has expired")
60 del self._cache[connector_name]
61 return None
62
63 logger.debug(f"Using cached token for {connector_name}")
64 return {"Authorization": f"Bearer {cached.token}"}
65
66 async def set(self, connector_name: str, token: str, connector_url: str, ttl_minutes: Optional[int] = None):
67 """Cache a new token"""
68 async with self._lock:
69 ttl = timedelta(minutes=ttl_minutes) if ttl_minutes else self._default_ttl
70 expires_at = datetime.utcnow() + ttl
71
72 self._cache[connector_name] = CachedToken(
73 token=token,
74 expires_at=expires_at,
75 connector_url=connector_url,
76 )
77 logger.debug(f"Cached token for {connector_name}, expires at {expires_at.isoformat()}")
78
79 async def invalidate(self, connector_name: str):
80 """Remove cached token for a connector"""
81 async with self._lock:
82 if connector_name in self._cache:
83 del self._cache[connector_name]
84 logger.debug(f"Invalidated cached token for {connector_name}")
85
86 async def clear(self):
87 """Clear all cached tokens"""
88 async with self._lock:
89 self._cache.clear()
90 logger.debug("Cleared all cached Wazuh tokens")
91
92
93 # Global token cache instance
94 _token_cache = WazuhTokenCache(default_ttl_minutes=10)
95
96
97 # =============================================================================
98 # Public Cache Management Functions
99 # =============================================================================
100
101
102 async def invalidate_wazuh_token_cache(connector_name: str = "Wazuh-Manager"):
103 """
104 Invalidate cached token for a connector.
105
106 Call this when credentials are updated or if you receive auth errors.
107 """
108 await _token_cache.invalidate(connector_name)
109
110
111 # ============================================================================
112 # Existing Wazuh Manager Utility Functions
113 # ============================================================================
114
115
116 async def clear_all_wazuh_token_caches():
117 """Clear all cached Wazuh tokens"""
118 await _token_cache.clear()
119
120
121 async def verify_wazuh_manager_credentials(
122 attributes: Dict[str, Any],
123 ) -> Dict[str, Any]:
124 """
125 Verifies the connection to Wazuh manager service.
126
127 Returns:
128 dict: A dictionary containing 'connectionSuccessful' status and 'authToken' if the connection is successful.
129 """
130 logger.info(
131 f"Verifying the wazuh-manager connection to {attributes['connector_url']}",
132 )
133
134 try:
135 wazuh_auth_token = requests.get(
136 f"{attributes['connector_url']}/security/user/authenticate",
137 auth=(
138 attributes["connector_username"],
139 attributes["connector_password"],
140 ),
141 verify=False,
142 )
143
144 if wazuh_auth_token.status_code == 200:
145 logger.debug("Wazuh Authentication Token successful")
146 return {
147 "connectionSuccessful": True,
148 "message": "Wazuh Manager authentication successful",
149 }
150 else:
151 logger.error(
152 f"Connection to {attributes['connector_url']} failed with error: {wazuh_auth_token.text}",
153 )
154
155 return {
156 "connectionSuccessful": False,
157 "message": f"Connection to {attributes['connector_url']} failed",
158 }
159 except Exception as e:
160 logger.error(
161 f"Connection to {attributes['connector_url']} failed with error: {e}",
162 )
163
164 return {
165 "connectionSuccessful": False,
166 "message": f"Connection to {attributes['connector_url']} failed with error.",
167 }
168
169
170 async def verify_wazuh_manager_connection(connector_name: str) -> str:
171 """
172 Returns the authentication token for the Wazuh manager service.
173
174 Returns:
175 str: Authentication token for the Wazuh manager service.
176 """
177 logger.info("Getting Wazuh Manager authentication token")
178 async with get_db_session() as session: # This will correctly enter the context manager
179 attributes = await get_connector_info_from_db(connector_name, session)
180 if attributes is None:
181 logger.error("No Wazuh Manager connector found in the database")
182 return None
183 return await verify_wazuh_manager_credentials(attributes)
184
185
186 # async def create_wazuh_manager_client(connector_name: str) -> str:
187 # """
188 # Returns the authentication token for the Wazuh manager service.
189
190 # Returns:
191 # str: Authentication token for the Wazuh manager service.
192 # """
193 # logger.info("Getting Wazuh Manager authentication token")
194 # # attributes = get_connector_info_from_db(connector_name)
195 # async with AsyncSessionLocal() as session:
196 # attributes = await get_connector_info_from_db(connector_name, session)
197 # if attributes is None:
198 # logger.error("No Wazuh Manager connector found in the database")
199 # return None
200 # logger.info(
201 # f"Verifying the wazuh-manager connection to {attributes['connector_url']}",
202 # )
203 # try:
204 # wazuh_auth_token = requests.get(
205 # f"{attributes['connector_url']}/security/user/authenticate",
206 # auth=(
207 # attributes["connector_username"],
208 # attributes["connector_password"],
209 # ),
210 # verify=False,
211 # )
212
213 # if wazuh_auth_token.status_code == 200:
214 # logger.debug("Wazuh Authentication Token successful")
215 # wazuh_auth_token = wazuh_auth_token.json()
216 # wazuh_auth_token = wazuh_auth_token["data"]["token"]
217
218 # return {"Authorization": f"Bearer {wazuh_auth_token}"}
219 # else:
220 # logger.error(
221 # f"Connection to {attributes['connector_url']} failed with error: {wazuh_auth_token.text}",
222 # )
223
224 # return None
225 # except Exception as e:
226 # logger.error(
227 # f"Connection to {attributes['connector_url']} failed with error: {e}",
228 # )
229
230 # return None
231
232
233 async def create_wazuh_manager_client(connector_name: str) -> Optional[Dict[str, str]]:
234 """
235 Returns the authentication token headers for the Wazuh manager service.
236
237 Uses cached token if available and valid, otherwise fetches a new one.
238
239 Returns:
240 Dict with Authorization header, or None if authentication fails
241 """
242 # Check cache first
243 cached_headers = await _token_cache.get(connector_name)
244 if cached_headers is not None:
245 return cached_headers
246
247 logger.info(f"Fetching new Wazuh Manager authentication token for {connector_name}")
248
249 async with AsyncSessionLocal() as session:
250 attributes = await get_connector_info_from_db(connector_name, session)
251
252 if attributes is None:
253 logger.error("No Wazuh Manager connector found in the database")
254 return None
255
256 logger.info(
257 f"Authenticating to wazuh-manager at {attributes['connector_url']}",
258 )
259
260 try:
261 response = requests.get(
262 f"{attributes['connector_url']}/security/user/authenticate",
263 auth=(
264 attributes["connector_username"],
265 attributes["connector_password"],
266 ),
267 verify=False,
268 )
269
270 if response.status_code == 200:
271 logger.debug("Wazuh Authentication Token successful")
272 token_data = response.json()
273 token = token_data["data"]["token"]
274
275 # Cache the token
276 await _token_cache.set(
277 connector_name=connector_name,
278 token=token,
279 connector_url=attributes["connector_url"],
280 )
281
282 return {"Authorization": f"Bearer {token}"}
283 else:
284 logger.error(
285 f"Connection to {attributes['connector_url']} failed with error: {response.text}",
286 )
287 return None
288
289 except Exception as e:
290 logger.error(
291 f"Connection to {attributes['connector_url']} failed with error: {e}",
292 )
293 return None
294
295
296 # async def send_get_request(
297 # endpoint: str,
298 # params: Optional[Dict[str, Any]] = None,
299 # connector_name: str = "Wazuh-Manager",
300 # ) -> Dict[str, Any]:
301 # """
302 # Sends a GET request to the Wazuh Manager service.
303
304 # Args:
305 # endpoint (str): The endpoint to send the GET request to.
306 # params (Optional[Dict[str, Any]], optional): The parameters to send with the GET request. Defaults to None.
307 # connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
308
309 # Returns:
310 # Dict[str, Any]: The response from the GET request.
311 # """
312 # logger.info(f"Sending GET request to {endpoint}")
313 # wazuh_manager_client = await create_wazuh_manager_client(connector_name)
314 # # attributes = get_connector_info_from_db(connector_name)
315 # async with AsyncSessionLocal() as session:
316 # attributes = await get_connector_info_from_db(connector_name, session)
317
318 # if attributes is None:
319 # logger.error("No Wazuh Manager connector found in the database")
320 # return None
321 # try:
322 # # Check if raw response is requested - support both old and new ways
323 # # Old way: params == {"raw": True} (exact match for backward compatibility)
324 # # New way: params contains "raw": True (for requests with multiple parameters)
325 # is_raw_request = (params == {"raw": True}) or (params and params.get("raw", False))
326
327 # if is_raw_request:
328 # response = requests.get(
329 # f"{attributes['connector_url']}{endpoint}",
330 # headers=wazuh_manager_client,
331 # params=params,
332 # verify=False,
333 # )
334 # response.raise_for_status()
335 # return {
336 # "data": response.text,
337 # "success": True,
338 # "message": "Successfully retrieved data",
339 # }
340 # response = requests.get(
341 # f"{attributes['connector_url']}{endpoint}",
342 # headers=wazuh_manager_client,
343 # params=params,
344 # verify=False,
345 # )
346 # response.raise_for_status()
347 # return {
348 # "data": response.json(),
349 # "success": True,
350 # "message": "Successfully retrieved data",
351 # }
352 # except Exception as e:
353 # logger.error(f"Failed to send GET request to {endpoint} with error: {e}")
354 # return {
355 # "success": False,
356 # "message": f"Failed to send GET request to {endpoint} with error: {e}",
357 # }
358
359
360 async def send_get_request(
361 endpoint: str,
362 params: Optional[Dict[str, Any]] = None,
363 connector_name: str = "Wazuh-Manager",
364 ) -> Dict[str, Any]:
365 """
366 Sends a GET request to the Wazuh Manager service.
367
368 Args:
369 endpoint (str): The endpoint to send the GET request to.
370 params (Optional[Dict[str, Any]], optional): The parameters to send with the GET request. Defaults to None.
371 connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
372
373 Returns:
374 Dict[str, Any]: The response from the GET request.
375 """
376 logger.info(f"Sending GET request to {endpoint}")
377 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
378
379 if wazuh_manager_client is None:
380 logger.error("Failed to get Wazuh Manager client")
381 return {
382 "success": False,
383 "message": "Failed to authenticate with Wazuh Manager",
384 }
385
386 async with AsyncSessionLocal() as session:
387 attributes = await get_connector_info_from_db(connector_name, session)
388
389 if attributes is None:
390 logger.error("No Wazuh Manager connector found in the database")
391 return {
392 "success": False,
393 "message": "No Wazuh Manager connector found in the database",
394 }
395
396 try:
397 is_raw_request = (params == {"raw": True}) or (params and params.get("raw", False))
398
399 if is_raw_request:
400 response = requests.get(
401 f"{attributes['connector_url']}{endpoint}",
402 headers=wazuh_manager_client,
403 params=params,
404 verify=False,
405 )
406 response.raise_for_status()
407 return {
408 "data": response.text,
409 "success": True,
410 "message": "Successfully retrieved data",
411 }
412
413 response = requests.get(
414 f"{attributes['connector_url']}{endpoint}",
415 headers=wazuh_manager_client,
416 params=params,
417 verify=False,
418 )
419
420 # Handle 401 Unauthorized - token may have expired on server side
421 if response.status_code == 401:
422 logger.warning("Received 401 Unauthorized, invalidating cached token and retrying")
423 await _token_cache.invalidate(connector_name)
424
425 # Retry with fresh token
426 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
427 if wazuh_manager_client is None:
428 return {
429 "success": False,
430 "message": "Failed to re-authenticate with Wazuh Manager",
431 }
432
433 response = requests.get(
434 f"{attributes['connector_url']}{endpoint}",
435 headers=wazuh_manager_client,
436 params=params,
437 verify=False,
438 )
439
440 response.raise_for_status()
441 return {
442 "data": response.json(),
443 "success": True,
444 "message": "Successfully retrieved data",
445 }
446 except Exception as e:
447 logger.error(f"Failed to send GET request to {endpoint} with error: {e}")
448 return {
449 "success": False,
450 "message": f"Failed to send GET request to {endpoint} with error: {e}",
451 }
452
453
454 async def send_post_request(
455 endpoint: str,
456 data: Dict[str, Any],
457 connector_name: str = "Wazuh-Manager",
458 ) -> Dict[str, Any]:
459 """
460 Sends a POST request to the Wazuh Manager service.
461
462 Args:
463 endpoint (str): The endpoint to send the POST request to.
464 data (Dict[str, Any]): The data to send with the POST request.
465 connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
466
467 Returns:
468 Dict[str, Any]: The response from the POST request.
469 """
470 logger.info(f"Sending POST request to {endpoint}")
471 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
472 async with AsyncSessionLocal() as session:
473 attributes = await get_connector_info_from_db(connector_name, session)
474 if attributes is None:
475 logger.error("No Wazuh Manager connector found in the database")
476 return None
477 try:
478 response = requests.post(
479 f"{attributes['connector_url']}{endpoint}",
480 headers=wazuh_manager_client,
481 json=data,
482 verify=False,
483 )
484 response.raise_for_status()
485 return {
486 "data": response.json(),
487 "success": True,
488 "message": "Successfully retrieved data",
489 }
490 except Exception as e:
491 logger.error(f"Failed to send POST request to {endpoint} with error: {e}")
492 return {
493 "success": False,
494 "message": f"Failed to send POST request to {endpoint} with error: {e}",
495 }
496
497
498 # async def send_put_request(
499 # endpoint: str,
500 # data: Optional[Dict[str, Any]],
501 # params: Optional[Dict[str, str]] = None,
502 # xml_data: Optional[bool] = False,
503 # binary_data: Optional[bool] = False,
504 # connector_name: str = "Wazuh-Manager",
505 # ) -> Dict[str, Any]:
506 # """
507 # Sends a PUT request to the Wazuh Manager service.
508
509 # Args:
510 # endpoint (str): The endpoint to send the PUT request to.
511 # data (Dict[str, Any]): The data to send with the PUT request.
512 # params (Optional[Dict[str, str]], optional): The parameters to send with the PUT request. Defaults to None.
513 # xml_data (Optional[bool], optional): Whether or not the data is XML. Defaults to False.
514 # connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
515
516 # Returns:
517 # Dict[str, Any]: The response from the PUT request.
518 # """
519 # logger.info(f"Sending PUT request to {endpoint}")
520 # wazuh_manager_client = await create_wazuh_manager_client(connector_name)
521 # async with AsyncSessionLocal() as session:
522 # attributes = await get_connector_info_from_db(connector_name, session)
523 # if attributes is None:
524 # logger.error("No Wazuh Manager connector found in the database")
525 # return None
526 # # Add the default `Content-Type` header to the request
527 # wazuh_manager_client["Content-Type"] = "application/json"
528 # # Add the `Content-Type` header to the request if the data is XML
529 # if xml_data:
530 # wazuh_manager_client["Content-Type"] = "application/xml"
531 # if binary_data:
532 # wazuh_manager_client["Content-Type"] = "application/octet-stream"
533 # try:
534 # logger.debug(f"Sending PUT request to {endpoint} with data: {data}")
535 # response = requests.put(
536 # f"{attributes['connector_url']}{endpoint}",
537 # headers=wazuh_manager_client,
538 # params=params,
539 # data=data,
540 # verify=False,
541 # )
542 # response.raise_for_status()
543 # return {
544 # "data": response.json(),
545 # "success": True,
546 # "message": "Successfully retrieved data",
547 # }
548 # except Exception as e:
549 # logger.error(f"Failed to send PUT request to {endpoint} with error: {e}")
550 # return {
551 # "success": False,
552 # "message": f"Failed to send PUT request to {endpoint} with error: {e}",
553 # }
554
555
556 async def send_put_request(
557 endpoint: str,
558 data: Optional[Dict[str, Any]],
559 params: Optional[Dict[str, str]] = None,
560 xml_data: Optional[bool] = False,
561 binary_data: Optional[bool] = False,
562 connector_name: str = "Wazuh-Manager",
563 debug: bool = False,
564 ) -> Dict[str, Any]:
565 """
566 Sends a PUT request to the Wazuh Manager service.
567
568 Args:
569 endpoint (str): The endpoint to send the PUT request to.
570 data (Dict[str, Any]): The data to send with the PUT request.
571 params (Optional[Dict[str, str]], optional): The parameters to send with the PUT request. Defaults to None.
572 xml_data (Optional[bool], optional): Whether or not the data is XML. Defaults to False.
573 binary_data (Optional[bool], optional): Whether or not the data is binary. Defaults to False.
574 connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
575 debug (bool, optional): Whether to enable detailed debug logging. Defaults to False.
576
577 Returns:
578 Dict[str, Any]: The response from the PUT request.
579 """
580 logger.info(f"Sending PUT request to {endpoint}")
581 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
582 async with AsyncSessionLocal() as session:
583 attributes = await get_connector_info_from_db(connector_name, session)
584
585 if attributes is None:
586 logger.error("No Wazuh Manager connector found in the database")
587 return None
588
589 # Add the default `Content-Type` header to the request
590 wazuh_manager_client["Content-Type"] = "application/json"
591
592 # Add the `Content-Type` header to the request if the data is XML
593 if xml_data:
594 wazuh_manager_client["Content-Type"] = "application/xml"
595 if binary_data:
596 wazuh_manager_client["Content-Type"] = "application/octet-stream"
597
598 # Enhanced debugging
599 if debug:
600 logger.debug(f"Request URL: {attributes['connector_url']}{endpoint}")
601 logger.debug(f"Request headers: {wazuh_manager_client}")
602 logger.debug(f"Request params: {params}")
603 logger.debug(f"Request data: {data}")
604
605 try:
606 logger.debug(f"Sending PUT request to {endpoint} with data: {data}")
607
608 response = requests.put(
609 f"{attributes['connector_url']}{endpoint}",
610 headers=wazuh_manager_client,
611 params=params,
612 data=data,
613 verify=False,
614 )
615
616 # Log response details before checking status
617 if debug:
618 logger.debug(f"Response status: {response.status_code}")
619 logger.debug(f"Response headers: {response.headers}")
620 try:
621 logger.debug(f"Response body: {response.text}")
622 except Exception as e: # Specify Exception instead of bare except
623 logger.debug(f"Could not parse response body: {str(e)}")
624
625 # Handle HTTP errors with detailed logging
626 try:
627 response.raise_for_status()
628 except requests.exceptions.HTTPError:
629 error_detail = ""
630 try:
631 error_json = response.json()
632 if isinstance(error_json, dict):
633 # Extract Wazuh API specific error details
634 if "detail" in error_json:
635 error_detail = error_json["detail"]
636 elif "message" in error_json:
637 error_detail = error_json["message"]
638 elif "data" in error_json and "detail" in error_json["data"]:
639 error_detail = error_json["data"]["detail"]
640 except (ValueError, json.JSONDecodeError) as e: # Specify exceptions instead of bare except
641 # If can't parse JSON, use text response
642 error_detail = response.text
643 logger.debug(f"Could not parse JSON response: {str(e)}")
644
645 logger.error(f"HTTP error {response.status_code}: {error_detail}")
646 return {
647 "success": False,
648 "status_code": response.status_code,
649 "message": f"HTTP error {response.status_code}: {error_detail}",
650 "error_detail": error_detail,
651 "raw_response": response.text,
652 }
653
654 return {
655 "data": response.json(),
656 "success": True,
657 "message": "Successfully retrieved data",
658 }
659 except Exception as e:
660 logger.exception(f"Failed to send PUT request to {endpoint}")
661 return {"success": False, "message": f"Failed to send PUT request to {endpoint} with error: {str(e)}", "exception": str(e)}
662
663
664 async def send_delete_request(
665 endpoint: str,
666 params: Optional[Dict[str, Any]] = None,
667 connector_name: str = "Wazuh-Manager",
668 ) -> Dict[str, Any]:
669 """
670 Sends a DELETE request to the Wazuh Manager service.
671
672 Args:
673 endpoint (str): The endpoint to send the DELETE request to.
674 params (Optional[Dict[str, Any]], optional): The parameters to send with the DELETE request. Defaults to None.
675 connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
676
677 Returns:
678 Dict[str, Any]: The response from the DELETE request.
679 """
680 logger.info(f"Sending DELETE request to {endpoint}")
681 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
682 async with AsyncSessionLocal() as session:
683 attributes = await get_connector_info_from_db(connector_name, session)
684 if attributes is None:
685 logger.error("No Wazuh Manager connector found in the database")
686 return None
687 try:
688 response = requests.delete(
689 f"{attributes['connector_url']}{endpoint}",
690 headers=wazuh_manager_client,
691 params=params,
692 verify=False,
693 )
694 response.raise_for_status()
695 return {
696 "data": response.json(),
697 "success": True,
698 "message": "Successfully deleted data",
699 }
700 except Exception as e:
701 logger.error(f"Failed to send DELETE request to {endpoint} with error: {e}")
702 return {
703 "success": False,
704 "message": f"Failed to send DELETE request to {endpoint} with error: {e}",
705 }
706
707
708 async def restart_service(connector_name: str = "Wazuh-Manager") -> Dict[str, Any]:
709 """
710 Restarts the Wazuh Manager service.
711
712 Returns:
713 Dict[str, Any]: The response from the DELETE request.
714 """
715 logger.info("Restarting Wazuh Manager service")
716 wazuh_manager_client = await create_wazuh_manager_client(connector_name)
717 async with AsyncSessionLocal() as session:
718 attributes = await get_connector_info_from_db(connector_name, session)
719 if attributes is None:
720 logger.error("No Wazuh Manager connector found in the database")
721 return None
722 try:
723 response = requests.put(
724 f"{attributes['connector_url']}/manager/restart",
725 headers=wazuh_manager_client,
726 verify=False,
727 )
728 response.raise_for_status()
729 return {
730 "data": response.json(),
731 "success": True,
732 "message": "Successfully restarted service",
733 }
734 except Exception as e:
735 logger.error(f"Failed to restart Wazuh Manager service with error: {e}")
736 return {
737 "success": False,
738 "message": f"Failed to restart Wazuh Manager service with error: {e}",
739 }
740
741
742 async def get_cluster_status(connector_name: str = "Wazuh-Manager") -> Dict[str, Any]:
743 """
744 Retrieves the cluster status of the Wazuh Manager service.
745
746 Args:
747 connector_name (str, optional): The name of the connector to use. Defaults to "Wazuh-Manager".
748
749 Returns:
750 Dict[str, Any]: The response from the GET request.
751 """
752 logger.info("Getting Wazuh Manager cluster status")
753 return await send_get_request(
754 endpoint="/cluster/status",
755 connector_name=connector_name,
756 )
757
758
759 async def restart_wazuh_manager_service() -> Dict[str, Any]:
760 """
761 Restarts the Wazuh Manager service.
762
763 Returns:
764 Dict[str, Any]: The response from the restart request.
765 """
766 logger.info("Restarting Wazuh Manager service")
767 status_response = await get_cluster_status()
768
769 # Check if the request was successful first
770 if not status_response.get("success"):
771 logger.error("Failed to get cluster status")
772 return {
773 "success": False,
774 "message": "Failed to get cluster status before restart",
775 }
776
777 # Access the nested data structure correctly
778 cluster_enabled = status_response.get("data", {}).get("data", {}).get("enabled", "unknown")
779
780 if cluster_enabled == "no":
781 logger.info("Wazuh Manager cluster is not enabled, restarting service")
782 return await restart_service()
783 elif cluster_enabled == "yes":
784 logger.info("Wazuh Manager cluster is enabled, restarting cluster")
785 response = await send_put_request(
786 endpoint="/cluster/restart",
787 data={},
788 )
789 if response.get("success"):
790 return {
791 "success": True,
792 "message": "Wazuh Manager cluster restarted successfully",
793 }
794 else:
795 return response
796 else:
797 logger.warning(f"Unknown cluster status: {cluster_enabled}, defaulting to service restart")
798 return await restart_service()