Revision e2dbeada
Corrections pour VigiGraph (code et templates).
git-svn-id: https://vigilo-dev.si.c-s.fr/svn@2790 b22e2e97-25c9-44ff-b637-2e5ceca36478
vigigraph/controllers/rpc.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
"""RPC controller for the combobox of vigigraph""" |
3 | 3 |
|
4 |
import time |
|
4 |
import time, urlparse
|
|
5 | 5 |
import urllib |
6 | 6 |
import urllib2 |
7 | 7 |
import logging |
8 | 8 |
|
9 |
# La fonction parse_qsl a été déplacée dans Python 2.6. |
|
10 |
try: |
|
11 |
from urlparse import parse_qsl |
|
12 |
except ImportError: |
|
13 |
from cgi import parse_qsl |
|
14 |
|
|
9 | 15 |
from pylons.i18n import ugettext as _, lazy_ugettext as l_ |
10 |
from tg import expose, response, request, redirect, config, url, exceptions |
|
16 |
from tg import expose, response, request, redirect, tmpl_context, \ |
|
17 |
config, url, exceptions, validate, flash |
|
11 | 18 |
from repoze.what.predicates import not_anonymous |
19 |
from formencode import validators, schema |
|
12 | 20 |
|
13 | 21 |
from sqlalchemy.orm import aliased |
14 | 22 |
from sqlalchemy import or_ |
... | ... | |
31 | 39 |
from vigilo.turbogears.helpers import get_current_user |
32 | 40 |
|
33 | 41 |
from vigigraph.widgets.searchhostform import SearchHostForm |
34 |
from vigigraph.lib import graphs |
|
35 |
|
|
36 | 42 |
|
37 | 43 |
LOGGER = logging.getLogger(__name__) |
38 | 44 |
|
39 | 45 |
__all__ = ['RpcController'] |
46 |
|
|
40 | 47 |
|
41 | 48 |
# pylint: disable-msg=R0201 |
42 | 49 |
class RpcController(BaseController): |
... | ... | |
53 | 60 |
{"caption" : _("Last %d days") % 2, "duration" : 192800}, |
54 | 61 |
{"caption" : _("Last %d days") % 7, "duration" : 604800}, |
55 | 62 |
{"caption" : _("Last %d days") % 14, "duration" : 1209600}, |
56 |
{"caption" : _("Last %d months") % 3, "duration" : 86400*31*3},
|
|
57 |
{"caption" : _("Last %d months") % 6, "duration" : 86400*183},
|
|
58 |
{"caption" : _("Last year"), "duration" : 86400*365},
|
|
63 |
{"caption" : _("Last %d months") % 3, "duration" : 86400 * 31 * 3},
|
|
64 |
{"caption" : _("Last %d months") % 6, "duration" : 86400 * 183},
|
|
65 |
{"caption" : _("Last year"), "duration" : 86400 * 365},
|
|
59 | 66 |
] |
60 | 67 |
|
68 |
def process_form_errors(self, *argv, **kwargv): |
|
69 |
""" |
|
70 |
Gestion des erreurs de validation : On affiche les erreurs |
|
71 |
puis on redirige vers la dernière page accédée. |
|
72 |
""" |
|
73 |
for k in tmpl_context.form_errors: |
|
74 |
flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error') |
|
75 |
redirect(request.environ.get('HTTP_REFERER', '/')) |
|
76 |
|
|
61 | 77 |
@expose('json') |
62 | 78 |
def maingroups(self, nocache=None): |
63 | 79 |
""" |
... | ... | |
96 | 112 |
topgroups = [(sig.name, str(sig.idgroup)) for sig in topgroups] |
97 | 113 |
return dict(items=topgroups) |
98 | 114 |
|
115 |
class HostgroupsSchema(schema.Schema): |
|
116 |
maingroupid = validators.Int(not_empty=True) |
|
117 |
nocache = validators.String(if_missing=None) |
|
118 |
|
|
119 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
120 |
@validate( |
|
121 |
validators=HostgroupsSchema(), |
|
122 |
error_handler=process_form_errors) |
|
99 | 123 |
@expose('json') |
100 |
def hostgroups(self, maingroupid, nocache=None):
|
|
124 |
def hostgroups(self, maingroupid, nocache): |
|
101 | 125 |
""" |
102 | 126 |
Determination des groupes associes au groupe parent |
103 | 127 |
dont identificateur = argument |
... | ... | |
133 | 157 |
hostgroups.insert(0, (_('No subgroup'), str(maingroupid))) |
134 | 158 |
return dict(items=hostgroups) |
135 | 159 |
|
160 |
class HostsSchema(schema.Schema): |
|
161 |
othergroupid = validators.Int(not_empty=True) |
|
162 |
nocache = validators.String(if_missing=None) |
|
163 |
|
|
164 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
165 |
@validate( |
|
166 |
validators=HostsSchema(), |
|
167 |
error_handler=process_form_errors) |
|
136 | 168 |
@expose('json') |
137 |
def hosts(self, othergroupid, nocache=None):
|
|
169 |
def hosts(self, othergroupid, nocache): |
|
138 | 170 |
""" |
139 | 171 |
Determination des hotes associes au groupe |
140 | 172 |
dont identificateur = argument |
... | ... | |
178 | 210 |
hosts = [(h.name, str(h.idhost)) for h in hosts] |
179 | 211 |
return dict(items=hosts) |
180 | 212 |
|
213 |
class GraphGroupsSchema(schema.Schema): |
|
214 |
idhost = validators.Int(not_empty=True) |
|
215 |
nocache = validators.String(if_missing=None) |
|
216 |
|
|
217 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
218 |
@validate( |
|
219 |
validators=GraphGroupsSchema(), |
|
220 |
error_handler=process_form_errors) |
|
181 | 221 |
@expose('json') |
182 |
def graphgroups(self, idhost, nocache=None):
|
|
222 |
def graphgroups(self, idhost, nocache): |
|
183 | 223 |
""" |
184 | 224 |
Determination des groupes de graphes associes a l hote |
185 | 225 |
dont identificateur = argument |
... | ... | |
222 | 262 |
graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups] |
223 | 263 |
return dict(items=graphgroups) |
224 | 264 |
|
265 |
class GraphsSchema(schema.Schema): |
|
266 |
idgraphgroup = validators.Int(not_empty=True) |
|
267 |
idhost = validators.Int(not_empty=True) |
|
268 |
nocache = validators.String(if_missing=None) |
|
269 |
|
|
270 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
271 |
@validate( |
|
272 |
validators=GraphsSchema(), |
|
273 |
error_handler=process_form_errors) |
|
225 | 274 |
@expose('json') |
226 |
def graphs(self, idgraphgroup, idhost, nocache=None):
|
|
275 |
def graphs(self, idgraphgroup, idhost, nocache): |
|
227 | 276 |
""" |
228 | 277 |
Determination des graphes |
229 | 278 |
avec un service dont identificateur = argument |
... | ... | |
267 | 316 |
graphs = [(pds.name, str(pds.idgraph)) for pds in graphs] |
268 | 317 |
return dict(items=graphs) |
269 | 318 |
|
319 |
class SearchHostAndGraphSchema(schema.Schema): |
|
320 |
host = validators.String(if_missing=None) |
|
321 |
graph = validators.String(if_missing=None) |
|
322 |
|
|
323 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
324 |
@validate( |
|
325 |
validators=SearchHostAndGraphSchema(), |
|
326 |
error_handler=process_form_errors) |
|
270 | 327 |
@expose('json') |
271 |
def searchHostAndGraph(self, **kwargs):
|
|
328 |
def searchHostAndGraph(self, host, graph):
|
|
272 | 329 |
""" |
273 | 330 |
Determination des couples (hote-graphe) repondant aux criteres de |
274 | 331 |
recherche sur hote et/ou graphe. |
... | ... | |
288 | 345 |
return dict(items=[]) |
289 | 346 |
supitemgroups = user.supitemgroups() |
290 | 347 |
|
291 |
host = kwargs.get('host') |
|
292 |
graph = kwargs.get('graph') |
|
293 |
items = None |
|
348 |
items = [] |
|
294 | 349 |
|
295 | 350 |
# On a un nom d'indicateur, mais pas de nom d'hôte, |
296 | 351 |
# on considère que l'utilisateur veut tous les indicateurs |
... | ... | |
352 | 407 |
items = [(item.hostname, item.graphname) for item in items] |
353 | 408 |
return dict(items=items) |
354 | 409 |
|
410 |
class SelectHostAndGraphSchema(schema.Schema): |
|
411 |
host = validators.String(if_missing=None) |
|
412 |
graph = validators.String(if_missing=None) |
|
413 |
nocache = validators.String(if_missing=None) |
|
414 |
|
|
415 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
416 |
@validate( |
|
417 |
validators=SearchHostAndGraphSchema(), |
|
418 |
error_handler=process_form_errors) |
|
355 | 419 |
@expose('json') |
356 |
def selectHostAndGraph(self, host=None, graph=None, nocache=None):
|
|
420 |
def selectHostAndGraph(self, host, graph, nocache):
|
|
357 | 421 |
""" |
358 | 422 |
Renvoie les valeurs à sélectionner dans les comboboxes |
359 | 423 |
de VigiGraph pour afficher les données de l'hôte ou du |
... | ... | |
441 | 505 |
graphgroups = [gg.name for gg in selected_graphgroups] |
442 | 506 |
return dict(items=[hostgroups, graphgroups]) |
443 | 507 |
|
444 |
# # VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes |
|
445 |
# @expose(content_type='image/png') |
|
446 |
# def getImage_png(self, host, start=None, duration=86400, graph=None, \ |
|
447 |
# details=1): |
|
448 |
# """ |
|
449 |
# Affichage de l image d un graphe |
|
450 |
# (via proxy RRD) |
|
451 |
|
|
452 |
# @param host : hôte |
|
453 |
# @type host : C{str} |
|
454 |
# @param start : date-heure de debut des donnees |
|
455 |
# @type start : C{str} |
|
456 |
# @param duration : plage de temps des données |
|
457 |
# @type duration : C{str} |
|
458 |
# (parametre optionnel, initialise a 86400 = plage de 1 jour) |
|
459 |
# @param graph : graphe |
|
460 |
# @type graph : C{str} |
|
461 |
# @param details : indicateur affichage details dans graphe (legende) |
|
462 |
# @type details : int |
|
463 |
|
|
464 |
# @return: image du graphe |
|
465 |
# @rtype: image png |
|
466 |
# """ |
|
467 |
# result = None |
|
468 |
|
|
469 | 508 |
@expose('graphslist.html') |
470 | 509 |
def graphsList(self, nocache=None, **kwargs): |
471 | 510 |
""" |
... | ... | |
478 | 517 |
@return: url de graphes |
479 | 518 |
@rtype: document html |
480 | 519 |
""" |
481 |
graphslist = graphs.graphsList(**kwargs) |
|
520 |
if not kwargs: |
|
521 |
return dict(graphslist=[]) |
|
522 |
|
|
523 |
# TRANSLATORS: Format Python de date/heure, lisible par un humain. |
|
524 |
format = _("%a, %d %b %Y %H:%M:%S") |
|
525 |
graphslist = [] |
|
526 |
for url in kwargs.itervalues(): |
|
527 |
parts = urlparse.urlparse(url) |
|
528 |
params = dict(parse_qsl(parts.query)) |
|
529 |
|
|
530 |
graph = {} |
|
531 |
start = int(params.get('start', time.time() - 86400)) |
|
532 |
duration = int(params.get('duration', 86400)) |
|
533 |
|
|
534 |
graph['graph'] = params.get('graphtemplate') |
|
535 |
graph['start_date'] = time.strftime(format, time.localtime(start)) |
|
536 |
graph['end_date'] = time.strftime(format, |
|
537 |
time.localtime(start + duration)) |
|
538 |
graph['img_src'] = url |
|
539 |
graph['host'] = params['host'] |
|
540 |
graphslist.append(graph) |
|
482 | 541 |
return dict(graphslist=graphslist) |
483 | 542 |
|
484 | 543 |
@expose(content_type='text/plain') |
... | ... | |
491 | 550 |
@rtype: C{str} |
492 | 551 |
""" |
493 | 552 |
|
494 |
delay = graphs.tempoDelayRefresh() |
|
495 |
return delay |
|
553 |
try: |
|
554 |
delay = int(config['delay_refresh']) |
|
555 |
except ValueError, KeyError: |
|
556 |
delay = 36000 |
|
557 |
return str(delay) |
|
496 | 558 |
|
559 |
class GetIndicatorsSchema(schema.Schema): |
|
560 |
graph = validators.String(not_empty=True) |
|
561 |
nocache = validators.String(if_missing=None) |
|
562 |
|
|
563 |
# @TODO définir un error_handler différent pour remonter l'erreur via JS. |
|
564 |
@validate( |
|
565 |
validators=GetIndicatorsSchema(), |
|
566 |
error_handler=process_form_errors) |
|
497 | 567 |
@expose('json') |
498 |
def getIndicators(self, nocache=None, graph=None):
|
|
568 |
def getIndicators(self, graph, nocache):
|
|
499 | 569 |
""" |
500 | 570 |
Liste d indicateurs associes a un graphe |
501 | 571 |
|
... | ... | |
510 | 580 |
indicators = [(ind.name, ind.idperfdatasource) for ind in indicators] |
511 | 581 |
return dict(items=indicators) |
512 | 582 |
|
583 |
|
|
584 |
class FullHostPageSchema(schema.Schema): |
|
585 |
host = validators.String(not_empty=True) |
|
586 |
start = validators.Int(if_missing=None) |
|
587 |
duration = validators.Int(if_missing=86400) |
|
588 |
|
|
513 | 589 |
# VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes |
590 |
@validate( |
|
591 |
validators=FullHostPageSchema(), |
|
592 |
error_handler=process_form_errors) |
|
514 | 593 |
@expose('fullhostpage.html') |
515 | 594 |
def fullHostPage(self, host, start=None, duration=86400): |
516 | 595 |
""" |
... | ... | |
570 | 649 |
return dict(host=host, start=start, duration=duration, |
571 | 650 |
presets=self.presets, graphs=graphs) |
572 | 651 |
|
652 |
|
|
653 |
class SingleGraphSchema(schema.Schema): |
|
654 |
host = validators.String(not_empty=True) |
|
655 |
graph = validators.String(not_empty=True) |
|
656 |
start = validators.Int(if_missing=None) |
|
657 |
duration = validators.Int(if_missing=86400) |
|
658 |
|
|
659 |
# VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes |
|
660 |
@validate( |
|
661 |
validators=SingleGraphSchema(), |
|
662 |
error_handler=process_form_errors) |
|
573 | 663 |
@expose('singlegraph.html') |
574 |
def singleGraph(self, host, graph, start=None, duration=86400):
|
|
664 |
def singleGraph(self, host, graph, start, duration):
|
|
575 | 665 |
""" |
576 | 666 |
Affichage d un graphe associe a un hote et un graphe |
577 | 667 |
* d apres les donnees RRD |
... | ... | |
615 | 705 |
|
616 | 706 |
return dict(searchhostform=searchhostform) |
617 | 707 |
|
708 |
class SearchHostSchema(schema.Schema): |
|
709 |
query = validators.String(if_missing=None) |
|
710 |
|
|
711 |
@validate( |
|
712 |
validators=SearchHostSchema(), |
|
713 |
error_handler=process_form_errors) |
|
618 | 714 |
@expose('searchhost.html') |
619 |
def searchHost(self, query=None):
|
|
715 |
def searchHost(self, query): |
|
620 | 716 |
""" |
621 | 717 |
Affiche les résultats de la recherche par nom d'hôte. |
622 | 718 |
La requête de recherche (L{query}) correspond à un préfixe |
vigigraph/lib/graphs.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
"""Functions for graphs""" |
|
3 |
|
|
4 |
from tg import config |
|
5 |
|
|
6 |
import urllib |
|
7 |
import urllib2 |
|
8 |
from pylons.i18n import ugettext as _ |
|
9 |
|
|
10 |
from time import gmtime, strftime |
|
11 |
from datetime import datetime |
|
12 |
|
|
13 |
|
|
14 |
def graphsList(**kwargs): |
|
15 |
""" |
|
16 |
Page liste des graphes |
|
17 |
|
|
18 |
@param kwargs : arguments nommes |
|
19 |
@type kwargs : dict |
|
20 |
""" |
|
21 |
graphslist = [] |
|
22 |
|
|
23 |
if kwargs is not None: |
|
24 |
# TRANSLATORS: Format Python de date/heure, lisible par un humain. |
|
25 |
format = _("%a, %d %b %Y %H:%M:%S") |
|
26 |
for key in kwargs: |
|
27 |
# titre |
|
28 |
title = _("Unknown") |
|
29 |
graph = "" |
|
30 |
server = "" |
|
31 |
# recherche arguments (apres ?) -> cle1=valeur1&cle2=valeur2&... |
|
32 |
lca = kwargs[key].split("?") |
|
33 |
if len(lca) == 2: |
|
34 |
# analyse de chacun des arguments -> cle=valeur |
|
35 |
largs = lca[1].split("&") |
|
36 |
for arg in largs: |
|
37 |
larg = arg.split("=") |
|
38 |
if len(larg) == 2: |
|
39 |
if larg[0] == "server": |
|
40 |
server = larg[1] |
|
41 |
elif larg[0] == "graphtemplate": |
|
42 |
graph = larg[1] |
|
43 |
elif larg[0] == "start": |
|
44 |
start = larg[1] |
|
45 |
elif larg[0] == "duration": |
|
46 |
duration = larg[1] |
|
47 |
if graph != "" or server != "": |
|
48 |
title = "'%s' Graph for host %s" % \ |
|
49 |
(urllib.unquote_plus(graph), server) |
|
50 |
graph = {} |
|
51 |
graph['title'] = title |
|
52 |
v = int(start) |
|
53 |
graph['sts'] = strftime(format, gmtime(v)) |
|
54 |
v = int(start) + int(duration) |
|
55 |
graph['ets'] = strftime(format, gmtime(v)) |
|
56 |
graph['src'] = urllib2.unquote(kwargs[key]) |
|
57 |
graphslist.append(graph) |
|
58 |
|
|
59 |
return graphslist |
|
60 |
|
|
61 |
def tempoDelayRefresh(): |
|
62 |
""" |
|
63 |
Lecture de la temporisation pour le rafraichissement automatique |
|
64 |
dans le fichier de configuration development.ini |
|
65 |
valeur exprimee en millisecondes, valeur par defaut = 30000 |
|
66 |
|
|
67 |
@return: valeur de temporisation |
|
68 |
@rtype: C{str} |
|
69 |
""" |
|
70 |
|
|
71 |
delay = config.get('delay_refresh') |
|
72 |
delay = delay.strip() |
|
73 |
|
|
74 |
b_evaluate = False |
|
75 |
if delay == '': |
|
76 |
b_evaluate = True |
|
77 |
else: |
|
78 |
if delay.isalnum(): |
|
79 |
delay_l = int(delay) |
|
80 |
b_evaluate = (delay_l <= 0) |
|
81 |
else: |
|
82 |
b_evaluate = True |
|
83 |
|
|
84 |
if b_evaluate: |
|
85 |
delay = '30000' |
|
86 |
|
|
87 |
return delay |
|
88 |
|
Also available in: Unified diff