Esempio n. 1
0
def status_parents(request):
    c = {}
    c['messages'] = []
    authuser = request.GET.get('contact_name', None)
    livestatus = utils.livestatus(request)
    all_hosts = livestatus.get_hosts()
    host_dict = {}
    map(lambda x: host_dict.__setitem__(x['name'], x), all_hosts)
    c['hosts'] = []

    for i in all_hosts:
        if len(i['childs']) > 0:
            c['hosts'].append(i)
            ok = 0
            crit = 0
            i['child_hosts'] = []
            for x in i['childs']:
                i['child_hosts'].append( host_dict[x] )
                if host_dict[x]['state'] == 0:
                    ok += 1
                else:
                    crit += 1
            total = float(len(i['childs']))
            i['health'] = float(ok) / total * 100.0
            i['percent_ok'] = ok/total*100
            i['percent_crit'] = crit/total*100

    return render_to_response('status_parents.html', c, context_instance = RequestContext(request))
Esempio n. 2
0
def network_parents(request):
    """ List of hosts that are network parents """
    c = {}
    c['messages'] = []
    authuser = request.GET.get('contact_name', None)
    livestatus = utils.livestatus(request)
    fields = "name childs state scheduled_downtime_depth address last_check last_state_change acknowledged downtimes services services_with_info".split()
    hosts = utils.get_hosts(request, 'Filter: childs !=', fields=fields, **request.GET)
    host_dict = {}
    map(lambda x: host_dict.__setitem__(x['name'], x), hosts)
    c['hosts'] = []

    for i in hosts:
        if i['childs']:

            c['hosts'].append(i)
            ok = 0
            crit = 0
            i['child_hosts'] = []
            for x in i['childs']:
                i['child_hosts'].append(host_dict[x])
                if host_dict[x]['state'] == 0:
                    ok += 1
                else:
                    crit += 1
            total = float(len(i['childs']))
            i['health'] = float(ok) / total * 100.0
            i['percent_ok'] = ok / total * 100
            i['percent_crit'] = crit / total * 100

    return render_to_response('status_parents.html', c, context_instance=RequestContext(request))
Esempio n. 3
0
def network_parents(request):
    """ List of hosts that are network parents """
    c = {}
    c['messages'] = []
    authuser = request.GET.get('contact_name', None)
    livestatus = utils.livestatus(request)
    fields = "name childs state scheduled_downtime_depth address last_check last_state_change acknowledged downtimes services services_with_info".split()
    hosts = utils.get_hosts(request, 'Filter: childs !=', fields=fields, **request.GET)
    host_dict = {}
    map(lambda x: host_dict.__setitem__(x['name'], x), hosts)
    c['hosts'] = []

    for i in hosts:
        if i['childs']:

            c['hosts'].append(i)
            ok = 0
            crit = 0
            i['child_hosts'] = []
            for x in i['childs']:
                i['child_hosts'].append(host_dict[x])
                if host_dict[x]['state'] == 0:
                    ok += 1
                else:
                    crit += 1
            total = float(len(i['childs']))
            i['health'] = float(ok) / total * 100.0
            i['percent_ok'] = ok / total * 100
            i['percent_crit'] = crit / total * 100

    return render_to_response('status_parents.html', c, context_instance=RequestContext(request))
Esempio n. 4
0
def status_parents(request):
    c = {}
    c['messages'] = []
    authuser = request.GET.get('contact_name', None)
    livestatus = utils.livestatus(request)
    all_hosts = livestatus.get_hosts()
    host_dict = {}
    map(lambda x: host_dict.__setitem__(x['name'], x), all_hosts)
    c['hosts'] = []

    for i in all_hosts:
        if len(i['childs']) > 0:
            c['hosts'].append(i)
            ok = 0
            crit = 0
            i['child_hosts'] = []
            for x in i['childs']:
                i['child_hosts'].append(host_dict[x])
                if host_dict[x]['state'] == 0:
                    ok += 1
                else:
                    crit += 1
            total = float(len(i['childs']))
            i['health'] = float(ok) / total * 100.0
            i['percent_ok'] = ok / total * 100
            i['percent_crit'] = crit / total * 100

    return render_to_response('status_parents.html', c, context_instance=RequestContext(request))
