Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / controllers / plugins / details.py @ 011743be

History | View | Annotate | Download (8.03 KB)

1 15b98053 Francois POIROTTE
# -*- coding: utf-8 -*-
2 4febadf0 Francois POIROTTE
# vim:set expandtab tabstop=4 shiftwidth=4:
3 011743be Francois POIROTTE
# Copyright (C) 2007-2020 CS GROUP - France
4 9b8d9497 Francois POIROTTE
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html>
5 a77de887 Francois POIROTTE
6 15b98053 Francois POIROTTE
"""
7 4febadf0 Francois POIROTTE
Un plugin pour VigiBoard qui ajoute une colonne avec les liens vers les
8
entrées d'historiques liées à l'événement, ainsi que les liens vers les
9
applications externes.
10 15b98053 Francois POIROTTE
"""
11
12
import urllib
13 dc005588 Francois POIROTTE
from tg import config, url, request
14 02c4a1e7 Francois POIROTTE
from tg.i18n import lazy_ugettext as l_
15 0921ffe3 Francois POIROTTE
import tw.forms as twf
16 03e5dc9e Vincent QUEMENER
from sqlalchemy.sql.expression import null as expr_null, union_all
17 a4ffe87d Francois POIROTTE
from sqlalchemy import func
18 03059edd Francois POIROTTE
19 02c4a1e7 Francois POIROTTE
from tg.predicates import has_permission, in_group
20 dc005588 Francois POIROTTE
from vigilo.turbogears.helpers import get_current_user
21
22 03e5dc9e Vincent QUEMENER
from vigilo.models.session import DBSession
23 dc005588 Francois POIROTTE
from vigilo.models.tables import Event, CorrEvent, Host, LowLevelService, \
24
    StateName, Map, MapNode, MapNodeHost, MapGroup
25
from vigilo.models.tables.secondary_tables import MAP_GROUP_TABLE
26 03e5dc9e Vincent QUEMENER
27 0921ffe3 Francois POIROTTE
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS
28
29 15b98053 Francois POIROTTE
30 94f31908 Francois POIROTTE
class PluginDetails(VigiboardRequestPlugin):
31 4febadf0 Francois POIROTTE
    """
32
    Plugin qui ajoute des liens vers les historiques et les applications
33
    externes.
34
    """
35
36 cf3c2494 Vincent QUEMENER
    def get_json_data(self, idcorrevent, *args, **kwargs):
37 15b98053 Francois POIROTTE
        """
38
        Renvoie les éléments pour l'affichage de la fenêtre de dialogue
39 94f31908 Francois POIROTTE
        contenant des détails sur un événement corrélé.
40 15b98053 Francois POIROTTE

41 94f31908 Francois POIROTTE
        @param idcorrevent: identifiant de l'événement corrélé.
42
        @type idcorrevent: C{int}
43 15b98053 Francois POIROTTE
        """
44
45
        # Obtention de données sur l'événement et sur son historique
46 03e5dc9e Vincent QUEMENER
        host_query = DBSession.query(
47
            Host.idhost.label("idsupitem"),
48 dc005588 Francois POIROTTE
            Host.idhost.label("idhost"),
49 03e5dc9e Vincent QUEMENER
            Host.name.label("host"),
50
            expr_null().label("service"),
51 15b98053 Francois POIROTTE
        )
52 03e5dc9e Vincent QUEMENER
        lls_query = DBSession.query(
53
            LowLevelService.idservice.label("idsupitem"),
54 dc005588 Francois POIROTTE
            Host.idhost.label("idhost"),
55 03e5dc9e Vincent QUEMENER
            Host.name.label("host"),
56
            LowLevelService.servicename.label("service"),
57
        ).join(
58
            (Host, Host.idhost == LowLevelService.idhost),
59
        )
60
        supitems = union_all(lls_query, host_query, correlate=False).alias()
