Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / controllers / plugins / details.py @ 73119f8a

History | View | Annotate | Download (7.08 KB)

1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4:
3
################################################################################
4
#
5
# Copyright (C) 2007-2013 CS-SI
6
#
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License version 2 as
9
# published by the Free Software Foundation.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
################################################################################
20

    
21
"""
22
Un plugin pour VigiBoard qui ajoute une colonne avec les liens vers les
23
entrées d'historiques liées à l'événement, ainsi que les liens vers les
24
applications externes.
25
"""
26

    
27
import urllib
28
from tg import config, url, request
29
from sqlalchemy.sql.expression import null as expr_null, union_all
30
from sqlalchemy import func
31

    
32
from repoze.what.predicates import has_permission, in_group
33
from vigilo.turbogears.helpers import get_current_user
34

    
35
from vigilo.models.session import DBSession
36
from vigilo.models.tables import Event, CorrEvent, Host, LowLevelService, \
37
    StateName, Map, MapNode, MapNodeHost, MapGroup
38
from vigilo.models.tables.secondary_tables import MAP_GROUP_TABLE
39

    
40
from vigiboard.controllers.plugins import VigiboardRequestPlugin
41

    
42
class PluginDetails(VigiboardRequestPlugin):
43
    """
44
    Plugin qui ajoute des liens vers les historiques et les applications
45
    externes.
46
    """
47

    
48
    def get_json_data(self, idcorrevent, *args, **kwargs):
49
        """
50
        Renvoie les éléments pour l'affichage de la fenêtre de dialogue
51
        contenant des détails sur un événement corrélé.
52

53
        @param idcorrevent: identifiant de l'événement corrélé.
54
        @type idcorrevent: C{int}
55
        """
56

    
57
        # Obtention de données sur l'événement et sur son historique
58
        host_query = DBSession.query(
59
            Host.idhost.label("idsupitem"),
60
            Host.idhost.label("idhost"),
61
            Host.name.label("host"),
62
            expr_null().label("service"),
63
        )
64
        lls_query = DBSession.query(
65
            LowLevelService.idservice.label("idsupitem"),
66
            Host.idhost.label("idhost"),
67
            Host.name.label("host"),
68
            LowLevelService.servicename.label("service"),
69
        ).join(
70
            (Host, Host.idhost == LowLevelService.idhost),
71
        )
72
        supitems = union_all(lls_query, host_query, correlate=False).alias()
73
        event = DBSession.query(
74
            CorrEvent.idcorrevent,
75
            CorrEvent.idcause,
76
            supitems.c.idhost,
77
            supitems.c.host,
78
            supitems.c.service,
79
            Event.message,
80
            Event.initial_state,
81
            Event.current_state,
82
            Event.peak_state
83
        ).join(
84
            (Event, Event.idevent == CorrEvent.idcause),
85
            (supitems, supitems.c.idsupitem == Event.idsupitem),
86
        ).filter(CorrEvent.idcorrevent == idcorrevent
87
        ).first()
88

    
89
        # On détermine les cartes auxquelles cet utilisateur a accès.
90
        user_maps = []
91
        max_maps = int(config['max_maps'])
92
        is_manager = config.is_manager.is_met(request.environ)
93
        if max_maps != 0 and (is_manager or
94
            has_permission('vigimap-access').is_met(request.environ)):
95
            items = DBSession.query(
96
                    Map.idmap,
97
                    Map.title,
98
                    func.lower(Map.title),
99
                ).distinct(
100
                ).join(
101
                    (MAP_GROUP_TABLE, MAP_GROUP_TABLE.c.idmap == Map.idmap),
102
                    (MapGroup, MapGroup.idgroup == MAP_GROUP_TABLE.c.idgroup),
103
                    (MapNodeHost, MapNodeHost.idmap == Map.idmap),
104
                ).order_by(func.lower(Map.title).asc()
105
                ).filter(MapNodeHost.idhost == event.idhost)
106

    
107
            if not is_manager:
108
                mapgroups = get_current_user().mapgroups(only_direct=True)
109
                # pylint: disable-msg=E1103
110
                items = items.filter(MapGroup.idgroup.in_(mapgroups))
111

    
112
            # La valeur -1 supprime la limite.
113
            if max_maps > 0:
114
                # On limite au nombre maximum de cartes demandés + 1.
115
                # Un message sera affiché s'il y a effectivement plus
116
                # de cartes que la limite configurée.
117
                items = items.limit(max_maps + 1)
118

    
119
            user_maps = [(m.idmap, m.title) for m in items.all()]
120

    
121
        context = {
122
            'idcorrevent': idcorrevent,
123
            'host': event.host,
124
            'service': event.service,
125
            'message': event.message,
126
            'maps': user_maps,
127
            'current_state': StateName.value_to_statename(event.current_state),
128
            'initial_state': StateName.value_to_statename(event.initial_state),
129
            'peak_state': StateName.value_to_statename(event.peak_state),
130
        }
131

    
132
        eventdetails = {}
133
        for edname, edlink in enumerate(config['vigiboard_links.eventdetails']):
134
            # Évite que les gardes ne se polluent entre elles.
135
            local_ctx = context.copy()
136

    
137
            # Les liens peuvent être conditionnés à l'aide
138
            # d'une expression ou d'un callable qui agira
139
            # comme un prédicat de test.
140
            if 'only_if' in edlink:
141
                if callable(edlink['only_if']):
142
                    display_link = edlink['only_if'](local_ctx)
143
                else:
144
                    display_link = edlink['only_if']
145
                if not display_link:
146
                    continue
147

    
148
            if callable(edlink['uri']):
149
                uri = edlink['uri'](local_ctx)
150
            else:
151
                uri = edlink['uri'] % local_ctx
152

    
153
            eventdetails[unicode(edname)] = {
154
                'url': url(uri),
155
                'target': edlink.get('target', '_blank')
156
            }
157

    
158
        return dict(
159
                current_state = StateName.value_to_statename(
160
                                    event.current_state),
161
                initial_state = StateName.value_to_statename(
162
                                    event.initial_state),
163
                peak_state = StateName.value_to_statename(
164
                                    event.peak_state),
165
                idcorrevent = idcorrevent,
166
                host = event.host,
167
                service = event.service,
168
                eventdetails = eventdetails,
169
                maps = user_maps,
170
                idcause = event.idcause,
171
            )
172

    
173
    def get_data(self, event):
174
        state = StateName.value_to_statename(event[0].cause.current_state)
175
        peak_state = StateName.value_to_statename(event[0].cause.peak_state)
176
        init_state = StateName.value_to_statename(event[0].cause.initial_state)
177
        return {
178
            'state': state,
179
            'peak_state': peak_state,
180
            'initial_state': init_state,
181
            'id': event[0].idcorrevent,
182
        }