Esempio n. 5
0
def custom_view(request, viewname):
    c = {}
    c['messages'] = []
    c['errors'] = []


    # View management
    user = userdata.User(request)
    c['viewname'] = viewname
    if not user.views:
        user.views = {}
        user.save()
        raise Http404(_("You don't have any view defined."))
    if viewname not in user.views.keys():
        raise Http404(_("This view doesn't exist."))
    view = user.views[viewname]

    # Data pre-processing
    livestatus = utils.livestatus(request)
    livestatus_query = custom_utils.data_to_query(view)

    # Query execution
    try:
        # the split is a workaround for pynag and the 'Stats:' clause
        c['data'] = livestatus.query(*livestatus_query.split('\n'))
    except Exception as e:
        # Any exception in livestatus query here is a critical error
        error = _('Error in LiveStatus query')
        c['errors'].append(error)
        c['errors'].append(e.message)
        return error_page(request, c)

    # Data post-processing
    # sorting
    c['data'] = sorted(c['data'],
                       key=functools.partial(custom_utils.sort_data,
                                             sorts=view['sorts']))
    
    # Moaaaar data for our templates
    c['view'] = view

    # For the template 'table.html' (and whynot others), determine if displaying
    # action_buttons is relevant, i.e. if we have results with at least
    # host_name and service_description.
    columns = set()
    for col in view['columns']: # no set comprehension in 2.6 :(
        columns.add(col['name'])

    if 'host_name' in columns and 'description' in columns:
        c['action_buttons'] = True
    else:
        c['action_buttons'] = False

    template = view['metadata'][0].get('template', 'table.html')

    return render_to_response(adagios.settings.CUSTOM_TEMPLATES_DIR + template, c,
                              context_instance=RequestContext(request))
Esempio n. 6
0
def status_servicegroups(request):
    c = {}
    c['messages'] = []
    c['errors'] = []
    servicegroup_name = None
    livestatus = utils.livestatus(request)
    servicegroups = livestatus.get_servicegroups()
    c['servicegroup_name'] = servicegroup_name
    c['request'] = request
    c['servicegroups'] = servicegroups
    return render_to_response('status_servicegroups.html', c, context_instance=RequestContext(request))
Esempio n. 7
0
def status_servicegroups(request):
    c = {}
    c['messages'] = []
    c['errors'] = []
    servicegroup_name = None
    livestatus = utils.livestatus(request)
    servicegroups = livestatus.get_servicegroups()
    c['servicegroup_name'] = servicegroup_name
    c['request'] = request
    c['servicegroups'] = servicegroups
    return render_to_response('status_servicegroups.html', c, context_instance=RequestContext(request))
Esempio n. 8
0
def custom_view(request, viewname):
    c = {}
    c['messages'] = []
    c['errors'] = []


    # View management
    user = userdata.User(request)
    c['viewname'] = viewname
    if not user.views:
        user.views = {}
        user.save()
        raise Http404(_("You don't have any view defined."))
    if viewname not in user.views.keys():
        raise Http404(_("This view doesn't exist."))
    view = user.views[viewname]

    # Data pre-processing
    livestatus = utils.livestatus(request)
    livestatus_query = custom_utils.data_to_query(view)

    # Query execution
    try:
        # the split is a workaround for pynag and the 'Stats:' clause
        c['data'] = livestatus.query(*livestatus_query.split('\n'))
    except Exception as e:
        # Any exception in livestatus query here is a critical error
        error = _('Error in LiveStatus query')
        c['errors'].append(error)
        c['errors'].append(e.message)
        return error_page(request, c)

    # Data post-processing
    # sorting
    c['data'] = sorted(c['data'],
                       key=functools.partial(custom_utils.sort_data,
                                             sorts=view['sorts']))
    
    # Moaaaar data for our templates
    c['view'] = view

    template = view['metadata'][0].get('template', 'table.html')

    return render_to_response(adagios.settings.CUSTOM_TEMPLATES_DIR + template, c,
                              context_instance=RequestContext(request))
Esempio n. 9
0
def get_data():
    """
    Queries Livestatus to get the list of all available columns.
    Loops on the backends until one works.
    """
    backends = utils.get_all_backends()
    livestatus = utils.livestatus(None)
    query = 'GET columns'
    # we try every backend until one works properly
    # otherwise columns appear multiple times, coming from multiple backends
    # this is faster than using set() afterwards
    res = None
    for backend in backends:
        try:
            res = livestatus.query(query, backend=backend)
            break
        except:
            continue
    if not res:
        raise Exception('No working backend found.')
    return res
