Add source status API and enhance dashboard with data source checks
- Introduced a new API endpoint `/api/source-status/` to return the status of Prometheus and OpenStack data sources. - Implemented lightweight health check functions for both Prometheus and OpenStack. - Updated the dashboard template to display the status of data sources dynamically. - Added tests for the new API endpoint to ensure correct functionality and response handling. - Configured a cache timeout for source status checks to improve performance.
This commit is contained in:
@@ -12,6 +12,7 @@ from dashboard.views import (
|
||||
collect_audits,
|
||||
api_stats,
|
||||
api_audits,
|
||||
api_source_status,
|
||||
)
|
||||
|
||||
|
||||
@@ -259,3 +260,102 @@ class ApiAuditsTest(TestCase):
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["audits"][0]["name"], "Cached Audit")
|
||||
self.assertEqual(data["current_cluster"], cached_cluster)
|
||||
|
||||
|
||||
class ApiSourceStatusTest(TestCase):
|
||||
"""Tests for api_source_status view."""
|
||||
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
|
||||
@patch("dashboard.views.settings")
|
||||
def test_api_source_status_mock_returns_mock_status(self, mock_settings):
|
||||
mock_settings.USE_MOCK_DATA = True
|
||||
mock_settings.SOURCE_STATUS_CACHE_TTL = 30
|
||||
request = self.factory.get("/api/source-status/")
|
||||
response = api_source_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response["Content-Type"], "application/json")
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["prometheus"]["status"], "mock")
|
||||
self.assertEqual(data["openstack"]["status"], "mock")
|
||||
|
||||
@patch("dashboard.views.check_openstack")
|
||||
@patch("dashboard.views.check_prometheus")
|
||||
@patch("dashboard.views.settings")
|
||||
def test_api_source_status_both_ok_returns_ok(
|
||||
self, mock_settings, mock_check_prometheus, mock_check_openstack
|
||||
):
|
||||
mock_settings.USE_MOCK_DATA = False
|
||||
mock_settings.SOURCE_STATUS_CACHE_TTL = 30
|
||||
mock_check_prometheus.return_value = {"status": "ok"}
|
||||
mock_check_openstack.return_value = {"status": "ok"}
|
||||
cache.clear()
|
||||
request = self.factory.get("/api/source-status/")
|
||||
response = api_source_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["prometheus"]["status"], "ok")
|
||||
self.assertEqual(data["openstack"]["status"], "ok")
|
||||
mock_check_prometheus.assert_called_once()
|
||||
mock_check_openstack.assert_called_once()
|
||||
|
||||
@patch("dashboard.views.check_openstack")
|
||||
@patch("dashboard.views.check_prometheus")
|
||||
@patch("dashboard.views.settings")
|
||||
def test_api_source_status_prometheus_error_returns_error_message(
|
||||
self, mock_settings, mock_check_prometheus, mock_check_openstack
|
||||
):
|
||||
mock_settings.USE_MOCK_DATA = False
|
||||
mock_settings.SOURCE_STATUS_CACHE_TTL = 30
|
||||
mock_check_prometheus.return_value = {"status": "error", "message": "Connection refused"}
|
||||
mock_check_openstack.return_value = {"status": "ok"}
|
||||
cache.clear()
|
||||
request = self.factory.get("/api/source-status/")
|
||||
response = api_source_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["prometheus"]["status"], "error")
|
||||
self.assertEqual(data["prometheus"]["message"], "Connection refused")
|
||||
self.assertEqual(data["openstack"]["status"], "ok")
|
||||
|
||||
@patch("dashboard.views.check_openstack")
|
||||
@patch("dashboard.views.check_prometheus")
|
||||
@patch("dashboard.views.settings")
|
||||
def test_api_source_status_openstack_error_returns_error_message(
|
||||
self, mock_settings, mock_check_prometheus, mock_check_openstack
|
||||
):
|
||||
mock_settings.USE_MOCK_DATA = False
|
||||
mock_settings.SOURCE_STATUS_CACHE_TTL = 30
|
||||
mock_check_prometheus.return_value = {"status": "ok"}
|
||||
mock_check_openstack.return_value = {"status": "error", "message": "Auth failed"}
|
||||
cache.clear()
|
||||
request = self.factory.get("/api/source-status/")
|
||||
response = api_source_status(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["prometheus"]["status"], "ok")
|
||||
self.assertEqual(data["openstack"]["status"], "error")
|
||||
self.assertEqual(data["openstack"]["message"], "Auth failed")
|
||||
|
||||
@patch("dashboard.views.check_openstack")
|
||||
@patch("dashboard.views.check_prometheus")
|
||||
@patch("dashboard.views.settings")
|
||||
def test_api_source_status_uses_cache(
|
||||
self, mock_settings, mock_check_prometheus, mock_check_openstack
|
||||
):
|
||||
mock_settings.USE_MOCK_DATA = False
|
||||
mock_settings.SOURCE_STATUS_CACHE_TTL = 30
|
||||
cache.clear()
|
||||
cached = {
|
||||
"prometheus": {"status": "ok"},
|
||||
"openstack": {"status": "ok"},
|
||||
}
|
||||
cache.set("dashboard_source_status", cached, timeout=30)
|
||||
request = self.factory.get("/api/source-status/")
|
||||
response = api_source_status(request)
|
||||
mock_check_prometheus.assert_not_called()
|
||||
mock_check_openstack.assert_not_called()
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data["prometheus"]["status"], "ok")
|
||||
self.assertEqual(data["openstack"]["status"], "ok")
|
||||
|
||||
Reference in New Issue
Block a user