Skip to content

Commit

Permalink
Change the group service page to group by nagios test.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Cooper committed Aug 17, 2011
1 parent 1181227 commit 0b87909
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 166 deletions.
2 changes: 0 additions & 2 deletions railroad/railroad/urls.py
Expand Up @@ -32,8 +32,6 @@
(r'^viewhost/(?P<host>\w+)/(?P<service>.+)$',
'railroad.viewhosts.views.service'),
(r'^viewgroup/(?P<group>[^/]+)$', 'railroad.viewhosts.views.group'),
(r'^viewgroup/(?P<group>[^/]+)/(?P<test>.+)/(?P<alias>.+)$',
'railroad.viewhosts.views.groupservice'),
# Configurator and helper functions for AJAX
(r'^configurator$', 'railroad.viewhosts.views.directconfigurator'),
(r'^configurator/graph$', 'railroad.viewhosts.views.customgraph'),
Expand Down
164 changes: 30 additions & 134 deletions railroad/railroad/viewhosts/views.py
Expand Up @@ -147,6 +147,13 @@ def parse():
for group in obj['hostgroup']:
group['alias'] = group['alias'].replace('/', '-')

for service in stat['service']:
# Django doesn't like variables that start with _.
if '_TEST' in service:
service['nagcat_template'] = service['_TEST'].split(';', 1)[-1]
else:
service['nagcat_template'] = ''

return stat, obj


Expand Down Expand Up @@ -459,57 +466,6 @@ def fetch_current_rrd_data(service, interval=60, aggregate='AVERAGE'):
'--end', str(end), aggregate)


def servicelist_by_filters(stat, filters={}):
"""Return a list of services from STAT that match FILTERS."""
# by default, match everything
svcs = servicelist(stat)
# first, look at hostnames
hnames = set(hostnames(stat))
if filters.get('host', None):
# try exact match first
if filters['host'] in hnames:
svcs = [s for s in svcs if s['host_name'] == filters['host']]
else:
svcs = [s for s in svcs
if re.search(filters['host'], s['host_name'])]
if filters.get('service', None):
# very unlikely that an exact match would also be a substring,
# so don't bother trying that first
svcs = [s for s in svcs
if re.search(filters['service'], s['service_description'])]
if (('a_red' in filters) or ('a_yellow' in filters)
or ('a_green' in filters)):
alertlevels = set()
if filters.get('a_red', False):
alertlevels.add("2")
if filters.get('a_yellow', False):
alertlevels.add("1")
if filters.get('a_green', False):
alertlevels.add("0")
svcs = [s for s in svcs if s['current_state'] in alertlevels]
return svcs

sort_options = (('svc', 'Service Name'), ('rrd', 'Latest RRD values'))


class FilterForm(forms.Form):
# The widget, attr is used to enable autocomplete on these text forms
host = forms.CharField(required=False, widget=forms.TextInput(
attrs={"id": "host", "class": "autocomplete"}))
service = forms.CharField(required=False, widget=forms.TextInput(
attrs={"id": "service", "class": "autocomplete"}))
a_green = forms.BooleanField(required=False, initial=True,
label="OKAY (green)")
a_yellow = forms.BooleanField(required=False, initial=True,
label="WARN (yellow)")
a_red = forms.BooleanField(required=False, initial=True,
label="CRITICAL (red)")
sortreverse = forms.BooleanField(required=False,
label="Reverse sort order")
sortby = forms.ChoiceField(choices=sort_options, initial="svc",
label="Sort results by")


def host(request, host):
"""Returns a page showing all services of the specified host"""
loaded_graphs = []
Expand Down Expand Up @@ -590,7 +546,6 @@ def service(request, host, service):

def group(request, group):
"""Returns a page showing all hosts/services of the specified group"""
t = loader.get_template('group.html')
stat, obj = parse()
service_dict = {}

Expand All @@ -599,32 +554,20 @@ def group(request, group):
raise Http404

host_names = map(lambda x: x['host_name'], host_list)
service_list = servicelist(stat)
services = []
for host in host_names:
services += servicelist_by_host(stat, host)

# Remove unique digits, dashes, commas, and version numbers to consolidate
# service descriptions. Duplicated in groupservice function
janitor = re.compile("[-,]?\d+\.?\d*[-,]?")
services.sort(key=lambda x: x['service_description'])
host_list.sort(key=lambda x: x['host_name'])