Esempio n. 10
0
def get_data():
    """
    Queries Livestatus to get the list of all available columns.
    Loops on the backends until one works.
    """
    backends = utils.get_all_backends()
    livestatus = utils.livestatus(None)
    query = 'GET columns'
    # we try every backend until one works properly
    # otherwise columns appear multiple times, coming from multiple backends
    # this is faster than using set() afterwards
    res = None
    for backend in backends:
        try:
            res = livestatus.query(query, backend=backend)
            break
        except:
            continue
    if not res:
        raise Exception('No working backend found.')
    return res
Esempio n. 11
0
def status_hostgroups(request):
    c = {}
    c['messages'] = []
    c['errors'] = []
    hostgroup_name = None
    livestatus = utils.livestatus(request)
    hostgroups = livestatus.get_hostgroups()
    c['hostgroup_name'] = hostgroup_name
    c['request'] = request

    # Lets establish a good list of all hostgroups and parentgroups
    all_hostgroups = pynag.Model.Hostgroup.objects.all
    all_subgroups = set()  # all hostgroups that belong in some other hostgroup
    # "subgroup":['master1','master2']
    hostgroup_parentgroups = defaultdict(set)
    hostgroup_childgroups = pynag.Model.ObjectRelations.hostgroup_hostgroups

    for hostgroup, subgroups in hostgroup_childgroups.items():
        map(lambda x: hostgroup_parentgroups[x].add(hostgroup), subgroups)

    for i in hostgroups:
        i['child_hostgroups'] = hostgroup_childgroups[i['name']]
        i['parent_hostgroups'] = hostgroup_parentgroups[i['name']]

    if hostgroup_name is None:
        # If no hostgroup was specified. Lets only show "root hostgroups"
        c['hosts'] = livestatus.get_hosts()
        my_hostgroups = []
        for i in hostgroups:
            if len(i['parent_hostgroups']) == 0:
                my_hostgroups.append(i)
        my_hostgroups.sort()
        c['hostgroups'] = my_hostgroups

    else:
        my_hostgroup = pynag.Model.Hostgroup.objects.get_by_shortname(
            hostgroup_name)
        subgroups = my_hostgroup.hostgroup_members or ''
        subgroups = subgroups.split(',')
        # Strip out any group that is not a subgroup of hostgroup_name
        right_hostgroups = []
        for group in hostgroups:
            if group.get('name', '') in subgroups:
                right_hostgroups.append(group)
        c['hostgroups'] = right_hostgroups

        # If a hostgroup was specified lets also get all the hosts for it
        c['hosts'] = livestatus.query(
            'GET hosts', 'Filter: host_groups >= %s' % hostgroup_name)
    for host in c['hosts']:
        ok = host.get('num_services_ok')
        warn = host.get('num_services_warn')
        crit = host.get('num_services_crit')
        pending = host.get('num_services_pending')
        unknown = host.get('num_services_unknown')
        total = ok + warn + crit + pending + unknown
        host['total'] = total
        host['problems'] = warn + crit + unknown
        try:
            total = float(total)
            host['health'] = float(ok) / total * 100.0
            host['percent_ok'] = ok / total * 100
            host['percent_warn'] = warn / total * 100
            host['percent_crit'] = crit / total * 100
            host['percent_unknown'] = unknown / total * 100
            host['percent_pending'] = pending / total * 100
        except ZeroDivisionError:
            host['health'] = 'n/a'
    # Extra statistics for our hostgroups
    for hg in c['hostgroups']:
        ok = hg.get('num_services_ok')
        warn = hg.get('num_services_warn')
        crit = hg.get('num_services_crit')
        pending = hg.get('num_services_pending')
        unknown = hg.get('num_services_unknown')
        total = ok + warn + crit + pending + unknown
        hg['total'] = total
        hg['problems'] = warn + crit + unknown
        try:
            total = float(total)
            hg['health'] = float(ok) / total * 100.0
            hg['health'] = float(ok) / total * 100.0
            hg['percent_ok'] = ok / total * 100
            hg['percent_warn'] = warn / total * 100
            hg['percent_crit'] = crit / total * 100
            hg['percent_unknown'] = unknown / total * 100
            hg['percent_pending'] = pending / total * 100
        except ZeroDivisionError:
            pass
    return render_to_response('status_hostgroups.html', c, context_instance=RequestContext(request))