61
        event = DBSession.query(
62
            CorrEvent.idcorrevent,
63
            CorrEvent.idcause,
64 dc005588 Francois POIROTTE
            supitems.c.idhost,
65 03e5dc9e Vincent QUEMENER
            supitems.c.host,
66
            supitems.c.service,
67
            Event.message,
68
            Event.initial_state,
69
            Event.current_state,
70
            Event.peak_state
71
        ).join(
72
            (Event, Event.idevent == CorrEvent.idcause),
73
            (supitems, supitems.c.idsupitem == Event.idsupitem),
74
        ).filter(CorrEvent.idcorrevent == idcorrevent
75
        ).first()
76 15b98053 Francois POIROTTE
77 dc005588 Francois POIROTTE
        # On détermine les cartes auxquelles cet utilisateur a accès.
78 a4ffe87d Francois POIROTTE
        user_maps = []
79 dc005588 Francois POIROTTE
        max_maps = int(config['max_maps'])
80 73119f8a Francois POIROTTE
        is_manager = config.is_manager.is_met(request.environ)
81 dc005588 Francois POIROTTE
        if max_maps != 0 and (is_manager or
82
            has_permission('vigimap-access').is_met(request.environ)):
83
            items = DBSession.query(
84
                    Map.idmap,
85
                    Map.title,
86
                ).distinct(
87
                ).join(
88
                    (MAP_GROUP_TABLE, MAP_GROUP_TABLE.c.idmap == Map.idmap),
89
                    (MapNodeHost, MapNodeHost.idmap == Map.idmap),
90 a4ffe87d Francois POIROTTE
                ).order_by(func.lower(Map.title).asc()
91 dc005588 Francois POIROTTE
                ).filter(MapNodeHost.idhost == event.idhost)
92
93
            if not is_manager:
94
                mapgroups = get_current_user().mapgroups(only_direct=True)
95
                # pylint: disable-msg=E1103
96 02c4a1e7 Francois POIROTTE
                items = items.filter(MAP_GROUP_TABLE.c.idgroup.in_(mapgroups))
97 dc005588 Francois POIROTTE
98
            # La valeur -1 supprime la limite.
99
            if max_maps > 0:
100
                # On limite au nombre maximum de cartes demandés + 1.
101
                # Un message sera affiché s'il y a effectivement plus
102
                # de cartes que la limite configurée.
103
                items = items.limit(max_maps + 1)
104
105 a4ffe87d Francois POIROTTE
            user_maps = [(m.idmap, m.title) for m in items.all()]
106 dc005588 Francois POIROTTE
107 147b6daa Francois POIROTTE
        context = {
108
            'idcorrevent': idcorrevent,
109
            'host': event.host,
110
            'service': event.service,
111
            'message': event.message,
112 dc005588 Francois POIROTTE
            'maps': user_maps,
113 5d0adb59 Francois POIROTTE
            'current_state': StateName.value_to_statename(event.current_state),
114
            'initial_state': StateName.value_to_statename(event.initial_state),
115
            'peak_state': StateName.value_to_statename(event.peak_state),
116 147b6daa Francois POIROTTE
        }
117
118 15b98053 Francois POIROTTE
        eventdetails = {}
119 65383903 Francois POIROTTE
        for edname, edlink in enumerate(config['vigiboard_links.eventdetails']):
120 147b6daa Francois POIROTTE
            # Évite que les gardes ne se polluent entre elles.
121
            local_ctx = context.copy()
122 15b98053 Francois POIROTTE
123 147b6daa Francois POIROTTE
            # Les liens peuvent être conditionnés à l'aide
124
            # d'une expression ou d'un callable qui agira
125
            # comme un prédicat de test.
126
            if 'only_if' in edlink:
127
                if callable(edlink['only_if']):
128
                    display_link = edlink['only_if'](local_ctx)
129
                else:
130
                    display_link = edlink['only_if']
131
                if not display_link:
132
                    continue
133 bcf87133 Francois POIROTTE
134 147b6daa Francois POIROTTE
            if callable(edlink['uri']):
135
                uri = edlink['uri'](local_ctx)
136 baf08f7e Francois POIROTTE
            else:
137 147b6daa Francois POIROTTE
                uri = edlink['uri'] % local_ctx
