diff --git a/api_app/analyzers_manager/classes.py b/api_app/analyzers_manager/classes.py index 7176e83370..02ac08e67f 100644 --- a/api_app/analyzers_manager/classes.py +++ b/api_app/analyzers_manager/classes.py @@ -452,15 +452,13 @@ def _docker_get(self): raise AssertionError return resp - def health_check(self, user: User = None) -> bool: + def health_check(self, user: User = None) -> Tuple[bool, str]: """ basic health check: if instance is up or not (timeout - 10s) """ try: requests.head(self.url, timeout=10) except requests.exceptions.RequestException: - health_status = False + return False, "It is NOT up" else: - health_status = True - - return health_status + return True, "It is up and running" diff --git a/api_app/classes.py b/api_app/classes.py index 109e5e8cba..d482303f64 100644 --- a/api_app/classes.py +++ b/api_app/classes.py @@ -360,7 +360,7 @@ def _get_health_check_url(self, user: User = None) -> typing.Optional[str]: return self.url return None - def health_check(self, user: User = None) -> bool: + def health_check(self, user: User = None) -> typing.Tuple[bool, str]: """ Perform a health check for the plugin. @@ -368,12 +368,12 @@ def health_check(self, user: User = None) -> bool: user (User): The user instance. Returns: - bool: Whether the health check was successful. + typing.Tuple[bool, str]: A tuple of (status, message). """ url = self._get_health_check_url(user) if url and url.startswith("http"): if settings.STAGE_CI or settings.MOCK_CONNECTIONS: - return True + return True, "It is up and running" logger.info(f"healthcheck url {url} for {self}") try: # momentarily set this to False to @@ -385,7 +385,7 @@ def health_check(self, user: User = None) -> bool: # So, in this case, we will consider it as check passed because we got an answer # For ex 405 code is when HEADs are not allowed. But it is the same. The service answered. if 400 <= response.status_code <= 408: - return True + return True, "It is up and running" response.raise_for_status() except ( requests.exceptions.ConnectionError, @@ -393,9 +393,9 @@ def health_check(self, user: User = None) -> bool: requests.exceptions.HTTPError, ) as e: logger.info(f"healthcheck failed: url {url} for {self}. Error: {e}") - return False + return False, "It is NOT up" else: - return True + return True, "It is up and running" raise NotImplementedError() def disable_for_rate_limit(self): diff --git a/api_app/views.py b/api_app/views.py index ce18dca7f5..17224a13cf 100644 --- a/api_app/views.py +++ b/api_app/views.py @@ -1311,12 +1311,7 @@ def health_check(self, request, name=None): config: PythonConfig = self.get_object() python_obj = config.python_module.python_class(config) try: - health_result = python_obj.health_check(request.user) - if isinstance(health_result, tuple): - health_status, health_message = health_result - else: - health_status = health_result - health_message = "It is up and running" if health_status else "It is NOT up" + health_status, health_message = python_obj.health_check(request.user) except NotImplementedError as e: logger.info(f"NotImplementedError {e}, user {request.user}, name {name}") raise ValidationError({"detail": "No healthcheck implemented"}) diff --git a/intel_owl/tasks.py b/intel_owl/tasks.py index 0f2b571bb1..b097db5d92 100644 --- a/intel_owl/tasks.py +++ b/intel_owl/tasks.py @@ -197,7 +197,7 @@ def health_check(python_module_pk: int, plugin_config_pk: str): ) if not config.disabled: try: - enabled = plugin.health_check(user=None) + enabled, _ = plugin.health_check(user=None) except NotImplementedError: logger.error(f"Unable to check healthcheck for {config.name}") else: diff --git a/tests/api_app/analyzers_manager/integration_tests/file_analyzers/test_strings_info.py b/tests/api_app/analyzers_manager/integration_tests/file_analyzers/test_strings_info.py index 3697a812a2..20fc5c0cf3 100644 --- a/tests/api_app/analyzers_manager/integration_tests/file_analyzers/test_strings_info.py +++ b/tests/api_app/analyzers_manager/integration_tests/file_analyzers/test_strings_info.py @@ -17,7 +17,7 @@ def tearDown() -> None: Job.objects.all().delete() @skipIf( - not StringsInfo(None).health_check(), + not StringsInfo(None).health_check()[0], "malware tools analyzer container not active", ) def test_urls(self): diff --git a/tests/api_app/connectors_manager/test_classes.py b/tests/api_app/connectors_manager/test_classes.py index ae78423674..b95de89fd7 100644 --- a/tests/api_app/connectors_manager/test_classes.py +++ b/tests/api_app/connectors_manager/test_classes.py @@ -46,12 +46,12 @@ def run(self) -> dict: with patch("requests.head") as mock_head: mock_head.return_value.status_code = 200 - result = MockUpConnector(cc).health_check(self.user) - self.assertTrue(result) + status, _ = MockUpConnector(cc).health_check(self.user) + self.assertTrue(status) cc.disabled = False cc.save() - result = MockUpConnector(cc).health_check(self.user) - self.assertTrue(result) + status, _ = MockUpConnector(cc).health_check(self.user) + self.assertTrue(status) cc.delete() pc.delete() diff --git a/tests/api_app/connectors_manager/test_views.py b/tests/api_app/connectors_manager/test_views.py index 4a8fd7cfae..ba408058b1 100644 --- a/tests/api_app/connectors_manager/test_views.py +++ b/tests/api_app/connectors_manager/test_views.py @@ -54,46 +54,6 @@ def test_health_check(self): pc1.delete() pc2.delete() - def test_health_check_legacy_boolean_return(self): - connector: ConnectorConfig = ConnectorConfig.objects.get(name="YETI") - pc1 = PluginConfig.objects.create( - parameter=connector.parameters.get(name="api_key_name"), - value="test", - for_organization=False, - owner=None, - connector_config=connector, - ) - pc2 = PluginConfig.objects.create( - parameter=connector.parameters.get(name="url_key_name"), - value="https://test", - for_organization=False, - owner=None, - connector_config=connector, - ) - - with patch("api_app.connectors_manager.connectors.yeti.YETI.health_check", return_value=True): - self.client.force_authenticate(self.superuser) - response = self.client.get(f"{self.URL}/{connector.name}/health_check") - self.assertEqual(response.status_code, 200) - - result = response.json() - self.assertIn("status", result) - self.assertTrue(result["status"]) - self.assertEqual(result["message"], "It is up and running") - - with patch("api_app.connectors_manager.connectors.yeti.YETI.health_check", return_value=False): - self.client.force_authenticate(self.superuser) - response = self.client.get(f"{self.URL}/{connector.name}/health_check") - self.assertEqual(response.status_code, 200) - - result = response.json() - self.assertIn("status", result) - self.assertFalse(result["status"]) - self.assertEqual(result["message"], "It is NOT up") - - pc1.delete() - pc2.delete() - def test_get(self): # 1 - existing connector self.client.force_authenticate(user=self.user)