diff --git a/openstack_health/api.py b/openstack_health/api.py index 761bb6a9..42ac0b33 100644 --- a/openstack_health/api.py +++ b/openstack_health/api.py @@ -33,6 +33,7 @@ from flask.ext.jsonpify import jsonify from flask import make_response from flask import request from operator import itemgetter +import pyelasticsearch import pytz from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker @@ -56,6 +57,7 @@ classifier = None rss_opts = {} feeds = {'last runs': {}} region = None +es_url = None def get_app(): @@ -98,15 +100,16 @@ def setup(): except ConfigParser.Error: rss_opts['frontend_url'] = ('http://status.openstack.org/' 'openstack-health') + global query_dir try: query_dir = config.get('default', 'query_dir') except ConfigParser.Error: pass + global es_url try: es_url = config.get('default', 'es_url') except ConfigParser.Error: es_url = None - if query_dir and er: global classifier classifier = er.Classifier(query_dir, es_url=es_url) @@ -561,12 +564,31 @@ def _check_db_availability(): return False +def _check_er_availability(): + global es_url + global query_dir + if not classifier: + if not er: + health = 'NotInstalled' + elif not es_url or not query_dir: + health = 'NotConfigured' + else: + url = classifier.es_url + es = pyelasticsearch.ElasticSearch(url) + health = {'Configured': {'elastic-search': es.health()['status']}} + return health + + @app.route('/status', methods=['GET']) def get_status(): is_db_available = _check_db_availability() + is_er_available = _check_er_availability() - status = {'status': {'availability': {'database': is_db_available}}} + status = {'status': {'availability': { + 'database': is_db_available, + 'elastic-recheck': is_er_available + }}} response = jsonify(status) if not is_db_available: diff --git a/openstack_health/tests/test_api.py b/openstack_health/tests/test_api.py index 23defde8..fe3a655e 100644 --- a/openstack_health/tests/test_api.py +++ b/openstack_health/tests/test_api.py @@ -679,9 +679,14 @@ class TestRestAPI(base.TestCase): @mock.patch('openstack_health.api._check_db_availability', return_value=False) - def test_get_status_failure(self, status_check_mock): - expected_response = {'status': {'availability': {'database': False}}} - + @mock.patch('openstack_health.api._check_er_availability', + return_value='NotInstalled') + def test_get_status_failure_er_not_installed(self, status_check_mock, + er_mock): + expected_response = {'status': {'availability': { + 'database': False, + 'elastic-recheck': 'NotInstalled' + }}} response = self.app.get('/status') self.assertEqual(response.status_code, 500) self.assertEqual(json.loads(response.data.decode('utf-8')), @@ -689,13 +694,32 @@ class TestRestAPI(base.TestCase): @mock.patch('openstack_health.api._check_db_availability', return_value=True) - def test_get_status_success(self, status_check_mock): - expected_response = {'status': {'availability': {'database': True}}} - + @mock.patch('openstack_health.api._check_er_availability', + return_value='NotConfigured') + def test_get_db_status_success_er_not_configured(self, status_check_mock, + er_mock): + expected_response = {'status': {'availability': { + 'database': True, + 'elastic-recheck': 'NotConfigured' + }}} response = self.app.get('/status') self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.data.decode('utf-8')), - expected_response) + output = json.loads(response.data.decode('utf-8')) + self.assertEqual(output, expected_response) + + @mock.patch('openstack_health.api._check_db_availability', + return_value=True) + @mock.patch('openstack_health.api._check_er_availability', + return_value={'Configured': {'elastic-search': 'green'}}) + def test_get_db_status_success_er_green(self, status_check_mock, er_mock): + expected_response = {'status': {'availability': { + 'database': True, + 'elastic-recheck': {'Configured': {'elastic-search': 'green'}} + }}} + response = self.app.get('/status') + self.assertEqual(response.status_code, 200) + output = json.loads(response.data.decode('utf-8')) + self.assertEqual(output, expected_response) def test_failed_runs_count_should_not_consider_unknown_ones(self): runs = [ diff --git a/requirements.txt b/requirements.txt index 8807fe71..d3af8cfe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ numpy>=1.7.0 # BSD six>=1.9.0 # MIT pytz>=2013.6 # MIT feedgen>=0.3.2 # BSD +pyelasticsearch<1.0