vigiboard / vigiboard / controllers / root.py @ 858d88aa
History | View | Annotate | Download (22.8 KB)
1 | 19e88cb8 | Thomas ANDREJAK | # -*- coding: utf-8 -*-
|
---|---|---|---|
2 | # vim:set expandtab tabstop=4 shiftwidth=4:
|
||
3 | """Vigiboard Controller"""
|
||
4 | |||
5 | 7365fb51 | Francois POIROTTE | from datetime import datetime |
6 | from time import mktime |
||
7 | import math |
||
8 | import urllib |
||
9 | |||
10 | 4dd2035e | Francois POIROTTE | from tg.exceptions import HTTPNotFound |
11 | aa0788a2 | Francois POIROTTE | from tg import expose, validate, require, flash, \ |
12 | c1ce3d6a | Francois POIROTTE | tmpl_context, request, config, session, redirect, url |
13 | 3e6ee4db | Francois POIROTTE | from tw.forms import validators |
14 | 19e88cb8 | Thomas ANDREJAK | from pylons.i18n import ugettext as _ |
15 | ef31cc13 | Francois POIROTTE | from pylons.i18n import lazy_ugettext as l_ |
16 | aa0788a2 | Francois POIROTTE | from pylons.controllers.util import abort |
17 | 6ab72614 | Vincent QUEMENER | from sqlalchemy import asc |
18 | 97f6d842 | Vincent QUEMENER | from sqlalchemy.sql import func |
19 | 7365fb51 | Francois POIROTTE | from repoze.what.predicates import Any, not_anonymous |
20 | ee3ae8c8 | Francois POIROTTE | |
21 | 5dbfa80d | Francois POIROTTE | from vigilo.models.configure import DBSession |
22 | 7365fb51 | Francois POIROTTE | from vigilo.models import Event, EventHistory, CorrEvent, SupItem, \ |
23 | 6ab72614 | Vincent QUEMENER | HostGroup, ServiceGroup, StateName, User |
24 | 080abea3 | Francois POIROTTE | from vigilo.models.functions import sql_escape_like |
25 | 7365fb51 | Francois POIROTTE | |
26 | 4d783824 | Francois POIROTTE | from vigilo.turbogears.controllers.autocomplete \ |
27 | import make_autocomplete_controller |
||
28 | 7365fb51 | Francois POIROTTE | from vigiboard.controllers.vigiboardrequest import VigiboardRequest |
29 | from vigiboard.controllers.vigiboard_controller import VigiboardRootController |
||
30 | from vigiboard.widgets.edit_event import edit_event_status_options |
||
31 | 398c727b | Francois POIROTTE | from vigiboard.lib.base import BaseController |
32 | 19e88cb8 | Thomas ANDREJAK | |
33 | 97f6d842 | Vincent QUEMENER | __all__ = ('RootController', 'get_last_modification_timestamp', |
34 | 'date_to_timestamp')
|
||
35 | 19e88cb8 | Thomas ANDREJAK | |
36 | 4d783824 | Francois POIROTTE | # pylint: disable-msg=R0201
|
37 | b8500d1a | Thomas ANDREJAK | class RootController(VigiboardRootController): |
38 | 19e88cb8 | Thomas ANDREJAK | """
|
39 | Le controller général de vigiboard
|
||
40 | """
|
||
41 | 4d783824 | Francois POIROTTE | autocomplete = make_autocomplete_controller(BaseController) |
42 | ef31cc13 | Francois POIROTTE | |
43 | aa0788a2 | Francois POIROTTE | def process_form_errors(self, *argv, **kwargv): |
44 | 19e88cb8 | Thomas ANDREJAK | """
|
45 | Gestion des erreurs de validation : On affiche les erreurs
|
||
46 | puis on redirige vers la dernière page accédée.
|
||
47 | """
|
||
48 | aa0788a2 | Francois POIROTTE | for k in tmpl_context.form_errors: |
49 | flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error') |
||
50 | 19e88cb8 | Thomas ANDREJAK | if request.environ.get('HTTP_REFERER') : |
51 | redirect(request.environ.get('HTTP_REFERER'
|
||
52 | ).split(request.environ.get('HTTP_HOST'))[1]) |
||
53 | else :
|
||
54 | redirect('/')
|
||
55 | |||
56 | 5f2cd70a | Francois POIROTTE | @expose('vigiboard.html') |
57 | 228aad1c | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
58 | 080abea3 | Francois POIROTTE | def default(self, page=None, hostgroup=None, servicegroup=None, |
59 | host=None, service=None, output=None, trouble_ticket=None, |
||
60 | from_date=None, to_date=None, *argv, **krgv): |
||
61 | 19e88cb8 | Thomas ANDREJAK | |
62 | """
|
||
63 | bc94248f | Francois POIROTTE | Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée
|
64 | a2a22ade | Francois POIROTTE | (page 1 par defaut), la liste des événements, rangés par ordre de prise
|
65 | bc94248f | Francois POIROTTE | en compte, puis de sévérité.
|
66 | 19e88cb8 | Thomas ANDREJAK | Pour accéder à cette page, l'utilisateur doit être authentifié.
|
67 |
|
||
68 | bc94248f | Francois POIROTTE | @param page: Numéro de la page souhaitée, commence à 1
|
69 | 19e88cb8 | Thomas ANDREJAK | @param host: Si l'utilisateur souhaite sélectionner seulement certains
|
70 | a2a22ade | Francois POIROTTE | événements suivant leur hôte, il peut placer une expression
|
71 | 19e88cb8 | Thomas ANDREJAK | ici en suivant la structure du LIKE en SQL
|
72 | @param service: Idem que host mais sur les services
|
||
73 | @param output: Idem que host mais sur le text explicatif
|
||
74 | @param trouble_ticket: Idem que host mais sur les tickets attribués
|
||
75 | """
|
||
76 | aa0788a2 | Francois POIROTTE | if page is None: |
77 | page = 1
|
||
78 | 693e96f1 | Thomas ANDREJAK | |
79 | aa0788a2 | Francois POIROTTE | try:
|
80 | page = int(page)
|
||
81 | except ValueError: |
||
82 | abort(404)
|
||
83 | |||
84 | if page < 1: |
||
85 | 19e88cb8 | Thomas ANDREJAK | page = 1
|
86 | |||
87 | bc94248f | Francois POIROTTE | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
88 | 4952a19c | Francois POIROTTE | user = User.by_user_name(username) |
89 | 840079e0 | Vincent QUEMENER | |
90 | 97f6d842 | Vincent QUEMENER | aggregates = VigiboardRequest(user) |
91 | 911069bc | Francois POIROTTE | aggregates.add_table( |
92 | CorrEvent, |
||
93 | aggregates.items.c.hostname, |
||
94 | aggregates.items.c.servicename |
||
95 | ) |
||
96 | aggregates.add_join((Event, CorrEvent.idcause == Event.idevent)) |
||
97 | bfd8ead8 | Vincent QUEMENER | aggregates.add_join((aggregates.items, |
98 | Event.idsupitem == aggregates.items.c.idsupitem)) |
||
99 | 5d20c2c5 | Francois POIROTTE | aggregates.add_order_by(asc(aggregates.items.c.hostname)) |
100 | d6c3a0c9 | Thomas ANDREJAK | |
101 | bc94248f | Francois POIROTTE | search = { |
102 | 'host': '', |
||
103 | 'service': '', |
||
104 | 'output': '', |
||
105 | 1101e03e | Francois POIROTTE | 'tt': '', |
106 | 'from_date': '', |
||
107 | 'to_date': '', |
||
108 | 080abea3 | Francois POIROTTE | 'hostgroup': '', |
109 | 'servicegroup': '', |
||
110 | bc94248f | Francois POIROTTE | } |
111 | 398c727b | Francois POIROTTE | |
112 | 19e88cb8 | Thomas ANDREJAK | # Application des filtres si nécessaire
|
113 | 398c727b | Francois POIROTTE | if hostgroup:
|
114 | search['hostgroup'] = hostgroup
|
||
115 | hostgroup = sql_escape_like(hostgroup) |
||
116 | 24334b4b | Vincent QUEMENER | aggregates.add_join((HostGroup, HostGroup.idgroup == \ |
117 | aggregates.items.c.idhostgroup)) |
||
118 | aggregates.add_filter(HostGroup.name.ilike('%%%s%%' % hostgroup))
|
||
119 | 398c727b | Francois POIROTTE | |
120 | if servicegroup:
|
||
121 | search['servicegroup'] = servicegroup
|
||
122 | servicegroup = sql_escape_like(servicegroup) |
||
123 | 24334b4b | Vincent QUEMENER | aggregates.add_join((ServiceGroup, ServiceGroup.idgroup == \ |
124 | aggregates.items.c.idservicegroup)) |
||
125 | 6ab72614 | Vincent QUEMENER | aggregates.add_filter( |
126 | ServiceGroup.name.ilike('%%%s%%' % servicegroup))
|
||
127 | 398c727b | Francois POIROTTE | |
128 | 08d86103 | Francois POIROTTE | if host:
|
129 | 693e96f1 | Thomas ANDREJAK | search['host'] = host
|
130 | 08d86103 | Francois POIROTTE | host = sql_escape_like(host) |
131 | 24334b4b | Vincent QUEMENER | aggregates.add_filter(aggregates.items.c.hostname.ilike( |
132 | '%%%s%%' % host))
|
||
133 | bc94248f | Francois POIROTTE | |
134 | 08d86103 | Francois POIROTTE | if service:
|
135 | 693e96f1 | Thomas ANDREJAK | search['service'] = service
|
136 | 08d86103 | Francois POIROTTE | service = sql_escape_like(service) |
137 | 24334b4b | Vincent QUEMENER | aggregates.add_filter(aggregates.items.c.servicename.ilike( |
138 | 1101e03e | Francois POIROTTE | '%%%s%%' % service))
|
139 | bc94248f | Francois POIROTTE | |
140 | 08d86103 | Francois POIROTTE | if output:
|
141 | 693e96f1 | Thomas ANDREJAK | search['output'] = output
|
142 | 08d86103 | Francois POIROTTE | output = sql_escape_like(output) |
143 | a2a22ade | Francois POIROTTE | aggregates.add_filter(Event.message.ilike('%%%s%%' % output))
|
144 | bc94248f | Francois POIROTTE | |
145 | 08d86103 | Francois POIROTTE | if trouble_ticket:
|
146 | 693e96f1 | Thomas ANDREJAK | search['tt'] = trouble_ticket
|
147 | 08d86103 | Francois POIROTTE | trouble_ticket = sql_escape_like(trouble_ticket) |
148 | 780ca169 | Francois POIROTTE | aggregates.add_filter(CorrEvent.trouble_ticket.ilike( |
149 | 19e88cb8 | Thomas ANDREJAK | '%%%s%%' % trouble_ticket))
|
150 | |||
151 | 1101e03e | Francois POIROTTE | if from_date:
|
152 | search['from_date'] = from_date
|
||
153 | # TRANSLATORS: Format de date et heure.
|
||
154 | try:
|
||
155 | from_date = datetime.strptime( |
||
156 | from_date, _('%Y-%m-%d %I:%M:%S %p'))
|
||
157 | except ValueError: |
||
158 | to_date = None
|
||
159 | aggregates.add_filter(CorrEvent.timestamp_active >= from_date) |
||
160 | |||
161 | if to_date:
|
||
162 | search['to_date'] = to_date
|
||
163 | # TRANSLATORS: Format de date et heure.
|
||
164 | try:
|
||
165 | to_date = datetime.strptime( |
||
166 | to_date, _('%Y-%m-%d %I:%M:%S %p'))
|
||
167 | except ValueError: |
||
168 | to_date = None
|
||
169 | aggregates.add_filter(CorrEvent.timestamp_active <= to_date) |
||
170 | |||
171 | 19e88cb8 | Thomas ANDREJAK | # Calcul des éléments à afficher et du nombre de pages possibles
|
172 | 3d0d254c | Francois POIROTTE | total_rows = aggregates.num_rows() |
173 | ee3ae8c8 | Francois POIROTTE | items_per_page = int(config['vigiboard_items_per_page']) |
174 | 19e88cb8 | Thomas ANDREJAK | |
175 | ee3ae8c8 | Francois POIROTTE | id_first_row = items_per_page * (page-1)
|
176 | id_last_row = min(id_first_row + items_per_page, total_rows)
|
||
177 | 19e88cb8 | Thomas ANDREJAK | |
178 | 3d0d254c | Francois POIROTTE | aggregates.format_events(id_first_row, id_last_row) |
179 | aggregates.generate_tmpl_context() |
||
180 | baedcd0f | Francois POIROTTE | |
181 | ee3ae8c8 | Francois POIROTTE | nb_pages = int(math.ceil(total_rows / (items_per_page + 0.0))) |
182 | baedcd0f | Francois POIROTTE | if not total_rows: |
183 | id_first_row = 0
|
||
184 | else:
|
||
185 | id_first_row += 1
|
||
186 | 3d0d254c | Francois POIROTTE | |
187 | 19e88cb8 | Thomas ANDREJAK | return dict( |
188 | 1101e03e | Francois POIROTTE | events = aggregates.events, |
189 | rows_info = { |
||
190 | 'id_first_row': id_first_row,
|
||
191 | 'id_last_row': id_last_row,
|
||
192 | 'total_rows': total_rows,
|
||
193 | }, |
||
194 | nb_pages = nb_pages, |
||
195 | page = page, |
||
196 | event_edit_status_options = edit_event_status_options, |
||
197 | history = [], |
||
198 | hist_error = False,
|
||
199 | plugin_context = aggregates.context_fct, |
||
200 | search = search, |
||
201 | 398c727b | Francois POIROTTE | refresh_times = config['vigiboard_refresh_times'],
|
202 | 1101e03e | Francois POIROTTE | ) |
203 | 693e96f1 | Thomas ANDREJAK | |
204 | 08d86103 | Francois POIROTTE | @validate(validators={'idcorrevent': validators.Int(not_empty=True)}, |
205 | 19e88cb8 | Thomas ANDREJAK | error_handler=process_form_errors) |
206 | @expose('json') |
||
207 | 228aad1c | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
208 | a45763b4 | Francois POIROTTE | def history_dialog(self, idcorrevent): |
209 | 19e88cb8 | Thomas ANDREJAK | |
210 | """
|
||
211 | JSon renvoyant les éléments pour l'affichage de la fenêtre de dialogue
|
||
212 | contenant des liens internes et externes.
|
||
213 | Pour accéder à cette page, l'utilisateur doit être authentifié.
|
||
214 |
|
||
215 | a2a22ade | Francois POIROTTE | @param id: identifiant de l'événement
|
216 | 19e88cb8 | Thomas ANDREJAK | """
|
217 | 693e96f1 | Thomas ANDREJAK | |
218 | a2a22ade | Francois POIROTTE | # Obtention de données sur l'événement et sur son historique
|
219 | aa0788a2 | Francois POIROTTE | username = request.environ.get('repoze.who.identity'
|
220 | ).get('repoze.who.userid')
|
||
221 | |||
222 | 911069bc | Francois POIROTTE | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
223 | events = VigiboardRequest(User.by_user_name(username)) |
||
224 | events.add_table( |
||
225 | Event, |
||
226 | events.items.c.hostname, |
||
227 | events.items.c.servicename, |
||
228 | 24334b4b | Vincent QUEMENER | ) |
229 | 911069bc | Francois POIROTTE | events.add_join((CorrEvent, CorrEvent.idcause == Event.idevent)) |
230 | bfd8ead8 | Vincent QUEMENER | events.add_join((events.items, |
231 | Event.idsupitem == events.items.c.idsupitem)) |
||
232 | 911069bc | Francois POIROTTE | events.add_filter(CorrEvent.idcorrevent == idcorrevent) |
233 | 24334b4b | Vincent QUEMENER | |
234 | 911069bc | Francois POIROTTE | # Vérification que au moins un des identifiants existe et est éditable
|
235 | if events.num_rows() != 1: |
||
236 | flash(_('No access to this event'), 'error') |
||
237 | redirect('/')
|
||
238 | 8484b8bd | Francois POIROTTE | |
239 | 911069bc | Francois POIROTTE | event = events.req[0]
|
240 | d6c3a0c9 | Thomas ANDREJAK | eventdetails = {} |
241 | b8500d1a | Thomas ANDREJAK | for edname, edlink in \ |
242 | aa0788a2 | Francois POIROTTE | config['vigiboard_links.eventdetails'].iteritems():
|
243 | b8500d1a | Thomas ANDREJAK | |
244 | 08d86103 | Francois POIROTTE | # Rappel:
|
245 | # event[0] = priorité de l'alerte corrélée.
|
||
246 | # event[1] = alerte brute.
|
||
247 | 911069bc | Francois POIROTTE | if event.servicename:
|
248 | service = urllib.quote(event.servicename) |
||
249 | 24334b4b | Vincent QUEMENER | else:
|
250 | service = None
|
||
251 | d6c3a0c9 | Thomas ANDREJAK | eventdetails[edname] = edlink[1] % {
|
252 | 08d86103 | Francois POIROTTE | 'idcorrevent': idcorrevent,
|
253 | 911069bc | Francois POIROTTE | 'host': urllib.quote(event.hostname),
|
254 | 24334b4b | Vincent QUEMENER | 'service': service,
|
255 | 911069bc | Francois POIROTTE | 'message': urllib.quote(event[0].message), |
256 | 08d86103 | Francois POIROTTE | } |
257 | b8500d1a | Thomas ANDREJAK | |
258 | 19e88cb8 | Thomas ANDREJAK | return dict( |
259 | f43329c2 | Francois POIROTTE | current_state = StateName.value_to_statename( |
260 | 911069bc | Francois POIROTTE | event[0].current_state),
|
261 | f43329c2 | Francois POIROTTE | initial_state = StateName.value_to_statename( |
262 | 911069bc | Francois POIROTTE | event[0].initial_state),
|
263 | f43329c2 | Francois POIROTTE | peak_state = StateName.value_to_statename( |
264 | 911069bc | Francois POIROTTE | event[0].peak_state),
|
265 | a45763b4 | Francois POIROTTE | idcorrevent = idcorrevent, |
266 | 911069bc | Francois POIROTTE | host = event.hostname, |
267 | service = event.servicename, |
||
268 | c49defb8 | Francois POIROTTE | eventdetails = eventdetails, |
269 | 19e88cb8 | Thomas ANDREJAK | ) |
270 | |||
271 | 08d86103 | Francois POIROTTE | @validate(validators={'idcorrevent': validators.Int(not_empty=True)}, |
272 | 19e88cb8 | Thomas ANDREJAK | error_handler=process_form_errors) |
273 | 5f2cd70a | Francois POIROTTE | @expose('vigiboard.html') |
274 | 228aad1c | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
275 | a45763b4 | Francois POIROTTE | def event(self, idcorrevent): |
276 | 19e88cb8 | Thomas ANDREJAK | """
|
277 | a2a22ade | Francois POIROTTE | Affichage de l'historique d'un événement.
|
278 | 19e88cb8 | Thomas ANDREJAK | Pour accéder à cette page, l'utilisateur doit être authentifié.
|
279 |
|
||
280 | a2a22ade | Francois POIROTTE | @param idevent: identifiant de l'événement souhaité
|
281 | 19e88cb8 | Thomas ANDREJAK | """
|
282 | |||
283 | bc94248f | Francois POIROTTE | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
284 | events = VigiboardRequest(User.by_user_name(username)) |
||
285 | 911069bc | Francois POIROTTE | events.add_table( |
286 | CorrEvent, |
||
287 | events.items.c.hostname, |
||
288 | events.items.c.servicename, |
||
289 | ) |
||
290 | events.add_join((Event, CorrEvent.idcause == Event.idevent)) |
||
291 | bfd8ead8 | Vincent QUEMENER | events.add_join((events.items, |
292 | Event.idsupitem == events.items.c.idsupitem)) |
||
293 | a45763b4 | Francois POIROTTE | events.add_filter(CorrEvent.idcorrevent == idcorrevent) |
294 | 19e88cb8 | Thomas ANDREJAK | |
295 | a2a22ade | Francois POIROTTE | # Vérification que l'événement existe
|
296 | 19e88cb8 | Thomas ANDREJAK | if events.num_rows() != 1 : |
297 | 911069bc | Francois POIROTTE | flash(_('No access to this event'), 'error') |
298 | 19e88cb8 | Thomas ANDREJAK | redirect('/')
|
299 | |||
300 | events.format_events(0, 1) |
||
301 | events.format_history() |
||
302 | events.generate_tmpl_context() |
||
303 | |||
304 | return dict( |
||
305 | 911069bc | Francois POIROTTE | events = events.events, |
306 | rows_info = { |
||
307 | 'id_first_row': 1, |
||
308 | 'id_last_row': 1, |
||
309 | 'total_rows': 1, |
||
310 | }, |
||
311 | nb_pages = 1,
|
||
312 | page = 1,
|
||
313 | event_edit_status_options = edit_event_status_options, |
||
314 | history = events.hist, |
||
315 | hist_error = True,
|
||
316 | plugin_context = events.context_fct, |
||
317 | search = { |
||
318 | 'host': '', |
||
319 | 'service': '', |
||
320 | 'output': '', |
||
321 | 'tt': '', |
||
322 | 'from_date': '', |
||
323 | 'to_date': '', |
||
324 | 'hostgroup': '', |
||
325 | 'servicegroup': '', |
||
326 | }, |
||
327 | refresh_times=config['vigiboard_refresh_times'],
|
||
328 | ) |
||
329 | 19e88cb8 | Thomas ANDREJAK | |
330 | 24334b4b | Vincent QUEMENER | @validate(
|
331 | validators={ |
||
332 | 'host': validators.NotEmpty(),
|
||
333 | # 'service': validators.NotEmpty()
|
||
334 | }, |
||
335 | 6ab72614 | Vincent QUEMENER | error_handler = process_form_errors) |
336 | 5f2cd70a | Francois POIROTTE | @expose('vigiboard.html') |
337 | 228aad1c | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
338 | 24334b4b | Vincent QUEMENER | def host_service(self, host, service=None): |
339 | 19e88cb8 | Thomas ANDREJAK | """
|
340 | a2a22ade | Francois POIROTTE | Affichage de l'historique de l'ensemble des événements correspondant
|
341 | bc94248f | Francois POIROTTE | au host et service demandé.
|
342 | 19e88cb8 | Thomas ANDREJAK | Pour accéder à cette page, l'utilisateur doit être authentifié.
|
343 |
|
||
344 | @param host: Nom de l'hôte souhaité.
|
||
345 | @param service: Nom du service souhaité
|
||
346 | """
|
||
347 | |||
348 | 24334b4b | Vincent QUEMENER | idsupitem = SupItem.get_supitem(host, service) |
349 | |||
350 | bc94248f | Francois POIROTTE | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
351 | events = VigiboardRequest(User.by_user_name(username)) |
||
352 | 911069bc | Francois POIROTTE | events.add_table( |
353 | CorrEvent, |
||
354 | events.items.c.hostname, |
||
355 | events.items.c.servicename, |
||
356 | ) |
||
357 | events.add_join((Event, CorrEvent.idcause == Event.idevent)) |
||
358 | bfd8ead8 | Vincent QUEMENER | events.add_join((events.items, |
359 | Event.idsupitem == events.items.c.idsupitem)) |
||
360 | 24334b4b | Vincent QUEMENER | events.add_filter(events.items.c.idsupitem == idsupitem) |
361 | baedcd0f | Francois POIROTTE | |
362 | a8f27bb3 | Francois POIROTTE | # XXX On devrait avoir une autre API que ça !!!
|
363 | a2a22ade | Francois POIROTTE | # Supprime le filtre qui empêche d'obtenir des événements fermés
|
364 | a8f27bb3 | Francois POIROTTE | # (ie: ayant l'état Nagios 'OK' et le statut 'AAClosed').
|
365 | 24334b4b | Vincent QUEMENER | if len(events.filter) > 0: |
366 | del events.filter[0] |
||
367 | 6892ebac | Thomas ANDREJAK | |
368 | a2a22ade | Francois POIROTTE | # Vérification qu'il y a au moins 1 événement qui correspond
|
369 | 19e88cb8 | Thomas ANDREJAK | if events.num_rows() == 0 : |
370 | 911069bc | Francois POIROTTE | flash(_('No access to this host/service or no event yet'), 'error') |
371 | 19e88cb8 | Thomas ANDREJAK | redirect('/')
|
372 | ee3ae8c8 | Francois POIROTTE | |
373 | 19e88cb8 | Thomas ANDREJAK | events.format_events(0, events.num_rows())
|
374 | events.format_history() |
||
375 | ee3ae8c8 | Francois POIROTTE | events.generate_tmpl_context() |
376 | |||
377 | 19e88cb8 | Thomas ANDREJAK | return dict( |
378 | 8484b8bd | Francois POIROTTE | events = events.events, |
379 | rows_info = { |
||
380 | 'id_first_row': 1, |
||
381 | 'id_last_row': 1, |
||
382 | 'total_rows': 1, |
||
383 | }, |
||
384 | baedcd0f | Francois POIROTTE | nb_pages = 1,
|
385 | 8484b8bd | Francois POIROTTE | page = 1,
|
386 | event_edit_status_options = edit_event_status_options, |
||
387 | history = events.hist, |
||
388 | hist_error = True,
|
||
389 | plugin_context = events.context_fct, |
||
390 | search = { |
||
391 | 1bb369b9 | Francois POIROTTE | 'host': '', |
392 | 'service': '', |
||
393 | 'output': '', |
||
394 | 'tt': '', |
||
395 | 'from_date': '', |
||
396 | 'to_date': '', |
||
397 | 'hostgroup': '', |
||
398 | 'servicegroup': '', |
||
399 | ef31cc13 | Francois POIROTTE | }, |
400 | 398c727b | Francois POIROTTE | refresh_times=config['vigiboard_refresh_times'],
|
401 | 8484b8bd | Francois POIROTTE | ) |
402 | 19e88cb8 | Thomas ANDREJAK | |
403 | @validate(validators={
|
||
404 | 1bb369b9 | Francois POIROTTE | "id": validators.Regex(r'^[0-9]+(,[0-9]+)*,?$'), |
405 | # "trouble_ticket": validators.Regex(r'^[0-9]*$'),
|
||
406 | 5d20c2c5 | Francois POIROTTE | "ack": validators.OneOf([
|
407 | 1bb369b9 | Francois POIROTTE | u'NoChange',
|
408 | u'None',
|
||
409 | u'Acknowledged',
|
||
410 | u'AAClosed'
|
||
411 | 08d86103 | Francois POIROTTE | ])}, error_handler=process_form_errors) |
412 | 228aad1c | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
413 | 19e88cb8 | Thomas ANDREJAK | def update(self,**krgv): |
414 | """
|
||
415 | a2a22ade | Francois POIROTTE | Mise à jour d'un événement suivant les arguments passés.
|
416 | 8484b8bd | Francois POIROTTE | Cela peut être un changement de ticket ou un changement de statut.
|
417 | 19e88cb8 | Thomas ANDREJAK |
|
418 | a2a22ade | Francois POIROTTE | @param krgv['id']: Le ou les identifiants des événements à traiter
|
419 | 97f6d842 | Vincent QUEMENER | @param krgv['last_modification']: La date de la dernière modification
|
420 | dont l'utilisateur est au courant.
|
||
421 | 19e88cb8 | Thomas ANDREJAK | @param krgv['tt']: Nouveau numéro du ticket associé.
|
422 | a2a22ade | Francois POIROTTE | @param krgv['status']: Nouveau status de/des événements.
|
423 | 19e88cb8 | Thomas ANDREJAK | """
|
424 | |||
425 | 97f6d842 | Vincent QUEMENER | # On vérifie que des identifiants ont bien été transmis via
|
426 | # le formulaire, et on informe l'utilisateur le cas échéant.
|
||
427 | 10848680 | Francois POIROTTE | if krgv['id'] is None: |
428 | flash(_('No event has been selected'), 'warning') |
||
429 | raise redirect(request.environ.get('HTTP_REFERER', url('/'))) |
||
430 | 5d20c2c5 | Francois POIROTTE | |
431 | # Le filtre permet d'éliminer les chaines vides contenues dans le
|
||
432 | # tableau ('a,b,' -> split -> ['a','b',''] -> filter -> ['a','b']).
|
||
433 | 2597785f | Francois POIROTTE | ids = map(int, filter(len, krgv['id'].split(','))) |
434 | 97f6d842 | Vincent QUEMENER | |
435 | # Si l'utilisateur édite plusieurs événements à la fois,
|
||
436 | # il nous faut chacun des identifiants
|
||
437 | 19e88cb8 | Thomas ANDREJAK | |
438 | bc94248f | Francois POIROTTE | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
439 | events = VigiboardRequest(User.by_user_name(username)) |
||
440 | 911069bc | Francois POIROTTE | events.add_table(CorrEvent) |
441 | events.add_join((Event, CorrEvent.idcause == Event.idevent)) |
||
442 | 5d20c2c5 | Francois POIROTTE | events.add_join((events.items, |
443 | bfd8ead8 | Vincent QUEMENER | Event.idsupitem == events.items.c.idsupitem)) |
444 | 780ca169 | Francois POIROTTE | events.add_filter(CorrEvent.idcorrevent.in_(ids)) |
445 | 19e88cb8 | Thomas ANDREJAK | |
446 | 5edd29ac | Vincent QUEMENER | events.generate_request() |
447 | idevents = [cause.idcause for cause in events.req] |
||
448 | # Si des changements sont survenus depuis que la
|
||
449 | # page est affichée, on en informe l'utilisateur.
|
||
450 | last_modification = get_last_modification_timestamp(idevents, None)
|
||
451 | if last_modification and datetime.fromtimestamp(\ |
||
452 | float(krgv['last_modification'])) < last_modification: |
||
453 | flash(_('Changes have occurred since the page was last displayed, '
|
||
454 | 'your changes HAVE NOT been saved.'), 'warning') |
||
455 | raise redirect(request.environ.get('HTTP_REFERER', url('/'))) |
||
456 | |||
457 | 19e88cb8 | Thomas ANDREJAK | # Vérification que au moins un des identifiants existe et est éditable
|
458 | 858d88aa | Francois POIROTTE | if events.num_rows() <= 0: |
459 | 19e88cb8 | Thomas ANDREJAK | flash(_('No access to this event'), 'error') |
460 | redirect('/')
|
||
461 | |||
462 | a2a22ade | Francois POIROTTE | # Modification des événements et création d'un historique
|
463 | a8f27bb3 | Francois POIROTTE | # pour chacun d'eux.
|
464 | 3d0d254c | Francois POIROTTE | for req in events.req: |
465 | 780ca169 | Francois POIROTTE | if isinstance(req, CorrEvent): |
466 | 19e88cb8 | Thomas ANDREJAK | event = req |
467 | else:
|
||
468 | event = req[0]
|
||
469 | 8484b8bd | Francois POIROTTE | |
470 | 19e88cb8 | Thomas ANDREJAK | if krgv['trouble_ticket'] != '' : |
471 | 8484b8bd | Francois POIROTTE | history = EventHistory( |
472 | type_action="Ticket change",
|
||
473 | idevent=event.idcause, |
||
474 | ee3ae8c8 | Francois POIROTTE | value=krgv['trouble_ticket'],
|
475 | 9494bbb3 | Vincent QUEMENER | text="Changed trouble ticket from '%s' to '%s'" % (
|
476 | ee3ae8c8 | Francois POIROTTE | event.trouble_ticket, krgv['trouble_ticket']
|
477 | ), |
||
478 | 8484b8bd | Francois POIROTTE | username=username, |
479 | ee3ae8c8 | Francois POIROTTE | timestamp=datetime.now(), |
480 | 8484b8bd | Francois POIROTTE | ) |
481 | 19e88cb8 | Thomas ANDREJAK | DBSession.add(history) |
482 | ee3ae8c8 | Francois POIROTTE | event.trouble_ticket = krgv['trouble_ticket']
|
483 | 8484b8bd | Francois POIROTTE | |
484 | 97f6d842 | Vincent QUEMENER | if krgv['ack'] != 'NoChange' : |
485 | 19e88cb8 | Thomas ANDREJAK | history = EventHistory( |
486 | ed4a7159 | Vincent QUEMENER | type_action="Acknowledgement change state",
|
487 | 8484b8bd | Francois POIROTTE | idevent=event.idcause, |
488 | 97f6d842 | Vincent QUEMENER | value=krgv['ack'],
|
489 | 9494bbb3 | Vincent QUEMENER | text="Changed acknowledgement status "
|
490 | "from '%s' to '%s'" % (
|
||
491 | 97f6d842 | Vincent QUEMENER | event.status, krgv['ack']
|
492 | ee3ae8c8 | Francois POIROTTE | ), |
493 | 8484b8bd | Francois POIROTTE | username=username, |
494 | ee3ae8c8 | Francois POIROTTE | timestamp=datetime.now(), |
495 | 8484b8bd | Francois POIROTTE | ) |
496 | 19e88cb8 | Thomas ANDREJAK | DBSession.add(history) |
497 | 97f6d842 | Vincent QUEMENER | event.status = krgv['ack']
|
498 | 3d0d254c | Francois POIROTTE | |
499 | 10848680 | Francois POIROTTE | DBSession.flush() |
500 | 19e88cb8 | Thomas ANDREJAK | flash(_('Updated successfully'))
|
501 | c1ce3d6a | Francois POIROTTE | redirect(request.environ.get('HTTP_REFERER', url('/'))) |
502 | 19e88cb8 | Thomas ANDREJAK | |
503 | 8ad24667 | Thomas ANDREJAK | |
504 | 08d86103 | Francois POIROTTE | @validate(validators={"plugin_name": validators.OneOf( |
505 | 3d0d254c | Francois POIROTTE | [i for [i, j] in config.get('vigiboard_plugins', [])])}, |
506 | b8500d1a | Thomas ANDREJAK | error_handler = process_form_errors) |
507 | 8ad24667 | Thomas ANDREJAK | @expose('json') |
508 | 4dd2035e | Francois POIROTTE | @require(Any(not_anonymous(), msg=l_("You need to be authenticated"))) |
509 | def get_plugin_value(self, idcorrevent, plugin_name, *arg, **krgv): |
||
510 | 8ad24667 | Thomas ANDREJAK | """
|
511 | 4dd2035e | Francois POIROTTE | Permet de récupérer la valeur d'un plugin associée à un CorrEvent
|
512 | donné via JSON.
|
||
513 | 8ad24667 | Thomas ANDREJAK | """
|
514 | 0f56fff9 | Francois POIROTTE | plugins = config['vigiboard_plugins']
|
515 | if plugins is None: |
||
516 | 4dd2035e | Francois POIROTTE | raise HTTPNotFound()
|
517 | |||
518 | # Permet de vérifier si l'utilisateur a bien les permissions
|
||
519 | # pour accéder à cet événement et si l'événement existe.
|
||
520 | username = request.environ['repoze.who.identity']['repoze.who.userid'] |
||
521 | events = VigiboardRequest(User.by_user_name(username)) |
||
522 | events.add_table(CorrEvent.idcorrevent) |
||
523 | events.add_join((Event, CorrEvent.idcause == Event.idevent)) |
||
524 | bfd8ead8 | Vincent QUEMENER | events.add_join((events.items, |
525 | Event.idsupitem == events.items.c.idsupitem)) |
||
526 | 4dd2035e | Francois POIROTTE | events.add_filter(CorrEvent.idcorrevent == idcorrevent) |
527 | |||
528 | # Pas d'événement ou permission refusée. On ne distingue pas
|
||
529 | # les 2 cas afin d'éviter la divulgation d'informations.
|
||
530 | if not events.num_rows(): |
||
531 | raise HTTPNotFound()
|
||
532 | 0f56fff9 | Francois POIROTTE | |
533 | plugin = [i for i in plugins if i[0] == plugin_name][0] |
||
534 | 8ad24667 | Thomas ANDREJAK | try:
|
535 | mypac = __import__(
|
||
536 | b8500d1a | Thomas ANDREJAK | 'vigiboard.controllers.vigiboard_plugin.' + plugin[0], |
537 | globals(), locals(), [plugin[1]], -1) |
||
538 | plug = getattr(mypac, plugin[1])() |
||
539 | 4dd2035e | Francois POIROTTE | return plug.controller(idcorrevent, *arg, **krgv)
|
540 | except ImportError: |
||
541 | raise HTTPNotFound()
|
||
542 | 1bb369b9 | Francois POIROTTE | |
543 | @validate(validators={
|
||
544 | "fontsize": validators.Regex(
|
||
545 | r'[0-9]+(pt|px|em|%)',
|
||
546 | 6ab72614 | Vincent QUEMENER | regexOps = ('I',)
|
547 | 1bb369b9 | Francois POIROTTE | )}, error_handler = process_form_errors) |
548 | 693e96f1 | Thomas ANDREJAK | @expose('json') |
549 | b8500d1a | Thomas ANDREJAK | def set_fontsize(self, fontsize): |
550 | 4dd2035e | Francois POIROTTE | """Enregistre la taille de la police dans les préférences."""
|
551 | b8500d1a | Thomas ANDREJAK | session['fontsize'] = fontsize
|
552 | session.save() |
||
553 | e2e218d7 | Francois POIROTTE | return dict() |
554 | 693e96f1 | Thomas ANDREJAK | |
555 | 08d86103 | Francois POIROTTE | @validate(validators={"refresh": validators.Int()}, |
556 | error_handler=process_form_errors) |
||
557 | 693e96f1 | Thomas ANDREJAK | @expose('json') |
558 | b8500d1a | Thomas ANDREJAK | def set_refresh(self, refresh): |
559 | 4dd2035e | Francois POIROTTE | """Enregistre le temps de rafraichissement dans les préférences."""
|
560 | b8500d1a | Thomas ANDREJAK | session['refresh'] = refresh
|
561 | session.save() |
||
562 | e2e218d7 | Francois POIROTTE | return dict() |
563 | |||
564 | @expose('json') |
||
565 | def set_theme(self, theme): |
||
566 | 4dd2035e | Francois POIROTTE | """Enregistre le thème à utiliser dans les préférences."""
|
567 | # On sauvegarde l'ID du thème sans vérifications
|
||
568 | # car les thèmes (styles CSS) sont définies dans
|
||
569 | # les packages de thèmes (ex: vigilo-themes-default).
|
||
570 | # La vérification de la valeur est faite dans les templates.
|
||
571 | e2e218d7 | Francois POIROTTE | session['theme'] = theme
|
572 | session.save() |
||
573 | return dict() |
||
574 | 97f6d842 | Vincent QUEMENER | |
575 | 24334b4b | Vincent QUEMENER | def get_last_modification_timestamp(event_id_list, |
576 | 4dd2035e | Francois POIROTTE | value_if_none=datetime.now()): |
577 | 97f6d842 | Vincent QUEMENER | """
|
578 | Récupère le timestamp de la dernière modification
|
||
579 | opérée sur l'un des événements dont l'identifiant
|
||
580 | fait partie de la liste passée en paramètre.
|
||
581 | """
|
||
582 | last_modification_timestamp = DBSession.query( |
||
583 | func.max(EventHistory.timestamp), |
||
584 | ).filter(EventHistory.idevent.in_(event_id_list) |
||
585 | ).scalar() |
||
586 | e9ccb711 | Francois POIROTTE | if not last_modification_timestamp: |
587 | 24334b4b | Vincent QUEMENER | if not value_if_none: |
588 | return None |
||
589 | else:
|
||
590 | last_modification_timestamp = value_if_none |
||
591 | e9ccb711 | Francois POIROTTE | return datetime.fromtimestamp(mktime(
|
592 | last_modification_timestamp.timetuple())) |