138 baf08f7e Francois POIROTTE
139
            eventdetails[unicode(edname)] = {
140 062a58e7 Francois POIROTTE
                'url': url(uri),
141 147b6daa Francois POIROTTE
                'target': edlink.get('target', '_blank')
142 15b98053 Francois POIROTTE
            }
143
144
        return dict(
145
                current_state = StateName.value_to_statename(
146 03e5dc9e Vincent QUEMENER
                                    event.current_state),
147 15b98053 Francois POIROTTE
                initial_state = StateName.value_to_statename(
148 03e5dc9e Vincent QUEMENER
                                    event.initial_state),
149 15b98053 Francois POIROTTE
                peak_state = StateName.value_to_statename(
150 03e5dc9e Vincent QUEMENER
                                    event.peak_state),
151 15b98053 Francois POIROTTE
                idcorrevent = idcorrevent,
152 03e5dc9e Vincent QUEMENER
                host = event.host,
153
                service = event.service,
154 15b98053 Francois POIROTTE
                eventdetails = eventdetails,
155 dc005588 Francois POIROTTE
                maps = user_maps,
156 03e5dc9e Vincent QUEMENER
                idcause = event.idcause,
157 15b98053 Francois POIROTTE
            )
158 a2fa6a5b Francois POIROTTE
159
    def get_data(self, event):
160
        state = StateName.value_to_statename(event[0].cause.current_state)
161
        peak_state = StateName.value_to_statename(event[0].cause.peak_state)
162
        init_state = StateName.value_to_statename(event[0].cause.initial_state)
163
        return {
164
            'state': state,
165
            'peak_state': peak_state,
166
            'initial_state': init_state,
167
            'id': event[0].idcorrevent,
168
        }
169 0921ffe3 Francois POIROTTE
170
    def get_search_fields(self):
171
        states = DBSession.query(StateName.idstatename, StateName.statename
172
                    ).order_by(StateName.order.asc()).all()
173 ecf084d9 Francois POIROTTE
        # Liste des valeurs acceptées pour la validation.
174
        valid = []
175
        # Liste des options présentes dans le champ de sélection.
176
        options = []
177
        for s in states:
178
            valid.extend([str(s.idstatename), s.statename])
179
            options.append( (
180
                str(s.idstatename),
181
                s.statename,
182
                {'title': l_(s.statename)}
183
            ) )
184
185 0921ffe3 Francois POIROTTE
        return [
186 ecf084d9 Francois POIROTTE
            twf.MultipleSelectField(
187 0921ffe3 Francois POIROTTE
                'state',
188
                label_text=l_('Current state'),
189
                options=options,
190
                validator=twf.validators.OneOf(
191 ecf084d9 Francois POIROTTE
                    valid,
192
                    if_invalid=[],
193
                    if_missing=[],
194 0921ffe3 Francois POIROTTE
                ),
195
            ),
196
        ]
197
198
    def handle_search_fields(self, query, search, state, subqueries):
199
        if state != ITEMS:
200
            return
201
202 ecf084d9 Francois POIROTTE
        states = []
203 02c4a1e7 Francois POIROTTE
        for value in search.get('state', []):
204 0921ffe3 Francois POIROTTE
            try:
205 ecf084d9 Francois POIROTTE
                states.append(int(value))
206 0921ffe3 Francois POIROTTE
            except (ValueError, TypeError):
207 ecf084d9 Francois POIROTTE
                try:
208
                    states.append(StateName.statename_to_value(value))
209
                except:
210 02c4a1e7 Francois POIROTTE
                    # On ignore silencieusement un critère de recherche erroné
211 ecf084d9 Francois POIROTTE
                    pass
212
213
        if states:
214
            query.add_filter(Event.current_state.in_(states))
215 0921ffe3 Francois POIROTTE
216
    def get_sort_criterion(self, query, column):
217 80fa03cd Francois POIROTTE
        columns = {
218
            'details': StateName.order,
219
            'problem': StateName.statename.in_([u'OK', u'UP']),
220
        }
221
        return columns.get(column)