Esempio n. 12
0
def service_detail(request, host_name, service_description):
    """ Displays status details for one host or service """
    c = {}
    c['messages'] = []
    c['errors'] = []

    livestatus = utils.livestatus(request)
    backend = request.GET.get('backend')
    c['pnp_url'] = adagios.settings.pnp_url
    c['nagios_url'] = adagios.settings.nagios_url
    c['request'] = request
    now = time.time()
    seconds_in_a_day = 60 * 60 * 24
    seconds_passed_today = now % seconds_in_a_day
    today = now - seconds_passed_today  # midnight of today

    try:
        c['host'] = my_host = livestatus.get_host(host_name, backend)
        my_host['object_type'] = 'host'
        my_host['short_name'] = my_host['name']
    except IndexError:
        c['errors'].append(_("Could not find any host named '%s'") % host_name)
        return error_page(request, c)

    if service_description is None:
        tmp = request.GET.get('service_description')
        if tmp is not None:
            return service_detail(request, host_name, service_description=tmp)
        primary_object = my_host
        c['service_description'] = '_HOST_'
        #c['log'] = pynag.Parsers.LogFiles(maincfg=adagios.settings.nagios_config).get_state_history(
        #    host_name=host_name, service_description=None)
    else:
        try:
            c['service'] = my_service = livestatus.get_service(
                host_name, service_description, backend=backend)
            my_service['object_type'] = 'service'
            c['service_description'] = service_description
            my_service['short_name'] = "%s/%s" % (
                my_service['host_name'], my_service['description'])
            primary_object = my_service
            #c['log'] = pynag.Parsers.LogFiles(maincfg=adagios.settings.nagios_config).get_state_history(
            #    host_name=host_name, service_description=service_description)
        except IndexError:
            c['errors'].append(
                _("Could not find any service named '%s'") % service_description)
            return error_page(request, c)

    c['my_object'] = primary_object
    c['object_type'] = primary_object['object_type']

    # Friendly statusname (i.e. turn 2 into "critical")
    primary_object['status'] = state[primary_object['state']]

    # Plugin longoutput comes to us with special characters escaped. lets undo
    # that:
    primary_object['long_plugin_output'] = primary_object[
        'long_plugin_output'].replace('\\n', '\n')

    # Service list on the sidebar should be sorted
    my_host['services_with_info'] = sorted(
        my_host.get('services_with_info', []))
    c['host_name'] = host_name

    perfdata = primary_object['perf_data']
    perfdata = pynag.Utils.PerfData(perfdata)
    for i, datum in enumerate(perfdata.metrics):
        datum.i = i
        try:
            datum.status = state[datum.get_status()]
        except pynag.Utils.PynagError:
            datum.status = state[3]
    c['perfdata'] = perfdata.metrics
    
    # Get a complete list of network parents
    try:
        c['network_parents'] = reversed(_get_network_parents(request, host_name))
    except Exception, e:
        c['errors'].append(e)