for service in service_list:
service_alias = janitor.sub("", service['service_description'])
service_test = service.get('_TEST', None)
service_test = service_test if service_test \
else service['check_command']
if service['host_name'] in host_names:
if service_test not in service_dict:
service_dict[service_test] = []
if service_alias not in service_dict[service_test]:
service_dict[service_test].append(service_alias)
# Uniquify the service names
service_dict = {}
for s in services:
key = s['service_description']
service_dict[key] = s

services = []
service_tests = service_dict.keys()
for service_test in service_tests:
for service_alias in service_dict[service_test]:
services.append({'service_test': service_test, \
'service_alias': service_alias})

services.sort(lambda x, y: cmp(x['service_alias'], y['service_alias']))
host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
services = service_dict.values()

end = int(time.time())
start = end - DAY
Expand All @@ -635,56 +578,7 @@ def group(request, group):
'time_interval': [start, end]}

context_data = add_hostlist(stat, obj, context_data)
c = Context(context_data)
return HttpResponse(t.render(c))


def groupservice(request, group, test, alias):
"""Returns a page showing all instances of specified service of group"""
loaded_graphs = []
stat, obj = parse()
if group != None and test != None and alias != None:
end = int(time.time())
start = end - DAY
host_list = hostlist_by_group(stat, obj, group)
target = map(lambda x: x['host_name'], host_list)

service_list = servicelist(stat)

# Filter service_list by test and alias (strip numbers/hyphens)
janitor = re.compile("[-,]?\d+\.?\d*[-,]?")
for service in service_list:
service_test = service.get('_TEST', None) if \
service.get('_TEST', None) else \
service.get('check_command', None)
service_alias = janitor.sub("", service['service_description'])

if service_test == test and service_alias == alias:
host_name = service['host_name']
try:
host = host_list[target.index(host_name)]
if 'services' not in host:
host['services'] = []
service['is_graphable'] = \
is_graphable(host_name, service['service_description'])
if (service['is_graphable']):
service['start'] = start
service['end'] = end
service['period'] = 'ajax'
host['services'].append(service)
except ValueError:
continue

host_list = [h for h in host_list if 'services' in h]
host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
map(lambda z: z['services'].sort(lambda x, y: \
cmp(x['service_description'], y['service_description'])), \
host_list)

for host in host_list:
loaded_graphs.extend(host['services'])
return configurator(request, stat, obj, 'Group-Service Detail: %s > %s' %
(group, alias), '%s > %s' % (group, alias), loaded_graphs)
return render_to_response('group.html', context_data)


def form(request):
Expand Down Expand Up @@ -740,11 +634,6 @@ def real_meta(hosts='', services='', groups=''):
graph_template = loader.get_template('graph.html')

for graph in get_graphs(stat, obj, hosts, groups, services):
# Django doesn't like variables that start with _.
if '_TEST' in graph:
graph['nagcat_template'] = graph['_TEST'].split(';', 1)[-1]
else:
graph['nagcat_template'] = ''

