Move service health view into new overview panel
Change-Id: I827134cfca77f1dc792e31f93278e9c804fa7358
This commit is contained in:
parent
9976d69a0d
commit
0deaf7f789
@ -16,13 +16,6 @@ DETAIL_URL = urlresolvers.reverse(
|
|||||||
|
|
||||||
|
|
||||||
class AlarmsTest(helpers.TestCase):
|
class AlarmsTest(helpers.TestCase):
|
||||||
def test_index_get(self):
|
|
||||||
res = self.client.get(INDEX_URL)
|
|
||||||
|
|
||||||
self.assertTemplateUsed(
|
|
||||||
res, 'monitoring/alarms/index.html')
|
|
||||||
self.assertTemplateUsed(res, 'monitoring/alarms/monitor.html')
|
|
||||||
|
|
||||||
def test_alarms_get(self):
|
def test_alarms_get(self):
|
||||||
with patch('monitoring.api.monitor', **{
|
with patch('monitoring.api.monitor', **{
|
||||||
'spec_set': ['alarm_list_by_service'],
|
'spec_set': ['alarm_list_by_service'],
|
||||||
|
@ -21,7 +21,6 @@ from monitoring.alarms import views
|
|||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
url(r'^status', views.StatusView.as_view(), name='status'),
|
|
||||||
url(r'^alarm/(?P<service>[^/]+)/$',
|
url(r'^alarm/(?P<service>[^/]+)/$',
|
||||||
views.AlarmServiceView.as_view(),
|
views.AlarmServiceView.as_view(),
|
||||||
name='alarm'),
|
name='alarm'),
|
||||||
|
@ -22,9 +22,10 @@ from django.conf import settings # noqa
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.urlresolvers import reverse_lazy, reverse # noqa
|
from django.core.urlresolvers import reverse_lazy, reverse # noqa
|
||||||
from django.http import HttpResponse # noqa
|
from django.http import HttpResponse # noqa
|
||||||
|
from django.shortcuts import redirect
|
||||||
from django.template import defaultfilters as filters
|
from django.template import defaultfilters as filters
|
||||||
from django.utils.translation import ugettext as _ # noqa
|
from django.utils.translation import ugettext as _ # noqa
|
||||||
from django.views.generic import TemplateView # noqa
|
from django.views.generic import View # noqa
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
@ -95,26 +96,9 @@ def generate_status(request):
|
|||||||
return SERVICES
|
return SERVICES
|
||||||
|
|
||||||
|
|
||||||
class IndexView(TemplateView):
|
class IndexView(View):
|
||||||
template_name = constants.TEMPLATE_PREFIX + 'index.html'
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
return redirect(constants.URL_PREFIX + 'alarm', service='all')
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(IndexView, self).get_context_data(**kwargs)
|
|
||||||
context["token"] = self.request.user.token.id
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class StatusView(TemplateView):
|
|
||||||
template_name = ""
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
ret = {
|
|
||||||
'series': generate_status(self.request),
|
|
||||||
'settings': {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return HttpResponse(json.dumps(ret),
|
|
||||||
content_type='application/json')
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmServiceView(tables.DataTableView):
|
class AlarmServiceView(tables.DataTableView):
|
||||||
|
@ -22,8 +22,8 @@ import horizon
|
|||||||
class Monitoring(horizon.Dashboard):
|
class Monitoring(horizon.Dashboard):
|
||||||
name = _("Monitoring")
|
name = _("Monitoring")
|
||||||
slug = "monitoring"
|
slug = "monitoring"
|
||||||
panels = ('alarms', 'notifications')
|
panels = ('overview', 'alarms', 'notifications')
|
||||||
default_panel = 'alarms'
|
default_panel = 'overview'
|
||||||
|
|
||||||
|
|
||||||
horizon.register(Monitoring)
|
horizon.register(Monitoring)
|
||||||
|
0
monitoring/overview/__init__.py
Normal file
0
monitoring/overview/__init__.py
Normal file
25
monitoring/overview/constants.py
Normal file
25
monitoring/overview/constants.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
URL_PREFIX = 'horizon:monitoring:overview:'
|
||||||
|
TEMPLATE_PREFIX = 'monitoring/overview/'
|
||||||
|
|
||||||
|
CRITICAL_ICON = '/static/monitoring/img/critical-icon.png'
|
||||||
|
WARNING_ICON = '/static/monitoring/img/warning-icon.png'
|
||||||
|
OK_ICON = '/static/monitoring/img/ok-icon.png'
|
||||||
|
UNKNOWN_ICON = '/static/monitoring/img/unknown-icon.png'
|
||||||
|
NOTFOUND_ICON = '/static/monitoring/img/notfound-icon.png'
|
29
monitoring/overview/panel.py
Normal file
29
monitoring/overview/panel.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
|
||||||
|
from monitoring import dashboard
|
||||||
|
|
||||||
|
|
||||||
|
class Overview(horizon.Panel):
|
||||||
|
name = _("Overview")
|
||||||
|
slug = 'overview'
|
||||||
|
|
||||||
|
|
||||||
|
dashboard.Monitoring.register(Overview)
|
@ -14,5 +14,5 @@
|
|||||||
{% trans 'Dashboard' %}
|
{% trans 'Dashboard' %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% include 'monitoring/alarms/monitor.html' %}
|
{% include 'monitoring/overview/monitor.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -55,7 +55,7 @@
|
|||||||
{$ group.name $}
|
{$ group.name $}
|
||||||
</div>
|
</div>
|
||||||
<div ng-repeat="service in group.services" style="display:inline-block; margin-bottom:4px; margin-right:4px;">
|
<div ng-repeat="service in group.services" style="display:inline-block; margin-bottom:4px; margin-right:4px;">
|
||||||
<a href="/monitoring/alarm/{$ service.name $}">
|
<a href="/monitoring/alarms/alarm/{$ service.name $}">
|
||||||
<div class="base-chicklet {$ service.class $}">
|
<div class="base-chicklet {$ service.class $}">
|
||||||
<div>
|
<div>
|
||||||
<div class="status-icon-holder" >
|
<div class="status-icon-holder" >
|
18
monitoring/overview/tests.py
Normal file
18
monitoring/overview/tests.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from django.core import urlresolvers
|
||||||
|
from mock import patch, call # noqa
|
||||||
|
|
||||||
|
from monitoring.test import helpers
|
||||||
|
from monitoring.overview import constants
|
||||||
|
|
||||||
|
|
||||||
|
INDEX_URL = urlresolvers.reverse(
|
||||||
|
constants.URL_PREFIX + 'index')
|
||||||
|
|
||||||
|
|
||||||
|
class OverviewTest(helpers.TestCase):
|
||||||
|
def test_index_get(self):
|
||||||
|
res = self.client.get(INDEX_URL)
|
||||||
|
self.assertTemplateUsed(
|
||||||
|
res, 'monitoring/overview/index.html')
|
||||||
|
self.assertTemplateUsed(res, 'monitoring/overview/monitor.html')
|
||||||
|
|
25
monitoring/overview/urls.py
Normal file
25
monitoring/overview/urls.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from django.conf.urls import patterns # noqa
|
||||||
|
from django.conf.urls import url # noqa
|
||||||
|
|
||||||
|
from monitoring.overview import views
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
'',
|
||||||
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
|
url(r'^status', views.StatusView.as_view(), name='status'),
|
||||||
|
)
|
106
monitoring/overview/views.py
Normal file
106
monitoring/overview/views.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.import logging
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings # noqa
|
||||||
|
from django.http import HttpResponse # noqa
|
||||||
|
from django.views.generic import TemplateView # noqa
|
||||||
|
|
||||||
|
from monitoring.overview import constants
|
||||||
|
from monitoring.alarms import tables as alarm_tables
|
||||||
|
from monitoring import api
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
SERVICES = getattr(settings, 'MONITORING_SERVICES', [])
|
||||||
|
|
||||||
|
|
||||||
|
def get_icon(status):
|
||||||
|
if status == 'chicklet-success':
|
||||||
|
return constants.OK_ICON
|
||||||
|
if status == 'chicklet-error':
|
||||||
|
return constants.CRITICAL_ICON
|
||||||
|
if status == 'chicklet-warning':
|
||||||
|
return constants.WARNING_ICON
|
||||||
|
if status == 'chicklet-unknown':
|
||||||
|
return constants.UNKNOWN_ICON
|
||||||
|
if status == 'chicklet-notfound':
|
||||||
|
return constants.NOTFOUND_ICON
|
||||||
|
|
||||||
|
|
||||||
|
priorities = [
|
||||||
|
{'status': 'chicklet-success', 'severity': 'OK'},
|
||||||
|
{'status': 'chicklet-unknown', 'severity': 'UNDETERMINED'},
|
||||||
|
{'status': 'chicklet-warning', 'severity': 'LOW'},
|
||||||
|
{'status': 'chicklet-warning', 'severity': 'MEDIUM'},
|
||||||
|
{'status': 'chicklet-warning', 'severity': 'HIGH'},
|
||||||
|
{'status': 'chicklet-error', 'severity': 'CRITICAL'},
|
||||||
|
]
|
||||||
|
index_by_severity = {d['severity']: i for i, d in enumerate(priorities)}
|
||||||
|
|
||||||
|
|
||||||
|
def get_status(alarms):
|
||||||
|
if not alarms:
|
||||||
|
return 'chicklet-notfound'
|
||||||
|
status_index = 0
|
||||||
|
for a in alarms:
|
||||||
|
severity = alarm_tables.show_severity(a)
|
||||||
|
severity_index = index_by_severity[severity]
|
||||||
|
status_index = max(status_index, severity_index)
|
||||||
|
return priorities[status_index]['status']
|
||||||
|
|
||||||
|
|
||||||
|
def generate_status(request):
|
||||||
|
try:
|
||||||
|
alarms = api.monitor.alarm_list(request)
|
||||||
|
except Exception:
|
||||||
|
alarms = []
|
||||||
|
alarms_by_service = {}
|
||||||
|
for a in alarms:
|
||||||
|
service = alarm_tables.show_service(a)
|
||||||
|
service_alarms = alarms_by_service.setdefault(service, [])
|
||||||
|
service_alarms.append(a)
|
||||||
|
for row in SERVICES:
|
||||||
|
row['name'] = unicode(row['name'])
|
||||||
|
for service in row['services']:
|
||||||
|
service_alarms = alarms_by_service.get(service['name'], [])
|
||||||
|
service['class'] = get_status(service_alarms)
|
||||||
|
service['icon'] = get_icon(service['class'])
|
||||||
|
service['display'] = unicode(service['display'])
|
||||||
|
return SERVICES
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(TemplateView):
|
||||||
|
template_name = constants.TEMPLATE_PREFIX + 'index.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(IndexView, self).get_context_data(**kwargs)
|
||||||
|
context["token"] = self.request.user.token.id
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class StatusView(TemplateView):
|
||||||
|
template_name = ""
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
ret = {
|
||||||
|
'series': generate_status(self.request),
|
||||||
|
'settings': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResponse(json.dumps(ret),
|
||||||
|
content_type='application/json')
|
Loading…
x
Reference in New Issue
Block a user