Esempio n. 13
0
def status_hostgroups(request):
    c = {}
    c['messages'] = []
    c['errors'] = []
    hostgroup_name = None
    livestatus = utils.livestatus(request)
    hostgroups = livestatus.get_hostgroups()
    c['hostgroup_name'] = hostgroup_name
    c['request'] = request

    # Lets establish a good list of all hostgroups and parentgroups
    all_hostgroups = pynag.Model.Hostgroup.objects.all
    all_subgroups = set()  # all hostgroups that belong in some other hostgroup
    # "subgroup":['master1','master2']
    hostgroup_parentgroups = defaultdict(set)
    hostgroup_childgroups = pynag.Model.ObjectRelations.hostgroup_hostgroups

    for hostgroup, subgroups in list(hostgroup_childgroups.items()):
        list(map(lambda x: hostgroup_parentgroups[x].add(hostgroup),
                 subgroups))

    for i in hostgroups:
        i['child_hostgroups'] = hostgroup_childgroups[i['name']]
        i['parent_hostgroups'] = hostgroup_parentgroups[i['name']]

    if hostgroup_name is None:
        # If no hostgroup was specified. Lets only show "root hostgroups"
        c['hosts'] = livestatus.get_hosts()
        my_hostgroups = []
        for i in hostgroups:
            if len(i['parent_hostgroups']) == 0:
                my_hostgroups.append(i)
        my_hostgroups.sort()
        c['hostgroups'] = my_hostgroups

    else:
        my_hostgroup = pynag.Model.Hostgroup.objects.get_by_shortname(
            hostgroup_name)
        subgroups = my_hostgroup.hostgroup_members or ''
        subgroups = subgroups.split(',')
        # Strip out any group that is not a subgroup of hostgroup_name
        right_hostgroups = []
        for group in hostgroups:
            if group.get('name', '') in subgroups:
                right_hostgroups.append(group)
        c['hostgroups'] = right_hostgroups

        # If a hostgroup was specified lets also get all the hosts for it
        c['hosts'] = livestatus.query(
            'GET hosts', 'Filter: host_groups >= %s' % hostgroup_name)
    for host in c['hosts']:
        ok = host.get('num_services_ok')
        warn = host.get('num_services_warn')
        crit = host.get('num_services_crit')
        pending = host.get('num_services_pending')
        unknown = host.get('num_services_unknown')
        total = ok + warn + crit + pending + unknown
        host['total'] = total
        host['problems'] = warn + crit + unknown
        try:
            total = float(total)
            host['health'] = float(ok) / total * 100.0
            host['percent_ok'] = ok / total * 100
            host['percent_warn'] = warn / total * 100
            host['percent_crit'] = crit / total * 100
            host['percent_unknown'] = unknown / total * 100
            host['percent_pending'] = pending / total * 100
        except ZeroDivisionError:
            host['health'] = 'n/a'
    # Extra statistics for our hostgroups
    for hg in c['hostgroups']:
        ok = hg.get('num_services_ok')
        warn = hg.get('num_services_warn')
        crit = hg.get('num_services_crit')
        pending = hg.get('num_services_pending')
        unknown = hg.get('num_services_unknown')
        total = ok + warn + crit + pending + unknown
        hg['total'] = total
        hg['problems'] = warn + crit + unknown
        try:
            total = float(total)
            hg['health'] = float(ok) / total * 100.0
            hg['health'] = float(ok) / total * 100.0
            hg['percent_ok'] = ok / total * 100
            hg['percent_warn'] = warn / total * 100
            hg['percent_crit'] = crit / total * 100
            hg['percent_unknown'] = unknown / total * 100
            hg['percent_pending'] = pending / total * 100
        except ZeroDivisionError:
            pass
    return render_to_response('status_hostgroups.html',
                              c,
                              context_instance=RequestContext(request))
Esempio n. 14
0
def service_detail(request, host_name, service_description):
    """ Displays status details for one host or service """
    c = {}
    c['messages'] = []
    c['errors'] = []

    livestatus = utils.livestatus(request)
    backend = request.GET.get('backend')
    c['pnp_url'] = adagios.settings.pnp_url
    c['nagios_url'] = adagios.settings.nagios_url
    c['request'] = request
    now = time.time()
    seconds_in_a_day = 60 * 60 * 24
    seconds_passed_today = now % seconds_in_a_day
    today = now - seconds_passed_today  # midnight of today

    try:
        c['host'] = my_host = livestatus.get_host(host_name, backend)
        my_host['object_type'] = 'host'
        my_host['short_name'] = my_host['name']
    except IndexError:
        c['errors'].append(_("Could not find any host named '%s'") % host_name)
        return error_page(request, c)

    if service_description is None:
        tmp = request.GET.get('service_description')
        if tmp is not None:
            return service_detail(request, host_name, service_description=tmp)
        primary_object = my_host
        c['service_description'] = '_HOST_'
    else:
        try:
            c['service'] = my_service = livestatus.get_service(
                host_name, service_description, backend=backend)
            my_service['object_type'] = 'service'
            c['service_description'] = service_description
            my_service['short_name'] = "%s/%s" % (my_service['host_name'],
                                                  my_service['description'])
            primary_object = my_service
        except IndexError:
            c['errors'].append(
                _("Could not find any service named '%s'") %
                service_description)
            return error_page(request, c)

    c['my_object'] = primary_object
    c['object_type'] = primary_object['object_type']

    # Friendly statusname (i.e. turn 2 into "critical")
    primary_object['status'] = state[primary_object['state']]

    # Plugin longoutput comes to us with special characters escaped. lets undo
    # that:
    primary_object['long_plugin_output'] = primary_object[
        'long_plugin_output'].replace('\\n', '\n')

    # Service list on the sidebar should be sorted
    my_host['services_with_info'] = sorted(
        my_host.get('services_with_info', []))
    c['host_name'] = host_name

    perfdata = primary_object['perf_data']
    perfdata = pynag.Utils.PerfData(perfdata)
    for i, datum in enumerate(perfdata.metrics):
        datum.i = i
        try:
            datum.status = state[datum.get_status()]
        except pynag.Utils.PynagError:
            datum.status = state[3]
    c['perfdata'] = perfdata.metrics

    # Get a complete list of network parents
    try:
        c['network_parents'] = reversed(
            _get_network_parents(request, host_name))
    except Exception as e:
        c['errors'].append(e)

    # Lets get some graphs
    if adagios.settings.enable_pnp4nagios:
        try:
            tmp = run_pnp("json", host=host_name)
            tmp = json.loads(tmp)
        except Exception as e:
            tmp = []
            c['pnp4nagios_error'] = e
        c['graph_urls'] = tmp

    if adagios.settings.enable_graphite:
        metrics = [x.label for x in perfdata.metrics]
        service = c['service_description'].replace(' ', '_')
        c['graphite'] = graphite.get(
            adagios.settings.graphite_url,
            c['host_name'],
            service,
            metrics,
            adagios.settings.GRAPHITE_PERIODS,
        )
        # used in the General tab - preview
        for graph in c['graphite']:
            if graph['css_id'] == adagios.settings.GRAPHITE_DEFAULT_TAB:
                default = {}
                for k, v in list(graph['metrics'].items()):
                    default[k] = v
                c['graphite_default'] = default

    return render_to_response('status_detail.html',
                              c,
                              context_instance=RequestContext(request))
