vigiboard / vigiboard / controllers / plugins / details.py @ 8c198622
History | View | Annotate | Download (8.02 KB)
1 |
# -*- coding: utf-8 -*-
|
---|---|
2 |
# vim:set expandtab tabstop=4 shiftwidth=4:
|
3 |
# Copyright (C) 2007-2019 CS-SI
|
4 |
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html>
|
5 |
|
6 |
"""
|
7 |
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 |
"""
|
11 |
|
12 |
import urllib |
13 |
from tg import config, url, request |
14 |
from tg.i18n import lazy_ugettext as l_ |
15 |
import tw.forms as twf |
16 |
from sqlalchemy.sql.expression import null as expr_null, union_all |
17 |
from sqlalchemy import func |
18 |
|
19 |
from tg.predicates import has_permission, in_group |
20 |
from vigilo.turbogears.helpers import get_current_user |
21 |
|
22 |
from vigilo.models.session import DBSession |
23 |
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 |
|
27 |
from vigiboard.controllers.plugins import VigiboardRequestPlugin, ITEMS |
28 |
|
29 |
|
30 |
class PluginDetails(VigiboardRequestPlugin): |
31 |
"""
|
32 |
Plugin qui ajoute des liens vers les historiques et les applications
|
33 |
externes.
|
34 |
"""
|
35 |
|
36 |
def get_json_data(self, idcorrevent, *args, **kwargs): |
37 |
"""
|
38 |
Renvoie les éléments pour l'affichage de la fenêtre de dialogue
|
39 |
contenant des détails sur un événement corrélé.
|
40 |
|
41 |
@param idcorrevent: identifiant de l'événement corrélé.
|
42 |
@type idcorrevent: C{int}
|
43 |
"""
|
44 |
|
45 |
# Obtention de données sur l'événement et sur son historique
|
46 |
host_query = DBSession.query( |
47 |
Host.idhost.label("idsupitem"),
|
48 |
Host.idhost.label("idhost"),
|
49 |
Host.name.label("host"),
|
50 |
expr_null().label("service"),
|
51 |
) |
52 |
lls_query = DBSession.query( |
53 |
LowLevelService.idservice.label("idsupitem"),
|
54 |
Host.idhost.label("idhost"),
|
55 |
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 |
supitems.c.idhost, |
65 |
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 |
|
77 |
# On détermine les cartes auxquelles cet utilisateur a accès.
|
78 |
user_maps = [] |
79 |
max_maps = int(config['max_maps']) |
80 |
is_manager = config.is_manager.is_met(request.environ) |
81 |
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 |
).order_by(func.lower(Map.title).asc() |
91 |
).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 |
items = items.filter(MAP_GROUP_TABLE.c.idgroup.in_(mapgroups)) |
97 |
|
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 |
user_maps = [(m.idmap, m.title) for m in items.all()] |
106 |
|
107 |
context = { |
108 |
'idcorrevent': idcorrevent,
|
109 |
'host': event.host,
|
110 |
'service': event.service,
|
111 |
'message': event.message,
|
112 |
'maps': user_maps,
|
113 |
'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 |
} |
117 |
|
118 |
eventdetails = {} |
119 |
for edname, edlink in enumerate(config['vigiboard_links.eventdetails']): |
120 |
# Évite que les gardes ne se polluent entre elles.
|
121 |
local_ctx = context.copy() |
122 |
|
123 |
# 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 |
|
134 |
if callable(edlink['uri']): |
135 |
uri = edlink['uri'](local_ctx)
|
136 |
else:
|
137 |
uri = edlink['uri'] % local_ctx
|
138 |
|
139 |
eventdetails[unicode(edname)] = {
|
140 |
'url': url(uri),
|
141 |
'target': edlink.get('target', '_blank') |
142 |
} |
143 |
|
144 |
return dict( |
145 |
current_state = StateName.value_to_statename( |
146 |
event.current_state), |
147 |
initial_state = StateName.value_to_statename( |
148 |
event.initial_state), |
149 |
peak_state = StateName.value_to_statename( |
150 |
event.peak_state), |
151 |
idcorrevent = idcorrevent, |
152 |
host = event.host, |
153 |
service = event.service, |
154 |
eventdetails = eventdetails, |
155 |
maps = user_maps, |
156 |
idcause = event.idcause, |
157 |
) |
158 |
|
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 |
|
170 |
def get_search_fields(self): |
171 |
states = DBSession.query(StateName.idstatename, StateName.statename |
172 |
).order_by(StateName.order.asc()).all() |
173 |
# 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 |
return [
|
186 |
twf.MultipleSelectField( |
187 |
'state',
|
188 |
label_text=l_('Current state'),
|
189 |
options=options, |
190 |
validator=twf.validators.OneOf( |
191 |
valid, |
192 |
if_invalid=[], |
193 |
if_missing=[], |
194 |
), |
195 |
), |
196 |
] |
197 |
|
198 |
def handle_search_fields(self, query, search, state, subqueries): |
199 |
if state != ITEMS:
|
200 |
return
|
201 |
|
202 |
states = [] |
203 |
for value in search.get('state', []): |
204 |
try:
|
205 |
states.append(int(value))
|
206 |
except (ValueError, TypeError): |
207 |
try:
|
208 |
states.append(StateName.statename_to_value(value)) |
209 |
except:
|
210 |
# On ignore silencieusement un critère de recherche erroné
|
211 |
pass
|
212 |
|
213 |
if states:
|
214 |
query.add_filter(Event.current_state.in_(states)) |
215 |
|
216 |
def get_sort_criterion(self, query, column): |
217 |
columns = { |
218 |
'details': StateName.order,
|
219 |
'problem': StateName.statename.in_([u'OK', u'UP']), |
220 |
} |
221 |
return columns.get(column)
|
222 |
|