so = {
'host': graph['host_name'],
Expand Down Expand Up @@ -867,9 +756,18 @@ def directurl(request, id):


def directconfigurator(request):
"""Returns a blank configurator page"""
"""Returns a configurator page, optionall populated from GET."""
stat, obj = parse()
return configurator(request, stat, obj)

query = {
'hosts': request.GET.get('hosts', ''),
'services': request.GET.get('services', ''),
'groups': request.GET.get('groups', ''),
}

service_list = real_meta(**query)

return configurator(request, stat, obj, graphs=service_list)


def hostconfigurator(request, hosts):
Expand Down Expand Up @@ -1051,8 +949,6 @@ def formstate(request):
return HttpResponse(json.dumps(stripstate(state)))




def graphs(request):
stat, obj = parse()

Expand Down
9 changes: 9 additions & 0 deletions railroad/static/css/style.css
Expand Up @@ -549,3 +549,12 @@ fieldset {
overflow-y: auto;
padding-right: 20px;
}

.twirler ul {
list-style: disc;
margin-left: 20px;
}

td.twirler {
vertical-align: top;
}
2 changes: 1 addition & 1 deletion railroad/templates/graph.html
Expand Up @@ -33,7 +33,7 @@
<dt name="attempts">Attempts</dt>
<dd name="attempts">{{ current_attempt }}/{{ max_attempts}}</dd>

<dt>Nagcat Template</dt>
<dt>Nagcat Test</dt>
<dd>{{ nagcat_template }}</dd>
</dl>
</td>
Expand Down
62 changes: 40 additions & 22 deletions railroad/templates/group.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
{% load services %}

{% block title %}Group: {{group_name}}{% endblock %}

Expand All @@ -8,37 +9,54 @@ <h1>{{group_name}}</h1>

{% block content %}

<div class="services">
<h2>Hosts</h2>
<table>
<tr>
{% for host in hosts %}
{% ifequal host.current_state '0' %}
<td class="greenbg">
{% else %}
{% ifequal host.current_state '1' %}
<td class="yellowbg">
{% else %}
<td class="redbg">
{% endifequal %}
{% endifequal %}
<a href="/railroad/configurator/host/{{ host.host_name }}">{{host.host_name}}</a>
</td>
{% if forloop.counter|divisibleby:"5" %}</tr><tr>{% endif %}
{% endfor %}
</tr>
<tr>
{% for host in hosts %}
<td class="state_{{ host.current_state|state_name|lower }}">
<a href="/railroad/configurator/host/{{ host.host_name }}">{{host.host_name}}</a>
</td>
{% if forloop.counter|divisibleby:"5" %}</tr><tr>{% endif %}
{% endfor %}
</tr>
</table>
<br />
<h2>Services</h2>
<table>
<tr>
{% for service in services %}
<td>
<a href="/railroad/configurator/service/{{ service.service_alias }}">{{service.service_alias}}</a>
</td>
{% regroup services|dictsort:"nagcat_template" by nagcat_template as test_services %}
{% for test in test_services %}
{% ifequal test.list|length 1 %}
<td>
<a href="{% url railroad.viewhosts.views.directconfigurator %}?services={{ test.list.0.service_description }}&groups={{ group_name }}">
{{test.list.0.service_description}}
</a>
</td>
{% else %}
<td class="twirler">
<span class="target">
{% ifequal test.grouper "" %}
No Test
{% else %}
{{ test.grouper }}
<a href="{% url railroad.viewhosts.views.directconfigurator %}?test={{ test.grouper }}">
<div class="sprite arrow_e hover"></div>
</a>
{% endifequal %}
</span>
<ul>
{% for service in test.list|dictsort:"service_description" %}
<li>
<a href="{% url railroad.viewhosts.views.directconfigurator %}?services={{ service.service_description }}&groups={{ group_name }}">
{{service.service_description}}
</a>
</li>
{% endfor %}
</ul>
</td>
{% endifequal %}
{% if forloop.counter|divisibleby:"2" %}</tr><tr>{% endif %}
{% endfor %}
</tr>
</table>
</div>
{% endblock %}
1 change: 1 addition & 0 deletions railroad/templates/index.html
Expand Up @@ -30,6 +30,7 @@ <h2>Quicklook
{% for state in service_states reversed %}
<li>
<span class="status_text state_{{ state.grouper|state_name|lower }}">

{{ state.grouper|state_name }} -
{{ state.list|length }} service{{state.list|length|pluralize}}
</span>
Expand Down
14 changes: 7 additions & 7 deletions railroad/templates/sidebar.html
@@ -1,16 +1,16 @@
{% load services %}
{% block sidebar %}
<div id="sidebar">
<div class="biglist">
{% for elem in sidebar %}
<div class="listheader"><a href="{% url railroad.viewhosts.views.group elem.0 %}">{{elem.0}}</a></div>
<div class="listheader">
<a href="{% url railroad.viewhosts.views.group elem.0 %}">{{elem.0}}</a></div>
<ul>
{% for host in elem.1 %}
{% ifequal host.current_state 0 %}
<li class="red">
{% else %}
<li class="green">
{% endifequal %}
<a href="{% url railroad.viewhosts.views.hostconfigurator host.host_name %}">{{host.host_name}}</a>
<li class="state_{{ host.current_state|state_name|lower }}">
<a href="{% url railroad.viewhosts.views.directconfigurator %}?hosts={{host.host_name}}">
{{host.host_name}}
</a>
</li>
{% endfor %}
</ul>
Expand Down

0 comments on commit 0b87909

Please sign in to comment.