vigigraph / vigigraph / controllers / rpc.py @ 56b77667
History | View | Annotate | Download (33.2 KB)
1 | 079f14f1 | Thomas BURGUIERE | # -*- coding: utf-8 -*-
|
---|---|---|---|
2 | 56b77667 | Francois POIROTTE | # Copyright (C) 2006-2020 CS-SI
|
3 | 90a1f4ab | Aurelien BOMPARD | # License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html>
|
4 | |||
5 | 079f14f1 | Thomas BURGUIERE | """RPC controller for the combobox of vigigraph"""
|
6 | |||
7 | 8d86738e | Aurelien BOMPARD | # pylint: disable-msg=W0613
|
8 | # W0613: Unused argument : les arguments des contrôleurs sont les composants
|
||
9 | # de la query-string de l'URL
|
||
10 | |||
11 | |||
12 | import time |
||
13 | import urllib2 |
||
14 | 0f65a3b8 | Francois POIROTTE | import urlparse |
15 | 16a7bac7 | Francois POIROTTE | import logging |
16 | |||
17 | 77b7746d | Francois POIROTTE | from tg.i18n import ugettext as _, lazy_ugettext as l_, lazy_ungettext as ln_ |
18 | d1850fc4 | Francois POIROTTE | from tg import expose, request, redirect, tmpl_context, \ |
19 | 75c8d4a7 | Vincent QUEMENER | config, validate, flash, exceptions as http_exc |
20 | ded8142d | Francois POIROTTE | from tg.predicates import not_anonymous, has_permission, in_group, Any, All |
21 | 75c8d4a7 | Vincent QUEMENER | |
22 | cfed65e0 | Francois POIROTTE | from formencode import schema |
23 | from tw.forms import validators |
||
24 | 24589c11 | Francois POIROTTE | from sqlalchemy.orm import aliased, lazyload |
25 | 3c4e7981 | Francois POIROTTE | from sqlalchemy.sql import functions |
26 | 6aec31f5 | Francois POIROTTE | from sqlalchemy import or_ |
27 | cf4ae971 | Francois POIROTTE | |
28 | bc2d4167 | Francois POIROTTE | from vigilo.turbogears.controllers import BaseController |
29 | from vigilo.turbogears.helpers import get_current_user |
||
30 | 24589c11 | Francois POIROTTE | from vigilo.turbogears.controllers.proxy import get_through_proxy |
31 | 77b7746d | Francois POIROTTE | from tg.decorators import paginate |
32 | 89a96e65 | Francis LAHEUGUERE | |
33 | 9cc80ca6 | Francois POIROTTE | from vigilo.models.session import DBSession |
34 | 24589c11 | Francois POIROTTE | from vigilo.models.tables import Host, SupItemGroup, PerfDataSource |
35 | from vigilo.models.tables import Graph, GraphGroup, Change, UserGroup |
||
36 | from vigilo.models.tables import DataPermission |
||
37 | from vigilo.models.tables.group import Group |
||
38 | 7e6517fe | Francois POIROTTE | from vigilo.models.tables.grouphierarchy import GroupHierarchy |
39 | 1eeb5d7a | Francis LAHEUGUERE | |
40 | 454df3f9 | Francois POIROTTE | from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE |
41 | c765e251 | Francois POIROTTE | from vigilo.models.tables.secondary_tables import GRAPH_GROUP_TABLE |
42 | 9cc80ca6 | Francois POIROTTE | from vigilo.models.tables.secondary_tables import GRAPH_PERFDATASOURCE_TABLE |
43 | 24589c11 | Francois POIROTTE | from vigilo.models.tables.secondary_tables import USER_GROUP_TABLE |
44 | c765e251 | Francois POIROTTE | from vigilo.models.functions import sql_escape_like |
45 | 9a31cbd1 | Francois POIROTTE | |
46 | 55f029a4 | Francis LAHEUGUERE | LOGGER = logging.getLogger(__name__) |
47 | |||
48 | 079f14f1 | Thomas BURGUIERE | __all__ = ['RpcController']
|
49 | d19e6b55 | Francois POIROTTE | |
50 | 89b121bb | Francois POIROTTE | def ungettext(singular, plural, n): |
51 | return ln_(singular, plural, n) % {
|
||
52 | 'qtty': n,
|
||
53 | } |
||
54 | 079f14f1 | Thomas BURGUIERE | |
55 | 16a7bac7 | Francois POIROTTE | # pylint: disable-msg=R0201
|
56 | 079f14f1 | Thomas BURGUIERE | class RpcController(BaseController): |
57 | """
|
||
58 | 2c334d8b | Francis LAHEUGUERE | Class Controleur TurboGears
|
59 | 079f14f1 | Thomas BURGUIERE | """
|
60 | c765e251 | Francois POIROTTE | |
61 | 62c4c6f5 | Francois POIROTTE | # L'accès à ce contrôleur nécessite d'être identifié.
|
62 | 0c6b774c | Francois POIROTTE | allow_only = All( |
63 | not_anonymous(msg=l_("You need to be authenticated")),
|
||
64 | Any( |
||
65 | 8089d65a | Francois POIROTTE | config.is_manager, |
66 | 945bd396 | Francois POIROTTE | has_permission('vigigraph-access',
|
67 | d19e6b55 | Francois POIROTTE | msg=l_("You don't have access to VigiGraph")),
|
68 | 0c6b774c | Francois POIROTTE | ), |
69 | ) |
||
70 | 62c4c6f5 | Francois POIROTTE | |
71 | 89b121bb | Francois POIROTTE | # Plages de temps affichées sur la page de métrologie complète
|
72 | # d'un hôte avec la durée associée (en secondes).
|
||
73 | # Voir aussi graph.js pour l'équivalent côté JavaScript sur un graphe.
|
||
74 | c765e251 | Francois POIROTTE | presets = [ |
75 | 89b121bb | Francois POIROTTE | { |
76 | "caption" :
|
||
77 | ungettext("Last %(qtty)d hour", "Last %(qtty)d hours", 12), |
||
78 | "duration" : 43200, |
||
79 | }, |
||
80 | { |
||
81 | "caption" :
|
||
82 | ungettext("Last %(qtty)d hour", "Last %(qtty)d hours", 24), |
||
83 | "duration" : 86400, |
||
84 | }, |
||
85 | { |
||
86 | "caption" :
|
||
87 | ungettext("Last %(qtty)d day", "Last %(qtty)d days", 2), |
||
88 | "duration" : 192800, |
||
89 | }, |
||
90 | { |
||
91 | "caption" :
|
||
92 | ungettext("Last %(qtty)d day", "Last %(qtty)d days", 7), |
||
93 | "duration" : 604800, |
||
94 | }, |
||
95 | { |
||
96 | "caption" :
|
||
97 | ungettext("Last %(qtty)d day", "Last %(qtty)d days", 14), |
||
98 | "duration" : 1209600, |
||
99 | }, |
||
100 | { |
||
101 | "caption" :
|
||
102 | ungettext("Last %(qtty)d month", "Last %(qtty)d months", 1), |
||
103 | "duration" : 86400 * 30, |
||
104 | }, |
||
105 | { |
||
106 | "caption" :
|
||
107 | ungettext("Last %(qtty)d month", "Last %(qtty)d months", 3), |
||
108 | "duration" : 86400 * 30 * 3, |
||
109 | }, |
||
110 | { |
||
111 | "caption" :
|
||
112 | ungettext("Last %(qtty)d month", "Last %(qtty)d months", 6), |
||
113 | "duration" : 86400 * 30 * 6, |
||
114 | }, |
||
115 | { |
||
116 | "caption" :
|
||
117 | ungettext("Last %(qtty)d year", "Last %(qtty)d years", 1), |
||
118 | "duration" : 86400 * 365, |
||
119 | }, |
||
120 | c765e251 | Francois POIROTTE | ] |
121 | |||
122 | 8d86738e | Aurelien BOMPARD | def process_form_errors(self, *args, **kwargs): |
123 | e2dbeada | Francois POIROTTE | """
|
124 | Gestion des erreurs de validation : On affiche les erreurs
|
||
125 | puis on redirige vers la dernière page accédée.
|
||
126 | """
|
||
127 | for k in tmpl_context.form_errors: |
||
128 | flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error') |
||
129 | redirect(request.environ.get('HTTP_REFERER', '/')) |
||
130 | |||
131 | class SearchHostAndGraphSchema(schema.Schema): |
||
132 | d1850fc4 | Francois POIROTTE | """Schéma de validation pour la méthode L{searchHostAndGraph}."""
|
133 | cfed65e0 | Francois POIROTTE | search_form_host = validators.UnicodeString(if_missing=None)
|
134 | search_form_graph = validators.UnicodeString(if_missing=None)
|
||
135 | e2dbeada | Francois POIROTTE | |
136 | # @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
||
137 | @validate(
|
||
138 | d1850fc4 | Francois POIROTTE | validators = SearchHostAndGraphSchema(), |
139 | error_handler = process_form_errors) |
||
140 | 0f25906a | Francis LAHEUGUERE | @expose('json') |
141 | 77b7746d | Francois POIROTTE | def searchHostAndGraph(self, search_form_host=None, search_form_graph=None): |
142 | 2c334d8b | Francis LAHEUGUERE | """
|
143 | c765e251 | Francois POIROTTE | Determination des couples (hote-graphe) repondant aux criteres de
|
144 | recherche sur hote et/ou graphe.
|
||
145 | 09301287 | Francis LAHEUGUERE |
|
146 | c765e251 | Francois POIROTTE | Un critere peut correspondre a un intitule complet hote ou graphe
|
147 | ou a un extrait.
|
||
148 | 9b20ecb4 | Francis LAHEUGUERE |
|
149 | c765e251 | Francois POIROTTE | @return: couples hote-graphe
|
150 | 7e6517fe | Francois POIROTTE | @rtype: document json (sous forme de dict)
|
151 | 2c334d8b | Francis LAHEUGUERE | """
|
152 | 924533ae | Francois POIROTTE | limit = 100
|
153 | cf4ae971 | Francois POIROTTE | user = get_current_user() |
154 | 924533ae | Francois POIROTTE | ids = [] |
155 | labels = [] |
||
156 | 63aa2a70 | Francois POIROTTE | |
157 | cf4ae971 | Francois POIROTTE | if user is None: |
158 | return dict(items=[]) |
||
159 | 9b20ecb4 | Francis LAHEUGUERE | |
160 | 7e6517fe | Francois POIROTTE | # On a un nom d'indicateur, mais pas de nom d'hôte,
|
161 | # on considère que l'utilisateur veut tous les indicateurs
|
||
162 | cf4ae971 | Francois POIROTTE | # correspondant au motif, quel que soit l'hôte.
|
163 | 7c9baa43 | Francois POIROTTE | if search_form_graph:
|
164 | if not search_form_host: |
||
165 | 24589c11 | Francois POIROTTE | search_form_host = u'*'
|
166 | c765e251 | Francois POIROTTE | |
167 | 7c9baa43 | Francois POIROTTE | search_form_host = sql_escape_like(search_form_host) |
168 | search_form_graph = sql_escape_like(search_form_graph) |
||
169 | c765e251 | Francois POIROTTE | |
170 | items = DBSession.query( |
||
171 | 7c9baa43 | Francois POIROTTE | Host.idhost.label('idhost'),
|
172 | c765e251 | Francois POIROTTE | Host.name.label('hostname'),
|
173 | 6aec31f5 | Francois POIROTTE | Host.address.label('address'),
|
174 | 7c9baa43 | Francois POIROTTE | Graph.idgraph.label('idgraph'),
|
175 | c765e251 | Francois POIROTTE | Graph.name.label('graphname'),
|
176 | 454df3f9 | Francois POIROTTE | ).distinct().join( |
177 | 60c3c88e | Francois POIROTTE | (PerfDataSource, PerfDataSource.idhost == Host.idhost), |
178 | c765e251 | Francois POIROTTE | (GRAPH_PERFDATASOURCE_TABLE, \ |
179 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
||
180 | PerfDataSource.idperfdatasource), |
||
181 | (Graph, Graph.idgraph == \ |
||
182 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph), |
||
183 | 60c3c88e | Francois POIROTTE | (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \ |
184 | Host.idhost), |
||
185 | 6aec31f5 | Francois POIROTTE | ).filter(or_( |
186 | Host.name.ilike(search_form_host), |
||
187 | Host.address.ilike(search_form_host), |
||
188 | )).filter(Graph.name.ilike(search_form_graph) |
||
189 | c765e251 | Francois POIROTTE | ).order_by( |
190 | Host.name.asc(), |
||
191 | Graph.name.asc(), |
||
192 | ) |
||
193 | |||
194 | # On a ni hôte, ni indicateur. On renvoie une liste vide.
|
||
195 | # Si l'utilisateur voulait vraiment quelque chose,
|
||
196 | # il n'avait qu'à le demander.
|
||
197 | 7c9baa43 | Francois POIROTTE | elif not search_form_host: |
198 | c765e251 | Francois POIROTTE | return []
|
199 | |||
200 | # Sinon, on a juste un motif pour un hôte.
|
||
201 | # On renvoie la liste des hôtes correspondant.
|
||
202 | 9b20ecb4 | Francis LAHEUGUERE | else:
|
203 | 7c9baa43 | Francois POIROTTE | search_form_host = sql_escape_like(search_form_host) |
204 | c765e251 | Francois POIROTTE | items = DBSession.query( |
205 | 7c9baa43 | Francois POIROTTE | Host.idhost.label('idhost'),
|
206 | c765e251 | Francois POIROTTE | Host.name.label('hostname'),
|
207 | 6aec31f5 | Francois POIROTTE | Host.address.label('address'),
|
208 | 279ff224 | Francois POIROTTE | ).distinct().join( |
209 | cf4ae971 | Francois POIROTTE | (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \ |
210 | Host.idhost), |
||
211 | 6aec31f5 | Francois POIROTTE | ).filter(or_( |
212 | Host.name.ilike(search_form_host), |
||
213 | Host.address.ilike(search_form_host), |
||
214 | )).order_by(Host.name.asc()) |
||
215 | c765e251 | Francois POIROTTE | |
216 | 63aa2a70 | Francois POIROTTE | # Les managers ont accès à tout.
|
217 | # Les autres ont un accès restreint.
|
||
218 | 8089d65a | Francois POIROTTE | if not config.is_manager.is_met(request.environ): |
219 | 945bd396 | Francois POIROTTE | supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]] |
220 | fab6312f | Aurelien BOMPARD | # pylint: disable-msg=E1103
|
221 | 7e6517fe | Francois POIROTTE | items = items.join( |
222 | (GroupHierarchy, GroupHierarchy.idchild == \ |
||
223 | SUPITEM_GROUP_TABLE.c.idgroup) |
||
224 | ).filter(GroupHierarchy.idparent.in_(supitemgroups)) |
||
225 | 63aa2a70 | Francois POIROTTE | |
226 | 924533ae | Francois POIROTTE | items = items.limit(limit + 1).all() # pylint: disable-msg=E1103 |
227 | more_results = len(items) > limit
|
||
228 | |||
229 | 7c9baa43 | Francois POIROTTE | if not search_form_graph: |
230 | 924533ae | Francois POIROTTE | for i in xrange(min(limit, len(items))): |
231 | ids.append((items[i].idhost, None))
|
||
232 | 6aec31f5 | Francois POIROTTE | labels.append((items[i].hostname, items[i].address, None))
|
233 | c765e251 | Francois POIROTTE | else:
|
234 | 924533ae | Francois POIROTTE | for i in xrange(min(limit, len(items))): |
235 | ids.append((items[i].idhost, items[i].idgraph)) |
||
236 | 6aec31f5 | Francois POIROTTE | labels.append(( |
237 | items[i].hostname, |
||
238 | items[i].address, |
||
239 | items[i].graphname |
||
240 | )) |
||
241 | 9b5ab541 | Francois POIROTTE | |
242 | 924533ae | Francois POIROTTE | return dict(labels=labels, ids=ids, more=more_results) |
243 | 0f25906a | Francis LAHEUGUERE | |
244 | 9a31cbd1 | Francois POIROTTE | @expose('graphslist.html') |
245 | 0f65a3b8 | Francois POIROTTE | def graphsList(self, graphs=None, **kwargs): |
246 | 2c334d8b | Francis LAHEUGUERE | """
|
247 | 0f65a3b8 | Francois POIROTTE | Génération d'une page d'impression avec les graphes sélectionnés.
|
248 | 09301287 | Francis LAHEUGUERE |
|
249 | 0f65a3b8 | Francois POIROTTE | @param graphs : Liste des graphes à imprimer
|
250 | @type graphs : C{list}
|
||
251 | @param kwargs : arguments supplémentaires (inutilisés)
|
||
252 | @type kwargs : c{dict}
|
||
253 | 2c334d8b | Francis LAHEUGUERE |
|
254 | 0f65a3b8 | Francois POIROTTE | @return: Paramètres pour la génération de la page d'impression
|
255 | @rtype: dict
|
||
256 | 2c334d8b | Francis LAHEUGUERE | """
|
257 | 91a61890 | Francois POIROTTE | # @TODO: le must serait de hot-patcher mootools pour que son serializer
|
258 | # d'URL utilise directement le format attendu par TurboGears
|
||
259 | # (notation pointée plutôt qu'avec des crochets)
|
||
260 | |||
261 | 0f65a3b8 | Francois POIROTTE | if not graphs: |
262 | e2dbeada | Francois POIROTTE | return dict(graphslist=[]) |
263 | |||
264 | 0f65a3b8 | Francois POIROTTE | if not isinstance(graphs, list): |
265 | graphs = [graphs] |
||
266 | |||
267 | 948ecfdf | Francois POIROTTE | # On est obligé de convertir le format en UTF-8 car strftime
|
268 | # n'accepte pas les chaînes Unicode en entrée.
|
||
269 | e2dbeada | Francois POIROTTE | # TRANSLATORS: Format Python de date/heure, lisible par un humain.
|
270 | 948ecfdf | Francois POIROTTE | format = _("%a, %d %b %Y %H:%M:%S").encode('utf8') |
271 | e2dbeada | Francois POIROTTE | graphslist = [] |
272 | 0f65a3b8 | Francois POIROTTE | for graph in graphs: |
273 | params = urlparse.parse_qs(graph, True, True) |
||
274 | 91a61890 | Francois POIROTTE | try:
|
275 | 0f65a3b8 | Francois POIROTTE | host = params['host'][0] |
276 | graph = params['graph'][0] |
||
277 | start = int(params['start'][0] or time.time() - 86400) |
||
278 | duration = int(params['duration'][0]) |
||
279 | nocache = params['nocache'][0] |
||
280 | except (KeyError, TypeError, ValueError): |
||
281 | 91a61890 | Francois POIROTTE | break
|
282 | |||
283 | if not (host and graph and duration and nocache): |
||
284 | break
|
||
285 | |||
286 | graphslist.append({ |
||
287 | 'host': host,
|
||
288 | 'graph': graph,
|
||
289 | 'start': start,
|
||
290 | 'duration': duration,
|
||
291 | 'nocache': nocache,
|
||
292 | 'start_date': time.strftime(format,
|
||
293 | time.localtime(start)).decode('utf8'),
|
||
294 | 'end_date': time.strftime(format,
|
||
295 | time.localtime(start + duration)).decode('utf8')
|
||
296 | }) |
||
297 | c3d8b5c1 | Francis LAHEUGUERE | return dict(graphslist=graphslist) |
298 | ec3ea7ab | Francis LAHEUGUERE | |
299 | 7c9baa43 | Francois POIROTTE | @expose('json') |
300 | ec3ea7ab | Francis LAHEUGUERE | def tempoDelayRefresh(self, nocache=None): |
301 | 2c334d8b | Francis LAHEUGUERE | """
|
302 | 09301287 | Francis LAHEUGUERE | Determination valeur temporisation pour le rafraichissement automatique
|
303 | d un graphe
|
||
304 | 07ad969f | Francis LAHEUGUERE |
|
305 | 5b44cbbd | Francis LAHEUGUERE | @return: valeur de temporisation
|
306 | @rtype: C{str}
|
||
307 | 2c334d8b | Francis LAHEUGUERE | """
|
308 | 07ad969f | Francis LAHEUGUERE | |
309 | e2dbeada | Francois POIROTTE | try:
|
310 | 8fbb76ad | Francois POIROTTE | delay = int(config['refresh_delay']) |
311 | d1850fc4 | Francois POIROTTE | except (ValueError, KeyError): |
312 | 8fbb76ad | Francois POIROTTE | delay = 30
|
313 | 7c9baa43 | Francois POIROTTE | return {'delay': delay} |
314 | 89a96e65 | Francis LAHEUGUERE | |
315 | e2dbeada | Francois POIROTTE | class GetIndicatorsSchema(schema.Schema): |
316 | d1850fc4 | Francois POIROTTE | """Schéma de validation pour la méthode L{getIndicators}."""
|
317 | cfed65e0 | Francois POIROTTE | host = validators.UnicodeString(not_empty=True)
|
318 | graph = validators.UnicodeString(not_empty=True)
|
||
319 | nocache = validators.UnicodeString(if_missing=None)
|
||
320 | e2dbeada | Francois POIROTTE | |
321 | # @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
||
322 | @validate(
|
||
323 | d1850fc4 | Francois POIROTTE | validators = GetIndicatorsSchema(), |
324 | error_handler = process_form_errors) |
||
325 | 89a96e65 | Francis LAHEUGUERE | @expose('json') |
326 | 77b7746d | Francois POIROTTE | def getIndicators(self, host, graph, nocache=None): |
327 | 2c334d8b | Francis LAHEUGUERE | """
|
328 | Liste d indicateurs associes a un graphe
|
||
329 |
|
||
330 | @param graph : graphe
|
||
331 | @type graph : C{str}
|
||
332 |
|
||
333 | 5b44cbbd | Francis LAHEUGUERE | @return: dictionnaire des indicateurs d un graphe
|
334 | @rtype: document json (sous forme de dict)
|
||
335 | 2c334d8b | Francis LAHEUGUERE | """
|
336 | d19e6b55 | Francois POIROTTE | |
337 | a4389258 | Francois POIROTTE | indicators = self.getListIndicators(host, graph)
|
338 | 726122aa | Aurelien BOMPARD | indicators = [(ind.name, ind.label) for ind in indicators] |
339 | c765e251 | Francois POIROTTE | return dict(items=indicators) |
340 | 45dee20d | Francis LAHEUGUERE | |
341 | 726122aa | Aurelien BOMPARD | class StartTimeSchema(schema.Schema): |
342 | """Schéma de validation pour la méthode L{getIndicators}."""
|
||
343 | cfed65e0 | Francois POIROTTE | host = validators.UnicodeString(not_empty=True)
|
344 | nocache = validators.UnicodeString(if_missing=None)
|
||
345 | 726122aa | Aurelien BOMPARD | |
346 | # @TODO définir un error_handler différent pour remonter l'erreur via JS.
|
||
347 | @validate(
|
||
348 | validators = StartTimeSchema(), |
||
349 | error_handler = process_form_errors) |
||
350 | @expose('json') |
||
351 | 77b7746d | Francois POIROTTE | def startTime(self, host, nocache=None): |
352 | c2122f56 | Francois POIROTTE | # urllib2.quote() ne fonctionne pas sur le type unicode.
|
353 | # On transcode d'abord le nom d'hôte en UTF-8.
|
||
354 | quote_host = isinstance(host, unicode) and \ |
||
355 | host.encode('utf-8') or host |
||
356 | 726122aa | Aurelien BOMPARD | return get_through_proxy(
|
357 | 'vigirrd', host,
|
||
358 | c2122f56 | Francois POIROTTE | '/starttime?host=%s' % urllib2.quote(quote_host, '') |
359 | 726122aa | Aurelien BOMPARD | ) |
360 | e2dbeada | Francois POIROTTE | |
361 | class FullHostPageSchema(schema.Schema): |
||
362 | d1850fc4 | Francois POIROTTE | """Schéma de validation pour la méthode L{fullHostPage}."""
|
363 | cfed65e0 | Francois POIROTTE | host = validators.UnicodeString(not_empty=True)
|
364 | e2dbeada | Francois POIROTTE | start = validators.Int(if_missing=None)
|
365 | duration = validators.Int(if_missing=86400)
|
||
366 | |||
367 | fd508021 | Francis LAHEUGUERE | # VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
|
368 | f82ad767 | Francois POIROTTE | # VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes
|
369 | # On utilise la même page pour les 2 fonctionalités.
|
||
370 | e2dbeada | Francois POIROTTE | @validate(
|
371 | d1850fc4 | Francois POIROTTE | validators = FullHostPageSchema(), |
372 | error_handler = process_form_errors) |
||
373 | c1db3132 | Francis LAHEUGUERE | @expose('fullhostpage.html') |
374 | abb1d154 | Francis LAHEUGUERE | def fullHostPage(self, host, start=None, duration=86400): |
375 | """
|
||
376 | 2c334d8b | Francis LAHEUGUERE | Affichage de l'ensemble des graphes associes a un hote
|
377 | 5b44cbbd | Francis LAHEUGUERE | * d apres les donnees RRD
|
378 | * avec une date-heure de debut
|
||
379 | d19e6b55 | Francois POIROTTE | * pour une plage de temps
|
380 |
|
||
381 | 2c334d8b | Francis LAHEUGUERE | @param host : hôte
|
382 | @type host : C{str}
|
||
383 | @param start : date-heure de debut des donnees
|
||
384 | @type start : C{str}
|
||
385 | 8d86738e | Aurelien BOMPARD | @param duration : plage de temps des données. Parametre optionnel,
|
386 | initialisé a 86400 = plage de 1 jour.
|
||
387 | 2c334d8b | Francis LAHEUGUERE | @type duration : C{str}
|
388 |
|
||
389 | 8d86738e | Aurelien BOMPARD | @return: page avec les images des graphes et boutons de deplacement
|
390 | dans le temps
|
||
391 | 09301287 | Francis LAHEUGUERE | @rtype: page html
|
392 | abb1d154 | Francis LAHEUGUERE | """
|
393 | if start is None: |
||
394 | start = int(time.time()) - int(duration) |
||
395 | 75c8d4a7 | Vincent QUEMENER | else:
|
396 | start = int(start)
|
||
397 | 9a31cbd1 | Francois POIROTTE | duration = int(duration)
|
398 | |||
399 | user = get_current_user() |
||
400 | if user is None: |
||
401 | return dict(host=host, start=start, duration=duration, |
||
402 | presets=self.presets, graphs=[])
|
||
403 | |||
404 | 75c8d4a7 | Vincent QUEMENER | # Vérification des permissions de l'utilisateur sur l'hôte.
|
405 | 8089d65a | Francois POIROTTE | if not config.is_manager.is_met(request.environ): |
406 | 75c8d4a7 | Vincent QUEMENER | # Récupération des groupes auxquels l'utilisateur a accès.
|
407 | supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]] |
||
408 | cfed65e0 | Francois POIROTTE | |
409 | # On vérifie que l'hôte en question existe bel et bien.
|
||
410 | host_obj = Host.by_host_name(host) |
||
411 | if not host_obj: |
||
412 | message = _('No such host "%s"') % host
|
||
413 | LOGGER.warning(message) |
||
414 | raise http_exc.HTTPNotFound(message)
|
||
415 | |||
416 | 7e984955 | Vincent QUEMENER | # Récupération des groupes dont l'hôte fait partie
|
417 | cfed65e0 | Francois POIROTTE | hostgroups = [g.idgroup for g in host_obj.groups] |
418 | 7e984955 | Vincent QUEMENER | # Si aucun des groupes de l'hôte ne fait partie des groupes
|
419 | # auxquels l'utilisateur a accès, on affiche une erreur 403.
|
||
420 | if len(set(hostgroups).intersection(set(supitemgroups))) < 1: |
||
421 | 75c8d4a7 | Vincent QUEMENER | message = _('Access denied to host "%s"') % host
|
422 | LOGGER.warning(message) |
||
423 | 24589c11 | Francois POIROTTE | raise http_exc.HTTPForbidden(message)
|
424 | 75c8d4a7 | Vincent QUEMENER | |
425 | # Récupération de la liste des noms des graphes associés à l'hôte.
|
||
426 | 9a31cbd1 | Francois POIROTTE | graphs = DBSession.query( |
427 | Graph.name |
||
428 | ).distinct( |
||
429 | ).join( |
||
430 | (GRAPH_PERFDATASOURCE_TABLE, |
||
431 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
||
432 | (PerfDataSource, PerfDataSource.idperfdatasource == |
||
433 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
||
434 | 60c3c88e | Francois POIROTTE | (Host, Host.idhost == PerfDataSource.idhost), |
435 | e71a38ac | Francois POIROTTE | ).filter(Host.name == host) |
436 | 9a31cbd1 | Francois POIROTTE | |
437 | 63aa2a70 | Francois POIROTTE | graphs = graphs.all() |
438 | 9a31cbd1 | Francois POIROTTE | return dict(host=host, start=start, duration=duration, |
439 | presets=self.presets, graphs=graphs)
|
||
440 | c1db3132 | Francis LAHEUGUERE | |
441 | e2dbeada | Francois POIROTTE | |
442 | cfed65e0 | Francois POIROTTE | class SearchHostSchema(schema.Schema): |
443 | 6aec31f5 | Francois POIROTTE | """Schéma de validation pour la méthode L{searchHost}."""
|
444 | cfed65e0 | Francois POIROTTE | allow_extra_fields = True
|
445 | filter_extra_fields = True
|
||
446 | query = validators.UnicodeString(not_empty=True)
|
||
447 | |||
448 | e4b8d982 | Francois POIROTTE | @expose('searchhost.html') |
449 | cfed65e0 | Francois POIROTTE | @validate(
|
450 | validators = SearchHostSchema(), |
||
451 | error_handler = process_form_errors) |
||
452 | 9773b809 | Francois POIROTTE | @paginate('hosts', items_per_page=10) |
453 | cfed65e0 | Francois POIROTTE | def searchHost(self, query): |
454 | 2c334d8b | Francis LAHEUGUERE | """
|
455 | 9a31cbd1 | Francois POIROTTE | Affiche les résultats de la recherche par nom d'hôte.
|
456 | 2256d3db | Aurelien BOMPARD | La requête de recherche (C{query}) correspond à un préfixe
|
457 | 9a31cbd1 | Francois POIROTTE | qui sera recherché dans le nom d'hôte. Ce préfixe peut
|
458 | contenir les caractères '*' et '?' qui agissent comme des
|
||
459 | "jokers".
|
||
460 |
|
||
461 | 2256d3db | Aurelien BOMPARD | @keyword query: Prefixe de recherche sur les noms d'hôtes
|
462 | @type query: C{unicode}
|
||
463 | 2c334d8b | Francis LAHEUGUERE | """
|
464 | 9a31cbd1 | Francois POIROTTE | if not query: |
465 | redirect("searchHostForm")
|
||
466 | cfed65e0 | Francois POIROTTE | return
|
467 | 10ba3fed | Francis LAHEUGUERE | |
468 | 9a31cbd1 | Francois POIROTTE | query = sql_escape_like(query.strip()) |
469 | user = get_current_user() |
||
470 | if user is None: |
||
471 | return dict(items=[]) |
||
472 | 4fe15b02 | Francis LAHEUGUERE | |
473 | 9a31cbd1 | Francois POIROTTE | # Récupère les hôtes auxquels l'utilisateur a réellement accès.
|
474 | hosts = DBSession.query( |
||
475 | Host.name, |
||
476 | 6aec31f5 | Francois POIROTTE | Host.address, |
477 | 9a31cbd1 | Francois POIROTTE | ).distinct( |
478 | ).join( |
||
479 | 60c3c88e | Francois POIROTTE | (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \ |
480 | Host.idhost), |
||
481 | 6aec31f5 | Francois POIROTTE | ).filter(or_( |
482 | Host.name.like(query + u'%'),
|
||
483 | Host.address.like(query + u'%')
|
||
484 | )).order_by(Host.name.asc(),) |
||
485 | 63aa2a70 | Francois POIROTTE | |
486 | # Les managers ont accès à tout.
|
||
487 | # Les autres ont un accès restreint.
|
||
488 | 8089d65a | Francois POIROTTE | if not config.is_manager.is_met(request.environ): |
489 | 945bd396 | Francois POIROTTE | supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]] |
490 | 7e6517fe | Francois POIROTTE | hosts = hosts.join( |
491 | (GroupHierarchy, GroupHierarchy.idchild == \ |
||
492 | SUPITEM_GROUP_TABLE.c.idgroup) |
||
493 | ).filter(GroupHierarchy.idparent.in_(supitemgroups)) |
||
494 | 63aa2a70 | Francois POIROTTE | |
495 | 6aec31f5 | Francois POIROTTE | return dict(hosts=[(h.name, h.address) for h in hosts]) |
496 | 4fe15b02 | Francis LAHEUGUERE | |
497 | fd508021 | Francis LAHEUGUERE | # VIGILO_EXIG_VIGILO_PERF_0030:Moteur de recherche des graphes
|
498 | c765e251 | Francois POIROTTE | @expose('getopensearch.xml', content_type='text/xml') |
499 | 4fe15b02 | Francis LAHEUGUERE | def getOpenSearch(self): |
500 | 2c334d8b | Francis LAHEUGUERE | """
|
501 | 09301287 | Francis LAHEUGUERE | Moteur de recherche des graphes
|
502 | 2c334d8b | Francis LAHEUGUERE |
|
503 | 5b44cbbd | Francis LAHEUGUERE | @return: document
|
504 | 09301287 | Francis LAHEUGUERE | @rtype: document xml
|
505 | 2c334d8b | Francis LAHEUGUERE | """
|
506 | 9773b809 | Francois POIROTTE | return dict() |
507 | cdde92ac | Francis LAHEUGUERE | |
508 | 7c9baa43 | Francois POIROTTE | @expose('json') |
509 | 704b1fa1 | Aurelien BOMPARD | def hosttree(self, parent_id=None, onlytype="", offset=0, noCache=None): |
510 | cc1a971a | Vincent QUEMENER | """
|
511 | Affiche un étage de l'arbre de
|
||
512 | sélection des hôtes et groupes d'hôtes.
|
||
513 |
|
||
514 | @param parent_id: identifiant du groupe d'hôte parent
|
||
515 | @type parent_id: C{int} or None
|
||
516 | """
|
||
517 | 7c9baa43 | Francois POIROTTE | |
518 | # Si l'identifiant du groupe parent n'est pas
|
||
519 | # spécifié, on retourne la liste des groupes racines,
|
||
520 | 7e6517fe | Francois POIROTTE | # fournie par la méthode get_root_hosts_groups.
|
521 | 7c9baa43 | Francois POIROTTE | if parent_id is None: |
522 | return self.get_root_host_groups() |
||
523 | |||
524 | # TODO: Utiliser un schéma de validation
|
||
525 | parent_id = int(parent_id)
|
||
526 | 704b1fa1 | Aurelien BOMPARD | offset = int(offset)
|
527 | 7e6517fe | Francois POIROTTE | |
528 | # On vérifie si le groupe parent fait partie des
|
||
529 | # groupes auxquel l'utilisateur a accès, et on
|
||
530 | # retourne une liste vide dans le cas contraire
|
||
531 | 8089d65a | Francois POIROTTE | is_manager = config.is_manager.is_met(request.environ) |
532 | 7c9baa43 | Francois POIROTTE | if not is_manager: |
533 | 7e6517fe | Francois POIROTTE | direct_access = False
|
534 | user = get_current_user() |
||
535 | 24589c11 | Francois POIROTTE | |
536 | # On calcule la distance de ce groupe par rapport aux groupes
|
||
537 | # sur lesquels l'utilisateur a explicitement les permissions.
|
||
538 | #
|
||
539 | # La distance est définie ainsi :
|
||
540 | # 0 : l'utilisateur a des droits explicites sur ce groupe.
|
||
541 | # > 0 : l'utilisateur a accès implicitement au groupe.
|
||
542 | # < 0 : l'utilisateur n'a pas d'accès (il peut juste parcourir
|
||
543 | # ce groupe)
|
||
544 | #
|
||
545 | # Il faut 2 étapes pour trouver la distance. La 1ère essaye
|
||
546 | # de trouver une distance >= 0, la 2ème une distance <= 0.
|
||
547 | |||
548 | # Distance positive.
|
||
549 | distance = DBSession.query( |
||
550 | 3c4e7981 | Francois POIROTTE | functions.max(GroupHierarchy.hops) |
551 | 24589c11 | Francois POIROTTE | ).join( |
552 | (Group, Group.idgroup == GroupHierarchy.idparent), |
||
553 | 8d86738e | Aurelien BOMPARD | (DataPermission, |
554 | DataPermission.idgroup == Group.idgroup), |
||
555 | (UserGroup, |
||
556 | UserGroup.idgroup == DataPermission.idusergroup), |
||
557 | 24589c11 | Francois POIROTTE | (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \ |
558 | UserGroup.idgroup), |
||
559 | ).filter(USER_GROUP_TABLE.c.username == user.user_name |
||
560 | f20684bf | Francois POIROTTE | ).filter(Group.grouptype == u'supitemgroup'
|
561 | 24589c11 | Francois POIROTTE | ).filter(GroupHierarchy.idchild == parent_id |
562 | 3c4e7981 | Francois POIROTTE | ).scalar() |
563 | 24589c11 | Francois POIROTTE | |
564 | if distance is None: |
||
565 | # Distance négative.
|
||
566 | distance = DBSession.query( |
||
567 | 3c4e7981 | Francois POIROTTE | functions.max(GroupHierarchy.hops) |
568 | 7e6517fe | Francois POIROTTE | ).join( |
569 | 24589c11 | Francois POIROTTE | (Group, Group.idgroup == GroupHierarchy.idchild), |
570 | 8d86738e | Aurelien BOMPARD | (DataPermission, |
571 | DataPermission.idgroup == Group.idgroup), |
||
572 | (UserGroup, |
||
573 | UserGroup.idgroup == DataPermission.idusergroup), |
||
574 | 24589c11 | Francois POIROTTE | (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \ |
575 | UserGroup.idgroup), |
||
576 | ).filter(USER_GROUP_TABLE.c.username == user.user_name |
||
577 | f20684bf | Francois POIROTTE | ).filter(Group.grouptype == u'supitemgroup'
|
578 | 24589c11 | Francois POIROTTE | ).filter(GroupHierarchy.idparent == parent_id |
579 | 3c4e7981 | Francois POIROTTE | ).scalar() |
580 | 24589c11 | Francois POIROTTE | if distance is not None: |
581 | distance = -distance |
||
582 | |||
583 | if distance is None: |
||
584 | # Pas d'accès à ce groupe.
|
||
585 | return dict(groups = [], items = []) |
||
586 | |||
587 | direct_access = distance >= 0
|
||
588 | 7e6517fe | Francois POIROTTE | |
589 | 704b1fa1 | Aurelien BOMPARD | limit = int(config.get("max_menu_entries", 20)) |
590 | result = {"groups": [], "items": []} |
||
591 | |||
592 | if not onlytype or onlytype == "group": |
||
593 | # On récupère la liste des groupes dont
|
||
594 | # l'identifiant du parent est passé en paramètre
|
||
595 | 24589c11 | Francois POIROTTE | gh1 = aliased(GroupHierarchy, name='gh1')
|
596 | gh2 = aliased(GroupHierarchy, name='gh2')
|
||
597 | |||
598 | 704b1fa1 | Aurelien BOMPARD | db_groups = DBSession.query( |
599 | SupItemGroup |
||
600 | 24589c11 | Francois POIROTTE | ).options(lazyload('_path_obj')
|
601 | ).distinct( |
||
602 | 704b1fa1 | Aurelien BOMPARD | ).join( |
603 | 24589c11 | Francois POIROTTE | (gh1, gh1.idchild == SupItemGroup.idgroup), |
604 | ).filter(gh1.hops == 1
|
||
605 | ).filter(gh1.idparent == parent_id |
||
606 | 704b1fa1 | Aurelien BOMPARD | ).order_by(SupItemGroup.name.asc()) |
607 | 24589c11 | Francois POIROTTE | |
608 | 704b1fa1 | Aurelien BOMPARD | if not is_manager and not direct_access: |
609 | 24589c11 | Francois POIROTTE | # On ne doit afficher que les fils du groupe <parent_id>
|
610 | # tels que l'utilisateur a accès explicitement à l'un
|
||
611 | # des fils de l'un de ces groupes.
|
||
612 | db_groups = db_groups.join( |
||
613 | (gh2, gh2.idparent == gh1.idchild), |
||
614 | 8d86738e | Aurelien BOMPARD | (DataPermission, |
615 | DataPermission.idgroup == gh2.idchild), |
||
616 | (UserGroup, |
||
617 | UserGroup.idgroup == DataPermission.idusergroup), |
||
618 | (USER_GROUP_TABLE, |
||
619 | USER_GROUP_TABLE.c.idgroup == UserGroup.idgroup), |
||
620 | 24589c11 | Francois POIROTTE | ).filter(USER_GROUP_TABLE.c.username == user.user_name) |
621 | 704b1fa1 | Aurelien BOMPARD | |
622 | num_children_left = db_groups.count() - offset |
||
623 | if offset:
|
||
624 | result["continued_from"] = offset
|
||
625 | result["continued_type"] = "group" |
||
626 | all_groups = db_groups.limit(limit).offset(offset).all() |
||
627 | for group in all_groups: |
||
628 | result["groups"].append({
|
||
629 | 'id' : group.idgroup,
|
||
630 | 'name' : group.name,
|
||
631 | 'type' : "group", |
||
632 | }) |
||
633 | if num_children_left > limit:
|
||
634 | result["groups"].append({
|
||
635 | 'name': _("Next %(limit)s") % {"limit": limit}, |
||
636 | 'offset': offset + limit,
|
||
637 | 'parent_id': parent_id,
|
||
638 | 'type': 'continued', |
||
639 | 'for_type': 'group', |
||
640 | }) |
||
641 | 7c9baa43 | Francois POIROTTE | |
642 | # On récupère la liste des hôtes appartenant au
|
||
643 | # groupe dont l'identifiant est passé en paramètre
|
||
644 | 704b1fa1 | Aurelien BOMPARD | if ((not onlytype or onlytype == "item") |
645 | and (is_manager or direct_access)): |
||
646 | 7c9baa43 | Francois POIROTTE | db_hosts = DBSession.query( |
647 | Host.idhost, |
||
648 | Host.name, |
||
649 | ).join( |
||
650 | 7e6517fe | Francois POIROTTE | (SUPITEM_GROUP_TABLE, |
651 | SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost |
||
652 | ), |
||
653 | 7c9baa43 | Francois POIROTTE | ).filter(SUPITEM_GROUP_TABLE.c.idgroup == parent_id |
654 | ).order_by(Host.name.asc()) |
||
655 | 704b1fa1 | Aurelien BOMPARD | num_children_left = db_hosts.count() - offset |
656 | if offset:
|
||
657 | result["continued_from"] = offset
|
||
658 | result["continued_type"] = "item" |
||
659 | all_hosts = db_hosts.limit(limit).offset(offset).all() |
||
660 | for host in all_hosts: |
||
661 | result["items"].append({
|
||
662 | 7c9baa43 | Francois POIROTTE | 'id' : host.idhost,
|
663 | 'name' : host.name,
|
||
664 | 704b1fa1 | Aurelien BOMPARD | 'type' : "item", |
665 | }) |
||
666 | if num_children_left > limit:
|
||
667 | result["items"].append({
|
||
668 | 'name': _("Next %(limit)s") % {"limit": limit}, |
||
669 | 'offset': offset + limit,
|
||
670 | 'parent_id': parent_id,
|
||
671 | 'type': 'continued', |
||
672 | 'for_type': 'item', |
||
673 | 7c9baa43 | Francois POIROTTE | }) |
674 | |||
675 | 704b1fa1 | Aurelien BOMPARD | return result
|
676 | 7c9baa43 | Francois POIROTTE | |
677 | @expose('json') |
||
678 | 704b1fa1 | Aurelien BOMPARD | def graphtree(self, host_id=None, parent_id=None, offset=0, noCache=None): |
679 | cc1a971a | Vincent QUEMENER | """
|
680 | Affiche un étage de l'arbre de sélection
|
||
681 | des graphes et groupes de graphes.
|
||
682 |
|
||
683 | @param parent_id: identifiant du groupe de graphes parent
|
||
684 | @type parent_id: C{int} or None
|
||
685 | """
|
||
686 | 7c9baa43 | Francois POIROTTE | |
687 | # Si l'identifiant de l'hôte n'est pas spécifié, on
|
||
688 | # retourne un dictionnaire contenant deux listes vides
|
||
689 | if host_id is None: |
||
690 | 7e6517fe | Francois POIROTTE | return dict(groups = [], graphs=[]) |
691 | 7c9baa43 | Francois POIROTTE | |
692 | # On vérifie les permissions sur l'hôte
|
||
693 | # TODO: Utiliser un schéma de validation
|
||
694 | host_id = int(host_id)
|
||
695 | 7e6517fe | Francois POIROTTE | host = DBSession.query(Host |
696 | ).filter(Host.idhost == host_id |
||
697 | ).first() |
||
698 | 7c9baa43 | Francois POIROTTE | if host is None: |
699 | 7e6517fe | Francois POIROTTE | return dict(groups = [], graphs=[]) |
700 | 7c9baa43 | Francois POIROTTE | user = get_current_user() |
701 | if not host.is_allowed_for(user): |
||
702 | 7e6517fe | Francois POIROTTE | return dict(groups = [], graphs=[]) |
703 | 7c9baa43 | Francois POIROTTE | |
704 | b6d2af46 | Vincent QUEMENER | # On récupère la liste des groupes de graphes associés à l'hôte
|
705 | 7c9baa43 | Francois POIROTTE | host_graph_groups = DBSession.query( |
706 | GraphGroup |
||
707 | ).distinct( |
||
708 | ).join( |
||
709 | (GRAPH_GROUP_TABLE, \ |
||
710 | GRAPH_GROUP_TABLE.c.idgroup == GraphGroup.idgroup), |
||
711 | (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph), |
||
712 | (GRAPH_PERFDATASOURCE_TABLE, \ |
||
713 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
||
714 | (PerfDataSource, PerfDataSource.idperfdatasource == \ |
||
715 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
||
716 | 7e6517fe | Francois POIROTTE | (SUPITEM_GROUP_TABLE, \ |
717 | SUPITEM_GROUP_TABLE.c.idsupitem == PerfDataSource.idhost), |
||
718 | 7c9baa43 | Francois POIROTTE | ).filter(PerfDataSource.idhost == host_id |
719 | 7e6517fe | Francois POIROTTE | ).order_by(GraphGroup.name.asc() |
720 | ).all() |
||
721 | 7c9baa43 | Francois POIROTTE | |
722 | # Si l'identifiant du groupe parent n'est pas spécifié,
|
||
723 | # on récupère la liste des groupes de graphes racines.
|
||
724 | if parent_id is None: |
||
725 | 7e6517fe | Francois POIROTTE | graph_groups = GraphGroup.get_top_groups() |
726 | 7c9baa43 | Francois POIROTTE | |
727 | # Sinon on récupère la liste des graphes dont le
|
||
728 | 7e6517fe | Francois POIROTTE | # groupe passé en paramètre est le parent direct
|
729 | 7c9baa43 | Francois POIROTTE | else:
|
730 | # TODO: Utiliser un schéma de validation
|
||
731 | parent_id = int(parent_id)
|
||
732 | 7e6517fe | Francois POIROTTE | graph_groups = DBSession.query( |
733 | GraphGroup |
||
734 | ).join( |
||
735 | (GroupHierarchy, GroupHierarchy.idchild == \ |
||
736 | GraphGroup.idgroup), |
||
737 | ).filter(GroupHierarchy.hops == 1
|
||
738 | ).filter(GroupHierarchy.idparent == parent_id |
||
739 | ).order_by(GraphGroup.name.asc() |
||
740 | ).all() |
||
741 | 7c9baa43 | Francois POIROTTE | |
742 | # On réalise l'intersection des deux listes
|
||
743 | groups = [] |
||
744 | for gg in graph_groups: |
||
745 | if gg in host_graph_groups: |
||
746 | groups.append({ |
||
747 | 'id' : gg.idgroup,
|
||
748 | 'name' : gg.name,
|
||
749 | 704b1fa1 | Aurelien BOMPARD | 'type' : "group", |
750 | 7c9baa43 | Francois POIROTTE | }) |
751 | |||
752 | # On récupère la liste des graphes appartenant au
|
||
753 | # groupe dont l'identifiant est passé en paramètre
|
||
754 | graphs = [] |
||
755 | if parent_id:
|
||
756 | db_graphs = DBSession.query( |
||
757 | Graph.idgraph, |
||
758 | Graph.name, |
||
759 | b6d2af46 | Vincent QUEMENER | ).distinct( |
760 | 7c9baa43 | Francois POIROTTE | ).join( |
761 | (GRAPH_GROUP_TABLE, |
||
762 | b6d2af46 | Vincent QUEMENER | GRAPH_GROUP_TABLE.c.idgraph == Graph.idgraph), |
763 | (GRAPH_PERFDATASOURCE_TABLE, |
||
764 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph), |
||
765 | (PerfDataSource, |
||
766 | PerfDataSource.idperfdatasource == \ |
||
767 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource), |
||
768 | 7c9baa43 | Francois POIROTTE | ).filter(GRAPH_GROUP_TABLE.c.idgroup == parent_id |
769 | b6d2af46 | Vincent QUEMENER | ).filter(PerfDataSource.idhost == host_id |
770 | 7c9baa43 | Francois POIROTTE | ).order_by(Graph.name.asc()) |
771 | for graph in db_graphs.all(): |
||
772 | graphs.append({ |
||
773 | 'id' : graph.idgraph,
|
||
774 | 'name' : graph.name,
|
||
775 | 704b1fa1 | Aurelien BOMPARD | 'type' : "item", |
776 | 7c9baa43 | Francois POIROTTE | }) |
777 | |||
778 | 704b1fa1 | Aurelien BOMPARD | return dict(groups=groups, items=graphs) |
779 | 7c9baa43 | Francois POIROTTE | |
780 | def get_root_host_groups(self): |
||
781 | """
|
||
782 | Retourne tous les groupes racines (c'est à dire n'ayant
|
||
783 | aucun parent) d'hôtes auquel l'utilisateur a accès.
|
||
784 |
|
||
785 | @return: Un dictionnaire contenant la liste de ces groupes.
|
||
786 | @rtype : C{dict} of C{list} of C{dict} of C{mixed}
|
||
787 | """
|
||
788 | |||
789 | 7e6517fe | Francois POIROTTE | # On récupère tous les groupes qui ont un parent.
|
790 | children = DBSession.query( |
||
791 | SupItemGroup, |
||
792 | ).distinct( |
||
793 | ).join( |
||
794 | (GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup) |
||
795 | ).filter(GroupHierarchy.hops > 0)
|
||
796 | |||
797 | # Ensuite on les exclut de la liste des groupes,
|
||
798 | # pour ne garder que ceux qui sont au sommet de
|
||
799 | # l'arbre et qui constituent nos "root groups".
|
||
800 | root_groups = DBSession.query( |
||
801 | SupItemGroup, |
||
802 | ).except_(children |
||
803 | ).order_by(SupItemGroup.name) |
||
804 | 7c9baa43 | Francois POIROTTE | |
805 | # On filtre ces groupes racines afin de ne
|
||
806 | # retourner que ceux auquels l'utilisateur a accès
|
||
807 | user = get_current_user() |
||
808 | 8089d65a | Francois POIROTTE | if not config.is_manager.is_met(request.environ): |
809 | 7e6517fe | Francois POIROTTE | user_groups = [ug[0] for ug in user.supitemgroups()] |
810 | root_groups = root_groups.filter( |
||
811 | SupItemGroup.idgroup.in_(user_groups)) |
||
812 | 7c9baa43 | Francois POIROTTE | |
813 | groups = [] |
||
814 | 7e6517fe | Francois POIROTTE | for group in root_groups.all(): |
815 | 7c9baa43 | Francois POIROTTE | groups.append({ |
816 | 'id' : group.idgroup,
|
||
817 | 'name' : group.name,
|
||
818 | 704b1fa1 | Aurelien BOMPARD | 'type' : "group", |
819 | 7c9baa43 | Francois POIROTTE | }) |
820 | |||
821 | 3e3db819 | Aurelien BOMPARD | return dict(groups=groups, items=[]) |
822 | b6d2af46 | Vincent QUEMENER | |
823 | a4389258 | Francois POIROTTE | def getListIndicators(self, host, graph): |
824 | 2c334d8b | Francis LAHEUGUERE | """
|
825 | 2ed2fd99 | Francois POIROTTE | Liste d indicateurs associes a un graphe
|
826 | cdde92ac | Francis LAHEUGUERE |
|
827 | 2ed2fd99 | Francois POIROTTE | @param graph : graphe
|
828 | @type graph : C{str}
|
||
829 | 2c334d8b | Francis LAHEUGUERE |
|
830 | 2ed2fd99 | Francois POIROTTE | @return: liste d indicateurs
|
831 | @rtype : list
|
||
832 | 2c334d8b | Francis LAHEUGUERE | """
|
833 | |||
834 | 2ed2fd99 | Francois POIROTTE | indicators = [] |
835 | if graph is not None: |
||
836 | 60c3c88e | Francois POIROTTE | indicators = DBSession.query( |
837 | 726122aa | Aurelien BOMPARD | PerfDataSource.name, PerfDataSource.label |
838 | a4389258 | Francois POIROTTE | ).distinct( |
839 | 60c3c88e | Francois POIROTTE | ).join( |
840 | (GRAPH_PERFDATASOURCE_TABLE, \ |
||
841 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
||
842 | PerfDataSource.idperfdatasource), |
||
843 | (Graph, Graph.idgraph == \ |
||
844 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph), |
||
845 | a4389258 | Francois POIROTTE | (Host, Host.idhost == PerfDataSource.idhost), |
846 | 60c3c88e | Francois POIROTTE | ).filter(Graph.name == graph |
847 | a4389258 | Francois POIROTTE | ).filter(Host.name == host |
848 | 60c3c88e | Francois POIROTTE | ).all() |
849 | 2ed2fd99 | Francois POIROTTE | return indicators
|
850 | aed0c054 | Aurelien BOMPARD | |
851 | @expose('json') |
||
852 | def dbmtime(self): |
||
853 | change = Change.by_table_name(u"Graph")
|
||
854 | if change is None: |
||
855 | return {"mtime": None} |
||
856 | mtime = change.last_modified.replace(microsecond=0)
|
||
857 | return {"mtime": mtime} |
||
858 | 8f6567c2 | Francois POIROTTE | |
859 | @expose('json') |
||
860 | def selectHostAndGraph(self, host, graph): |
||
861 | # @TODO: vérifier les permissions
|
||
862 | ids = DBSession.query( |
||
863 | Host.idhost, Graph.idgraph |
||
864 | ).join( |
||
865 | (PerfDataSource, PerfDataSource.idhost == Host.idhost), |
||
866 | (GRAPH_PERFDATASOURCE_TABLE, \ |
||
867 | GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
||
868 | PerfDataSource.idperfdatasource), |
||
869 | (Graph, Graph.idgraph == \ |
||
870 | GRAPH_PERFDATASOURCE_TABLE.c.idgraph), |
||
871 | ).filter(Graph.name == unicode(graph)
|
||
872 | ).filter(Host.name == unicode(host)
|
||
873 | ).first() |
||
874 | |||
875 | return {
|
||
876 | 'idhost': ids and ids.idhost or None, |
||
877 | 'idgraph': ids and ids.idgraph or None, |
||
878 | } |
||
879 | 71acc6fa | Francois POIROTTE | |
880 | @expose('json') |
||
881 | def external_links(self): |
||
882 | return dict(links=config['external_links']) |