vigigraph / vigigraph / controllers / rpc.py @ 63aa2a70
History | View | Annotate | Download (31.1 KB)
1 |
# -*- coding: utf-8 -*-
|
---|---|
2 |
"""RPC controller for the combobox of vigigraph"""
|
3 |
|
4 |
import time, urlparse |
5 |
import logging |
6 |
|
7 |
# La fonction parse_qsl a été déplacée dans Python 2.6.
|
8 |
try:
|
9 |
from urlparse import parse_qsl |
10 |
except ImportError: |
11 |
from cgi import parse_qsl |
12 |
|
13 |
from pylons.i18n import ugettext as _, lazy_ugettext as l_ |
14 |
from tg import expose, request, redirect, tmpl_context, \ |
15 |
config, validate, flash |
16 |
from tg.decorators import paginate |
17 |
from repoze.what.predicates import not_anonymous, has_permission, \ |
18 |
in_group, Any, All |
19 |
from formencode import validators, schema |
20 |
from sqlalchemy import or_ |
21 |
|
22 |
from vigilo.turbogears.controllers import BaseController |
23 |
from vigilo.turbogears.helpers import get_current_user |
24 |
|
25 |
from vigilo.models.session import DBSession |
26 |
from vigilo.models.tables import LowLevelService, Host |
27 |
from vigilo.models.tables import SupItemGroup |
28 |
from vigilo.models.tables import PerfDataSource |
29 |
from vigilo.models.tables import Graph, GraphGroup |
30 |
from vigilo.models.tables.grouphierarchy import GroupHierarchy |
31 |
|
32 |
from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE |
33 |
from vigilo.models.tables.secondary_tables import GRAPH_GROUP_TABLE |
34 |
from vigilo.models.tables.secondary_tables import GRAPH_PERFDATASOURCE_TABLE |
35 |
from vigilo.models.functions import sql_escape_like |
36 |
|
37 |
from vigigraph.widgets.searchhostform import SearchHostForm |
38 |
|
39 |
LOGGER = logging.getLogger(__name__) |
40 |
|
41 |
__all__ = ['RpcController']
|
42 |
|
43 |
|
44 |
# pylint: disable-msg=R0201
|
45 |
class RpcController(BaseController): |
46 |
"""
|
47 |
Class Controleur TurboGears
|
48 |
"""
|
49 |
|
50 |
# L'accès à ce contrôleur nécessite d'être identifié.
|
51 |
allow_only = All( |
52 |
not_anonymous(msg=l_("You need to be authenticated")),
|
53 |
Any( |
54 |
in_group('managers'),
|
55 |
has_permission('vigigraph-read',
|
56 |
msg=l_("You don't have read access on VigiGraph")),
|
57 |
), |
58 |
) |
59 |
|
60 |
presets = [ |
61 |
{"caption" : _("Last %d hours") % 12, "duration" : 43200}, |
62 |
{"caption" : _("Last %d hours") % 24, "duration" : 86400}, |
63 |
{"caption" : _("Last %d days") % 2, "duration" : 192800}, |
64 |
{"caption" : _("Last %d days") % 7, "duration" : 604800}, |
65 |
{"caption" : _("Last %d days") % 14, "duration" : 1209600}, |
66 |
{"caption" : _("Last %d months") % 3, "duration" : 86400 * 31 * 3}, |
67 |
{"caption" : _("Last %d months") % 6, "duration" : 86400 * 183}, |
68 |
{"caption" : _("Last year"), "duration" : 86400 * 365}, |
69 |
] |
70 |
|
71 |
def process_form_errors(self, *argv, **kwargv): |
72 |
"""
|
73 |
Gestion des erreurs de validation : On affiche les erreurs
|
74 |
puis on redirige vers la dernière page accédée.
|
75 |
"""
|
76 |
for k in tmpl_context.form_errors: |
77 |
flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error') |
78 |
redirect(request.environ.get('HTTP_REFERER', '/')) |
79 |
|
80 |
@expose('json') |
81 |
def maingroups(self, nocache=None): |
82 |
"""
|
83 |
Determination des groupes principaux (sans parent)
|
84 |
|
85 |
@return: Dictionnaire dont la clé "items" contient une liste
|
86 |
de tuples contenant le nom et l'ID des groupes d'éléments
|
87 |
au sommet de la hiérarchie et auquels l'utilisateur a accès.
|
88 |
@rtype: C{dict}
|
89 |
@note: L'ID des groupes est converti en chaîne de caractères
|
90 |
dans le résultat.
|
91 |
"""
|
92 |
user = get_current_user() |
93 |
if user is None: |
94 |
return dict(items=[]) |
95 |
|
96 |
groups_with_parents = DBSession.query( |
97 |
GroupHierarchy.idparent, |
98 |
).distinct() |
99 |
|
100 |
# Les managers ont accès à tout.
|
101 |
# Les autres ont un accès restreint.
|
102 |
is_manager = in_group('managers').is_met(request.environ)
|
103 |
if not is_manager: |
104 |
supitemgroups = user.supitemgroups() |
105 |
groups_with_parents = groups_with_parents.filter( |
106 |
GroupHierarchy.idchild.in_(supitemgroups)) |
107 |
|
108 |
groups_with_parents = [g.idparent for g in groups_with_parents.all()] |
109 |
children = DBSession.query( |
110 |
SupItemGroup |
111 |
).distinct( |
112 |
).join( |
113 |
(GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup) |
114 |
).filter(GroupHierarchy.hops > 0)
|
115 |
|
116 |
topgroups = DBSession.query( |
117 |
SupItemGroup, |
118 |
).filter(SupItemGroup.idgroup.in_(groups_with_parents) |
119 |
).except_(children).order_by(SupItemGroup.name).all() |
120 |
topgroups = [(sig.name, str(sig.idgroup)) for sig in topgroups] |
121 |
return dict(items=topgroups) |
122 |
|
123 |
class HostgroupsSchema(schema.Schema): |
124 |
"""Schéma de validation pour la méthode L{hostgroups}."""
|
125 |
maingroupid = validators.Int(not_empty=True)
|
126 |
nocache = validators.String(if_missing=None)
|
127 |
|
128 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
129 |
@validate(
|
130 |
validators = HostgroupsSchema(), |
131 |
error_handler = process_form_errors) |
132 |
@expose('json') |
133 |
def hostgroups(self, maingroupid, nocache): |
134 |
"""
|
135 |
Determination des groupes associes au groupe parent
|
136 |
dont identificateur = argument
|
137 |
|
138 |
@param maingroupid: identificateur d un groupe principal
|
139 |
@type maingroupid: C{int}
|
140 |
|
141 |
@return: Dictionnaire dont la clé "items" contient une liste
|
142 |
de tuples avec le nom et l'ID des groupes d'éléments
|
143 |
auxquels l'utilisateur a accès.
|
144 |
@rtype: C{dict}
|
145 |
@note: L'ID des groupes est converti en chaîne de caractères
|
146 |
dans le résultat.
|
147 |
"""
|
148 |
user = get_current_user() |
149 |
if user is None: |
150 |
return dict(items=[]) |
151 |
|
152 |
hostgroups = DBSession.query( |
153 |
SupItemGroup.name, |
154 |
SupItemGroup.idgroup, |
155 |
).distinct().join( |
156 |
(GroupHierarchy, GroupHierarchy.idchild == \ |
157 |
SupItemGroup.idgroup), |
158 |
).filter(GroupHierarchy.idparent == maingroupid |
159 |
).filter(GroupHierarchy.hops == 1
|
160 |
).order_by(SupItemGroup.name.asc()) |
161 |
|
162 |
# Les managers ont accès à tout.
|
163 |
# Les autres ont un accès restreint.
|
164 |
is_manager = in_group('managers').is_met(request.environ)
|
165 |
if not is_manager: |
166 |
supitemgroups = user.supitemgroups() |
167 |
hostgroups = hostgroups.filter( |
168 |
SupItemGroup.idgroup.in_(supitemgroups)) |
169 |
|
170 |
hostgroups = [(hg.name, str(hg.idgroup)) for hg in hostgroups.all()] |
171 |
hostgroups.insert(0, (_('No subgroup'), str(maingroupid))) |
172 |
return dict(items=hostgroups) |
173 |
|
174 |
class HostsSchema(schema.Schema): |
175 |
"""Schéma de validation pour la méthode L{hosts}."""
|
176 |
othergroupid = validators.Int(not_empty=True)
|
177 |
nocache = validators.String(if_missing=None)
|
178 |
|
179 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
180 |
@validate(
|
181 |
validators = HostsSchema(), |
182 |
error_handler = process_form_errors) |
183 |
@expose('json') |
184 |
def hosts(self, othergroupid, nocache): |
185 |
"""
|
186 |
Determination des hotes associes au groupe
|
187 |
dont identificateur = argument
|
188 |
|
189 |
@param othergroupid : identificateur d un groupe
|
190 |
@type othergroupid : int
|
191 |
|
192 |
@return: hotes
|
193 |
@rtype: document json (sous forme de dict)
|
194 |
"""
|
195 |
user = get_current_user() |
196 |
if user is None: |
197 |
return dict(items=[]) |
198 |
|
199 |
groups_with_parents = DBSession.query( |
200 |
GroupHierarchy.idparent, |
201 |
).distinct() |
202 |
|
203 |
# Les managers ont accès à tout.
|
204 |
# Les autres ont un accès restreint.
|
205 |
is_manager = in_group('managers').is_met(request.environ)
|
206 |
if not is_manager: |
207 |
supitemgroups = user.supitemgroups() |
208 |
groups_with_parents = groups_with_parents.filter( |
209 |
GroupHierarchy.idchild.in_(supitemgroups)) |
210 |
|
211 |
groups_with_parents = [g.idparent for g in groups_with_parents.all()] |
212 |
hosts = DBSession.query( |
213 |
Host.name, |
214 |
Host.idhost, |
215 |
).distinct( |
216 |
).outerjoin( |
217 |
(LowLevelService, LowLevelService.idhost == Host.idhost), |
218 |
).join( |
219 |
(SUPITEM_GROUP_TABLE, or_( |
220 |
SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost, |
221 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
222 |
LowLevelService.idservice, |
223 |
)), |
224 |
).filter(SUPITEM_GROUP_TABLE.c.idgroup == othergroupid |
225 |
).filter(SUPITEM_GROUP_TABLE.c.idgroup.in_(groups_with_parents) |
226 |
).order_by( |
227 |
Host.name.asc(), |
228 |
).all() |
229 |
|
230 |
hosts = [(h.name, str(h.idhost)) for h in hosts] |
231 |
return dict(items=hosts) |
232 |
|
233 |
class GraphGroupsSchema(schema.Schema): |
234 |
"""Schéma de validation pour la méthode L{graphgroups}."""
|
235 |
idhost = validators.Int(not_empty=True)
|
236 |
nocache = validators.String(if_missing=None)
|
237 |
|
238 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
239 |
@validate(
|
240 |
validators = GraphGroupsSchema(), |
241 |
error_handler = process_form_errors) |
242 |
@expose('json') |
243 |
def graphgroups(self, idhost, nocache): |
244 |
"""
|
245 |
Determination des groupes de graphes associes a l hote
|
246 |
dont identificateur = argument
|
247 |
|
248 |
@param idhost : identificateur d un hote
|
249 |
@type idhost : int
|
250 |
|
251 |
@return: groupes de service
|
252 |
@rtype: document json (sous forme de dict)
|
253 |
"""
|
254 |
user = get_current_user() |
255 |
if user is None: |
256 |
return dict(items=[]) |
257 |
|
258 |
graphgroups = DBSession.query( |
259 |
GraphGroup.name, |
260 |
GraphGroup.idgroup, |
261 |
).distinct( |
262 |
).join( |
263 |
(GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \ |
264 |
GraphGroup.idgroup), |
265 |
(Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph), |
266 |
(GRAPH_PERFDATASOURCE_TABLE, \ |
267 |
GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
268 |
(PerfDataSource, PerfDataSource.idperfdatasource == \ |
269 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
270 |
(LowLevelService, LowLevelService.idservice == \ |
271 |
PerfDataSource.idservice), |
272 |
(SUPITEM_GROUP_TABLE, or_( |
273 |
SUPITEM_GROUP_TABLE.c.idsupitem == LowLevelService.idhost, |
274 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
275 |
LowLevelService.idservice, |
276 |
)), |
277 |
).filter(LowLevelService.idhost == idhost |
278 |
).order_by(GraphGroup.name.asc()) |
279 |
|
280 |
# Les managers ont accès à tout.
|
281 |
# Les autres ont un accès restreint.
|
282 |
is_manager = in_group('managers').is_met(request.environ)
|
283 |
if not is_manager: |
284 |
supitemgroups = user.supitemgroups() |
285 |
graphgroups = graphgroups.filter( |
286 |
SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups)) |
287 |
|
288 |
graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups.all()] |
289 |
return dict(items=graphgroups) |
290 |
|
291 |
class GraphsSchema(schema.Schema): |
292 |
"""Schéma de validation pour la méthode L{graphs}."""
|
293 |
idgraphgroup = validators.Int(not_empty=True)
|
294 |
idhost = validators.Int(not_empty=True)
|
295 |
nocache = validators.String(if_missing=None)
|
296 |
|
297 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
298 |
@validate(
|
299 |
validators = GraphsSchema(), |
300 |
error_handler = process_form_errors) |
301 |
@expose('json') |
302 |
def graphs(self, idgraphgroup, idhost, nocache): |
303 |
"""
|
304 |
Determination des graphes
|
305 |
avec un service dont identificateur = argument
|
306 |
|
307 |
@param idgraph : identificateur d un service
|
308 |
@type idgraph : int
|
309 |
|
310 |
@return: graphes
|
311 |
@rtype: document json (sous forme de dict)
|
312 |
"""
|
313 |
user = get_current_user() |
314 |
if user is None: |
315 |
return dict(items=[]) |
316 |
|
317 |
graphs = DBSession.query( |
318 |
Graph.name, |
319 |
Graph.idgraph, |
320 |
).distinct().join( |
321 |
(GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgraph == \ |
322 |
Graph.idgraph), |
323 |
(GraphGroup, GraphGroup.idgroup == \ |
324 |
GRAPH_GROUP_TABLE.c.idgroup), |
325 |
(GRAPH_PERFDATASOURCE_TABLE, \ |
326 |
GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
327 |
(PerfDataSource, PerfDataSource.idperfdatasource == \ |
328 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
329 |
(LowLevelService, LowLevelService.idservice == \ |
330 |
PerfDataSource.idservice), |
331 |
(SUPITEM_GROUP_TABLE, or_( |
332 |
SUPITEM_GROUP_TABLE.c.idsupitem == LowLevelService.idhost, |
333 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
334 |
LowLevelService.idservice, |
335 |
)), |
336 |
).filter(GraphGroup.idgroup == idgraphgroup |
337 |
).filter(LowLevelService.idhost == idhost |
338 |
).order_by(Graph.name.asc()) |
339 |
|
340 |
# Les managers ont accès à tout.
|
341 |
# Les autres ont un accès restreint.
|
342 |
is_manager = in_group('managers').is_met(request.environ)
|
343 |
if not is_manager: |
344 |
supitemgroups = user.supitemgroups() |
345 |
graphs = graphs.filter( |
346 |
SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups)) |
347 |
|
348 |
graphs = [(pds.name, str(pds.idgraph)) for pds in graphs.all()] |
349 |
return dict(items=graphs) |
350 |
|
351 |
class SearchHostAndGraphSchema(schema.Schema): |
352 |
"""Schéma de validation pour la méthode L{searchHostAndGraph}."""
|
353 |
host = validators.String(if_missing=None)
|
354 |
graph = validators.String(if_missing=None)
|
355 |
nocache = validators.String(if_missing=None)
|
356 |
|
357 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
358 |
@validate(
|
359 |
validators = SearchHostAndGraphSchema(), |
360 |
error_handler = process_form_errors) |
361 |
@expose('json') |
362 |
def searchHostAndGraph(self, host, graph, nocache): |
363 |
"""
|
364 |
Determination des couples (hote-graphe) repondant aux criteres de
|
365 |
recherche sur hote et/ou graphe.
|
366 |
|
367 |
Un critere peut correspondre a un intitule complet hote ou graphe
|
368 |
ou a un extrait.
|
369 |
|
370 |
@param kwargs : arguments nommes
|
371 |
@type kwargs : dict
|
372 |
( arguments nommes -> host et graphe )
|
373 |
|
374 |
@return: couples hote-graphe
|
375 |
@rtype: document json (sous forme de dict)
|
376 |
"""
|
377 |
user = get_current_user() |
378 |
items = [] |
379 |
|
380 |
if user is None: |
381 |
return dict(items=[]) |
382 |
|
383 |
# On a un nom d'indicateur, mais pas de nom d'hôte,
|
384 |
# on considère que l'utilisateur veut tous les indicateurs
|
385 |
# correspondant au motif, quel que soit l'hôte.
|
386 |
if graph is not None: |
387 |
if host is None: |
388 |
host = '*'
|
389 |
|
390 |
host = sql_escape_like(host) |
391 |
graph = sql_escape_like(graph) |
392 |
|
393 |
items = DBSession.query( |
394 |
Host.name.label('hostname'),
|
395 |
Graph.name.label('graphname'),
|
396 |
).distinct().join( |
397 |
(LowLevelService, LowLevelService.idhost == Host.idhost), |
398 |
(PerfDataSource, PerfDataSource.idservice == \ |
399 |
LowLevelService.idservice), |
400 |
(GRAPH_PERFDATASOURCE_TABLE, \ |
401 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
402 |
PerfDataSource.idperfdatasource), |
403 |
(Graph, Graph.idgraph == \ |
404 |
GRAPH_PERFDATASOURCE_TABLE.c.idgraph), |
405 |
(SUPITEM_GROUP_TABLE, or_( |
406 |
SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost, |
407 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
408 |
LowLevelService.idservice, |
409 |
)), |
410 |
).filter(Host.name.ilike('%' + host + '%') |
411 |
).filter(Graph.name.ilike('%' + graph + '%') |
412 |
).order_by( |
413 |
Host.name.asc(), |
414 |
Graph.name.asc(), |
415 |
) |
416 |
|
417 |
# On a ni hôte, ni indicateur. On renvoie une liste vide.
|
418 |
# Si l'utilisateur voulait vraiment quelque chose,
|
419 |
# il n'avait qu'à le demander.
|
420 |
elif host is None: |
421 |
return []
|
422 |
|
423 |
# Sinon, on a juste un motif pour un hôte.
|
424 |
# On renvoie la liste des hôtes correspondant.
|
425 |
else:
|
426 |
host = sql_escape_like(host) |
427 |
items = DBSession.query( |
428 |
Host.name.label('hostname'),
|
429 |
).join( |
430 |
(SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \ |
431 |
Host.idhost), |
432 |
).filter(Host.name.ilike('%' + host + '%') |
433 |
).order_by(Host.name.asc()) |
434 |
|
435 |
# Les managers ont accès à tout.
|
436 |
# Les autres ont un accès restreint.
|
437 |
is_manager = in_group('managers').is_met(request.environ)
|
438 |
if not is_manager: |
439 |
supitemgroups = user.supitemgroups() |
440 |
items = items.filter( |
441 |
SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups)) |
442 |
|
443 |
items = items.limit(100).all()
|
444 |
if graph is None: |
445 |
items = [(item.hostname, "") for item in items] |
446 |
else:
|
447 |
items = [(item.hostname, item.graphname) for item in items] |
448 |
return dict(items=items) |
449 |
|
450 |
class SelectHostAndGraphSchema(schema.Schema): |
451 |
"""Schéma de validation pour la méthode L{selectHostAndGraph}."""
|
452 |
host = validators.String(if_missing=None)
|
453 |
graph = validators.String(if_missing=None)
|
454 |
nocache = validators.String(if_missing=None)
|
455 |
|
456 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
457 |
@validate(
|
458 |
validators = SelectHostAndGraphSchema(), |
459 |
error_handler = process_form_errors) |
460 |
@expose('json') |
461 |
def selectHostAndGraph(self, host, graph, nocache): |
462 |
"""
|
463 |
Renvoie les valeurs à sélectionner dans les comboboxes
|
464 |
de VigiGraph pour afficher les données de l'hôte ou du
|
465 |
couple hôte/graphe sélectionné.
|
466 |
|
467 |
La clé "items" du dictionnaire renvoyé contient une liste avec
|
468 |
2 éléments, chacun de ces éléments étant lui-même une liste.
|
469 |
La 1ère liste contient les noms des groupes d'hôtes à sélectionner.
|
470 |
La 2ème liste contient la liste des groupes de graphes à sélectionner.
|
471 |
|
472 |
Pour le moment, la 2ème liste contiendra au plus 1 élément car
|
473 |
les groupes de graphes ne sont pas récursifs. L'utilisation d'une
|
474 |
liste permet d'assurer facilement une évolution vers des groupes
|
475 |
de graphes récursifs.
|
476 |
"""
|
477 |
|
478 |
# Ce cas ne devrait pas se produire, mais on tente
|
479 |
# d'avoir un comportement gracieux malgré tout.
|
480 |
if (not host) and (not graph): |
481 |
return dict(items=[[], []]) |
482 |
|
483 |
selected_hostgroups = [] |
484 |
selected_graphgroups = [] |
485 |
|
486 |
# @TODO: ajouter la gestion des permissions au code qui suit.
|
487 |
# Pour le moment, la récupération de idsupitemgroup & idgraphgroup
|
488 |
# ne prend pas en compte les permissions réelles de l'utilisateur.
|
489 |
|
490 |
if host:
|
491 |
# Sélectionne l'identifiant du premier SupItemGroup auquel
|
492 |
# l'utilisateur a accès et auquel l'hôte donné appartient.
|
493 |
idsupitemgroup = DBSession.query( |
494 |
SupItemGroup.idgroup, |
495 |
).distinct().join( |
496 |
(SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idgroup == \ |
497 |
SupItemGroup.idgroup), |
498 |
(Host, Host.idhost == SUPITEM_GROUP_TABLE.c.idsupitem), |
499 |
).filter(Host.name == host |
500 |
).scalar() |
501 |
|
502 |
# Si on a trouvé un tel groupe, on renvoie les noms des
|
503 |
# groupes de la hiérarchie à sélectionner pour arriver
|
504 |
# à celui-ci.
|
505 |
if idsupitemgroup is not None: |
506 |
selected_hostgroups = DBSession.query( |
507 |
SupItemGroup.name, |
508 |
).distinct().join( |
509 |
(GroupHierarchy, GroupHierarchy.idparent == \ |
510 |
GraphGroup.idgroup), |
511 |
).filter(GroupHierarchy.idchild == idsupitemgroup |
512 |
).order_by( |
513 |
GroupHierarchy.hops.desc() |
514 |
).all() |
515 |
|
516 |
if graph:
|
517 |
# Le principe est le même que pour l'hôte, en considérant
|
518 |
# cette fois les GraphGroup à la place des SupItemGroup.
|
519 |
idgraphgroup = DBSession.query( |
520 |
GraphGroup.idgroup, |
521 |
).distinct().join( |
522 |
(GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \ |
523 |
GraphGroup.idgroup), |
524 |
(Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph), |
525 |
).filter(Graph.name == graph |
526 |
).scalar() |
527 |
|
528 |
# Même principe que pour l'hôte.
|
529 |
if idgraphgroup is not None: |
530 |
selected_graphgroups = DBSession.query( |
531 |
GraphGroup.name, |
532 |
).distinct().join( |
533 |
(GroupHierarchy, GroupHierarchy.idparent == \ |
534 |
GraphGroup.idgroup), |
535 |
).filter(GroupHierarchy.idchild == idgraphgroup |
536 |
).order_by( |
537 |
GroupHierarchy.hops.desc() |
538 |
).all() |
539 |
|
540 |
hostgroups = [hg.name for hg in selected_hostgroups] |
541 |
graphgroups = [gg.name for gg in selected_graphgroups] |
542 |
return dict(items=[hostgroups, graphgroups]) |
543 |
|
544 |
@expose('graphslist.html') |
545 |
def graphsList(self, nocache=None, **kwargs): |
546 |
"""
|
547 |
Generation document avec url des graphes affiches
|
548 |
(pour l impression )
|
549 |
|
550 |
@param kwargs : arguments nommes
|
551 |
@type kwargs : dict
|
552 |
|
553 |
@return: url de graphes
|
554 |
@rtype: document html
|
555 |
"""
|
556 |
if not kwargs: |
557 |
return dict(graphslist=[]) |
558 |
|
559 |
# TRANSLATORS: Format Python de date/heure, lisible par un humain.
|
560 |
format = _("%a, %d %b %Y %H:%M:%S")
|
561 |
graphslist = [] |
562 |
for url in kwargs.itervalues(): |
563 |
parts = urlparse.urlparse(url) |
564 |
params = dict(parse_qsl(parts.query))
|
565 |
|
566 |
graph = {} |
567 |
start = int(params.get('start', time.time() - 86400)) |
568 |
duration = int(params.get('duration', 86400)) |
569 |
|
570 |
graph['graph'] = params.get('graphtemplate') |
571 |
graph['start_date'] = time.strftime(format, time.localtime(start))
|
572 |
graph['end_date'] = time.strftime(format,
|
573 |
time.localtime(start + duration)) |
574 |
graph['img_src'] = url
|
575 |
graph['host'] = params['host'] |
576 |
graphslist.append(graph) |
577 |
return dict(graphslist=graphslist) |
578 |
|
579 |
@expose(content_type='text/plain') |
580 |
def tempoDelayRefresh(self, nocache=None): |
581 |
"""
|
582 |
Determination valeur temporisation pour le rafraichissement automatique
|
583 |
d un graphe
|
584 |
|
585 |
@return: valeur de temporisation
|
586 |
@rtype: C{str}
|
587 |
"""
|
588 |
|
589 |
try:
|
590 |
delay = int(config['delay_refresh']) |
591 |
except (ValueError, KeyError): |
592 |
delay = 36000
|
593 |
return str(delay) |
594 |
|
595 |
class GetIndicatorsSchema(schema.Schema): |
596 |
"""Schéma de validation pour la méthode L{getIndicators}."""
|
597 |
graph = validators.String(not_empty=True)
|
598 |
nocache = validators.String(if_missing=None)
|
599 |
|
600 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
601 |
@validate(
|
602 |
validators = GetIndicatorsSchema(), |
603 |
error_handler = process_form_errors) |
604 |
@expose('json') |
605 |
def getIndicators(self, graph, nocache): |
606 |
"""
|
607 |
Liste d indicateurs associes a un graphe
|
608 |
|
609 |
@param graph : graphe
|
610 |
@type graph : C{str}
|
611 |
|
612 |
@return: dictionnaire des indicateurs d un graphe
|
613 |
@rtype: document json (sous forme de dict)
|
614 |
"""
|
615 |
|
616 |
indicators = self.getListIndicators(graph)
|
617 |
indicators = [ind.name for ind in indicators] |
618 |
return dict(items=indicators) |
619 |
|
620 |
|
621 |
class FullHostPageSchema(schema.Schema): |
622 |
"""Schéma de validation pour la méthode L{fullHostPage}."""
|
623 |
host = validators.String(not_empty=True)
|
624 |
start = validators.Int(if_missing=None)
|
625 |
duration = validators.Int(if_missing=86400)
|
626 |
|
627 |
# VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
|
628 |
@validate(
|
629 |
validators = FullHostPageSchema(), |
630 |
error_handler = process_form_errors) |
631 |
@expose('fullhostpage.html') |
632 |
def fullHostPage(self, host, start=None, duration=86400): |
633 |
"""
|
634 |
Affichage de l'ensemble des graphes associes a un hote
|
635 |
* d apres les donnees RRD
|
636 |
* avec une date-heure de debut
|
637 |
* pour une plage de temps
|
638 |
|
639 |
@param host : hôte
|
640 |
@type host : C{str}
|
641 |
@param start : date-heure de debut des donnees
|
642 |
@type start : C{str}
|
643 |
@param duration : plage de temps des données
|
644 |
@type duration : C{str}
|
645 |
(parametre optionnel, initialise a 86400 = plage de 1 jour)
|
646 |
|
647 |
@return: page avec les images des graphes et boutons de deplacement dans le temps
|
648 |
@rtype: page html
|
649 |
"""
|
650 |
|
651 |
if start is None: |
652 |
start = int(time.time()) - int(duration) |
653 |
|
654 |
start = int(start)
|
655 |
duration = int(duration)
|
656 |
|
657 |
user = get_current_user() |
658 |
if user is None: |
659 |
return dict(host=host, start=start, duration=duration, |
660 |
presets=self.presets, graphs=[])
|
661 |
|
662 |
# Récupération de la liste des noms des graphes,
|
663 |
# avec vérification des permissions de l'utilisateur.
|
664 |
graphs = DBSession.query( |
665 |
Graph.name |
666 |
).distinct( |
667 |
).join( |
668 |
(GRAPH_PERFDATASOURCE_TABLE, |
669 |
GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
670 |
(PerfDataSource, PerfDataSource.idperfdatasource == |
671 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
672 |
(LowLevelService, LowLevelService.idservice == |
673 |
PerfDataSource.idservice), |
674 |
).outerjoin( |
675 |
(Host, Host.idhost == LowLevelService.idhost), |
676 |
).join( |
677 |
(SUPITEM_GROUP_TABLE, or_( |
678 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
679 |
LowLevelService.idservice, |
680 |
SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost, |
681 |
)) |
682 |
) |
683 |
|
684 |
# Les managers ont accès à tout.
|
685 |
# Les autres ont un accès restreint.
|
686 |
is_manager = in_group('managers').is_met(request.environ)
|
687 |
if not is_manager: |
688 |
supitemgroups = user.supitemgroups() |
689 |
graphs = graphs.filter( |
690 |
SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups)) |
691 |
|
692 |
graphs = graphs.all() |
693 |
return dict(host=host, start=start, duration=duration, |
694 |
presets=self.presets, graphs=graphs)
|
695 |
|
696 |
|
697 |
class SingleGraphSchema(schema.Schema): |
698 |
"""Schéma de validation pour la méthode L{singleGraph}."""
|
699 |
host = validators.String(not_empty=True)
|
700 |
graph = validators.String(not_empty=True)
|
701 |
start = validators.Int(if_missing=None)
|
702 |
duration = validators.Int(if_missing=86400)
|
703 |
|
704 |
# VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes
|
705 |
@validate(
|
706 |
validators = SingleGraphSchema(), |
707 |
error_handler = process_form_errors) |
708 |
@expose('singlegraph.html') |
709 |
def singleGraph(self, host, graph, start, duration): |
710 |
"""
|
711 |
Affichage d un graphe associe a un hote et un graphe
|
712 |
* d apres les donnees RRD
|
713 |
* avec une date-heure de debut
|
714 |
* pour une plage de temps
|
715 |
|
716 |
@param host : hôte
|
717 |
@type host : C{str}
|
718 |
@param graph : graphe
|
719 |
@type graph : C{str}
|
720 |
@param start : date-heure de debut des donnees
|
721 |
@type start : C{str}
|
722 |
@param duration : plage de temps des données
|
723 |
@type duration : C{str}
|
724 |
(parametre optionnel, initialise a 86400 = plage de 1 jour)
|
725 |
|
726 |
@return: page avec l image du graphe et boutons de deplacement dans le temps
|
727 |
@rtype: page html
|
728 |
"""
|
729 |
|
730 |
if start is None: |
731 |
start = int(time.time()) - int(duration) |
732 |
|
733 |
start = int(start)
|
734 |
duration = int(duration)
|
735 |
|
736 |
return dict(host=host, graph=graph, start=start, duration=duration, \ |
737 |
presets=self.presets)
|
738 |
|
739 |
@expose('searchhostform.html') |
740 |
def searchHostForm(self): |
741 |
"""
|
742 |
Formulaire de recherche sur les hotes
|
743 |
|
744 |
@return: page avec formulaire de recherche
|
745 |
@rtype: page html
|
746 |
"""
|
747 |
searchhostform = SearchHostForm('search_host_form', \
|
748 |
submit_text=None)
|
749 |
|
750 |
return dict(searchhostform=searchhostform) |
751 |
|
752 |
@expose('searchhost.html') |
753 |
@paginate('hosts', items_per_page=10) |
754 |
def searchHost(self, *args, **kwargs): |
755 |
"""
|
756 |
Affiche les résultats de la recherche par nom d'hôte.
|
757 |
La requête de recherche (L{query}) correspond à un préfixe
|
758 |
qui sera recherché dans le nom d'hôte. Ce préfixe peut
|
759 |
contenir les caractères '*' et '?' qui agissent comme des
|
760 |
"jokers".
|
761 |
|
762 |
@param query: Prefixe de recherche sur les noms d'hôtes
|
763 |
@type query: C{unicode}
|
764 |
"""
|
765 |
query = kwargs.get('query')
|
766 |
if not query: |
767 |
redirect("searchHostForm")
|
768 |
|
769 |
query = sql_escape_like(query.strip()) |
770 |
user = get_current_user() |
771 |
if user is None: |
772 |
return dict(items=[]) |
773 |
|
774 |
# Récupère les hôtes auxquels l'utilisateur a réellement accès.
|
775 |
hosts = DBSession.query( |
776 |
Host.name, |
777 |
).distinct( |
778 |
).outerjoin( |
779 |
(LowLevelService, LowLevelService.idhost == Host.idhost), |
780 |
).join( |
781 |
(SUPITEM_GROUP_TABLE, or_( |
782 |
SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost, |
783 |
SUPITEM_GROUP_TABLE.c.idsupitem == |
784 |
LowLevelService.idservice, |
785 |
)), |
786 |
).filter(Host.name.like(query + '%')
|
787 |
).order_by( |
788 |
Host.name.asc(), |
789 |
) |
790 |
|
791 |
# Les managers ont accès à tout.
|
792 |
# Les autres ont un accès restreint.
|
793 |
is_manager = in_group('managers').is_met(request.environ)
|
794 |
if not is_manager: |
795 |
supitemgroups = user.supitemgroups() |
796 |
hosts = hosts.filter( |
797 |
SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups)) |
798 |
|
799 |
return dict(hosts=hosts) |
800 |
|
801 |
# VIGILO_EXIG_VIGILO_PERF_0030:Moteur de recherche des graphes
|
802 |
@expose('getopensearch.xml', content_type='text/xml') |
803 |
def getOpenSearch(self): |
804 |
"""
|
805 |
Moteur de recherche des graphes
|
806 |
|
807 |
@return: document
|
808 |
@rtype: document xml
|
809 |
"""
|
810 |
return dict() |
811 |
|
812 |
def getListIndicators(self, graph=None): |
813 |
"""
|
814 |
Liste d indicateurs associes a un graphe
|
815 |
|
816 |
@param graph : graphe
|
817 |
@type graph : C{str}
|
818 |
|
819 |
@return: liste d indicateurs
|
820 |
@rtype : list
|
821 |
"""
|
822 |
|
823 |
indicators = [] |
824 |
if graph is not None: |
825 |
indicators = DBSession.query \ |
826 |
(PerfDataSource.name) \ |
827 |
.join((GRAPH_PERFDATASOURCE_TABLE, \ |
828 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
829 |
PerfDataSource.idperfdatasource)) \ |
830 |
.join((Graph, \ |
831 |
Graph.idgraph == GRAPH_PERFDATASOURCE_TABLE.c.idgraph)) \ |
832 |
.filter(Graph.name == graph) \ |
833 |
.all() |
834 |
return indicators
|
835 |
|