Esempio n. 15
0
def status_detail(request, host_name=None, service_description=None):
    """ Displays status details for one host or service """
    c = {}
    c['messages'] = []
    c['errors'] = []

    host_name = request.GET.get('host_name')
    service_description = request.GET.get('service_description')
    livestatus = utils.livestatus(request)
    c['pnp_url'] = adagios.settings.pnp_url
    c['nagios_url'] = adagios.settings.nagios_url
    c['request'] = request
    now = time.time()
    seconds_in_a_day = 60 * 60 * 24
    seconds_passed_today = now % seconds_in_a_day
    today = now - seconds_passed_today  # midnight of today

    try:
        c['host'] = my_host = livestatus.get_host(host_name)
        my_host['object_type'] = 'host'
        my_host['short_name'] = my_host['name']
    except IndexError:
        c['errors'].append("Could not find any host named '%s'" % host_name)
        return error_page(request, c)

    if service_description is None:
        tmp = request.GET.get('service_description')
        if tmp is not None:
            return status_detail(request, host_name, service_description=tmp)
        primary_object = my_host
        c['service_description'] = '_HOST_'
        c['log'] = pynag.Parsers.LogFiles(maincfg=adagios.settings.nagios_config).get_state_history(
            host_name=host_name, service_description=None)

    else:
        try:
            c['service'] = my_service = livestatus.get_service(
                host_name, service_description)
            my_service['object_type'] = 'service'
            c['service_description'] = service_description
            my_service['short_name'] = "%s/%s" % (
                my_service['host_name'], my_service['description'])
            primary_object = my_service
            c['log'] = pynag.Parsers.LogFiles(maincfg=adagios.settings.nagios_config).get_state_history(
                host_name=host_name, service_description=service_description)
        except IndexError:
            c['errors'].append(
                "Could not find any service named '%s'" % service_description)
            return error_page(request, c)

    c['my_object'] = primary_object
    c['object_type'] = primary_object['object_type']

    # Friendly statusname (i.e. turn 2 into "critical")
    primary_object['status'] = state[primary_object['state']]

    # Plugin longoutput comes to us with special characters escaped. lets undo
    # that:
    primary_object['long_plugin_output'] = primary_object[
        'long_plugin_output'].replace('\\n', '\n')

    # Service list on the sidebar should be sorted
    my_host['services_with_info'] = sorted(
        my_host.get('services_with_info', []))
    c['host_name'] = host_name

    perfdata = primary_object['perf_data']
    perfdata = pynag.Utils.PerfData(perfdata)
    for i, datum in enumerate(perfdata.metrics):
        datum.i = i
        try:
            datum.status = state[datum.get_status()]
        except pynag.Utils.PynagError:
            datum.status = state[3]
    c['perfdata'] = perfdata.metrics

    # Get a complete list of network parents
    try:
        c['network_parents'] = reversed(_get_network_parents(host_name))
    except Exception, e:
        c['errors'].append(e)