Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigigraph / vigigraph / controllers / rpc.py @ 60c3c88e

History | View | Annotate | Download (29.9 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 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-access',
56
                msg=l_("You don't have 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 = [sig[0] for sig in user.supitemgroups() if sig[1]]
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 = [sig[0] for sig in user.supitemgroups() if sig[1]]
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 = [sig[0] for sig in user.supitemgroups() if sig[1]]
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
            ).join(
217
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
218
                    Host.idhost),
219
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup == othergroupid
220
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup.in_(groups_with_parents)
221
            ).order_by(
222
                Host.name.asc(),
223
            ).all()
224
            
225
        hosts = [(h.name, str(h.idhost)) for h in hosts]
226
        return dict(items=hosts)
227

    
228
    class GraphGroupsSchema(schema.Schema):
229
        """Schéma de validation pour la méthode L{graphgroups}."""
230
        idhost = validators.Int(not_empty=True)
231
        nocache = validators.String(if_missing=None)
232

    
233
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
234
    @validate(
235
        validators = GraphGroupsSchema(),
236
        error_handler = process_form_errors)
237
    @expose('json')
238
    def graphgroups(self, idhost, nocache):
239
        """
240
        Determination des groupes de graphes associes a l hote
241
        dont identificateur = argument
242

243
        @param idhost : identificateur d un hote
244
        @type idhost : int
245

246
        @return: groupes de service
247
        @rtype: document json (sous forme de dict)
248
        """
249
        user = get_current_user()
250
        if user is None:
251
            return dict(items=[])
252

    
253
        graphgroups = DBSession.query(
254
                GraphGroup.name,
255
                GraphGroup.idgroup,
256
            ).distinct(
257
            ).join(
258
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
259
                    GraphGroup.idgroup),
260
                (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
261
                (GRAPH_PERFDATASOURCE_TABLE, \
262
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
263
                (PerfDataSource, PerfDataSource.idperfdatasource == \
264
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
265
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
266
                    PerfDataSource.idhost),
267
            ).filter(PerfDataSource.idhost == idhost
268
            ).order_by(GraphGroup.name.asc())
269

    
270
        # Les managers ont accès à tout.
271
        # Les autres ont un accès restreint.
272
        is_manager = in_group('managers').is_met(request.environ)
273
        if not is_manager:
274
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
275
            graphgroups = graphgroups.filter(
276
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
277
        
278
        graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups.all()]
279
        return dict(items=graphgroups)
280

    
281
    class GraphsSchema(schema.Schema):
282
        """Schéma de validation pour la méthode L{graphs}."""
283
        idgraphgroup = validators.Int(not_empty=True)
284
        idhost = validators.Int(not_empty=True)
285
        nocache = validators.String(if_missing=None)
286

    
287
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
288
    @validate(
289
        validators = GraphsSchema(),
290
        error_handler = process_form_errors)
291
    @expose('json')
292
    def graphs(self, idgraphgroup, idhost, nocache):
293
        """
294
        Determination des graphes
295
        avec un service dont identificateur = argument
296

297
        @param idgraph : identificateur d un service
298
        @type idgraph : int
299

300
        @return: graphes
301
        @rtype: document json (sous forme de dict)
302
        """
303
        user = get_current_user()
304
        if user is None:
305
            return dict(items=[])
306

    
307
        graphs = DBSession.query(
308
                Graph.name,
309
                Graph.idgraph,
310
            ).distinct().join(
311
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgraph == \
312
                    Graph.idgraph),
313
                (GraphGroup, GraphGroup.idgroup == \
314
                    GRAPH_GROUP_TABLE.c.idgroup),
315
                (GRAPH_PERFDATASOURCE_TABLE, \
316
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
317
                (PerfDataSource, PerfDataSource.idperfdatasource == \
318
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
319
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
320
                    PerfDataSource.idhost),
321
            ).filter(GraphGroup.idgroup == idgraphgroup
322
            ).filter(PerfDataSource.idhost == idhost
323
            ).order_by(Graph.name.asc())
324

    
325
        # Les managers ont accès à tout.
326
        # Les autres ont un accès restreint.
327
        is_manager = in_group('managers').is_met(request.environ)
328
        if not is_manager:
329
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
330
            graphs = graphs.filter(
331
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
332

    
333
        graphs = [(pds.name, str(pds.idgraph)) for pds in graphs.all()]
334
        return dict(items=graphs)
335

    
336
    class SearchHostAndGraphSchema(schema.Schema):
337
        """Schéma de validation pour la méthode L{searchHostAndGraph}."""
338
        host = validators.String(if_missing=None)
339
        graph = validators.String(if_missing=None)
340
        nocache = validators.String(if_missing=None)
341

    
342
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
343
    @validate(
344
        validators = SearchHostAndGraphSchema(),
345
        error_handler = process_form_errors)
346
    @expose('json')
347
    def searchHostAndGraph(self, host, graph, nocache):
348
        """
349
        Determination des couples (hote-graphe) repondant aux criteres de
350
        recherche sur hote et/ou graphe.
351

352
        Un critere peut correspondre a un intitule complet hote ou graphe
353
        ou a un extrait.
354

355
        @param kwargs : arguments nommes
356
        @type kwargs : dict
357
                         ( arguments nommes -> host et graphe )
358

359
        @return: couples hote-graphe
360
        @rtype: document json (sous forme de dict)
361
        """
362
        user = get_current_user()
363
        items = []
364

    
365
        if user is None:
366
            return dict(items=[])
367

    
368
        # On a un nom d'indicateur, mais pas de nom d'hôte,
369
        # on considère que l'utilisateur veut tous les indicateurs
370
        # correspondant au motif, quel que soit l'hôte.
371
        if graph is not None:
372
            if host is None:
373
                host = '*'
374

    
375
            host = sql_escape_like(host)
376
            graph = sql_escape_like(graph)
377

    
378
            items = DBSession.query(
379
                    Host.name.label('hostname'),
380
                    Graph.name.label('graphname'),
381
                ).distinct().join(
382
                    (PerfDataSource, PerfDataSource.idhost == Host.idhost),
383
                    (GRAPH_PERFDATASOURCE_TABLE, \
384
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
385
                        PerfDataSource.idperfdatasource),
386
                    (Graph, Graph.idgraph == \
387
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
388
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
389
                        Host.idhost),
390
                ).filter(Host.name.ilike('%' + host + '%')
391
                ).filter(Graph.name.ilike('%' + graph + '%')
392
                ).order_by(
393
                    Host.name.asc(),
394
                    Graph.name.asc(),
395
                )
396

    
397
        # On a ni hôte, ni indicateur. On renvoie une liste vide.
398
        # Si l'utilisateur voulait vraiment quelque chose,
399
        # il n'avait qu'à le demander.
400
        elif host is None:
401
            return []
402

    
403
        # Sinon, on a juste un motif pour un hôte.
404
        # On renvoie la liste des hôtes correspondant.
405
        else:
406
            host = sql_escape_like(host)
407
            items = DBSession.query(
408
                    Host.name.label('hostname'),
409
                ).join(
410
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
411
                        Host.idhost),
412
                ).filter(Host.name.ilike('%' + host + '%')
413
                ).order_by(Host.name.asc())
414

    
415
        # Les managers ont accès à tout.
416
        # Les autres ont un accès restreint.
417
        is_manager = in_group('managers').is_met(request.environ)
418
        if not is_manager:
419
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
420
            items = items.filter(
421
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
422

    
423
        items = items.limit(100).all()
424
        if graph is None:
425
            items = [(item.hostname, "") for item in items]
426
        else:
427
            items = [(item.hostname, item.graphname) for item in items]
428
        return dict(items=items)
429

    
430
    class SelectHostAndGraphSchema(schema.Schema):
431
        """Schéma de validation pour la méthode L{selectHostAndGraph}."""
432
        host = validators.String(if_missing=None)
433
        graph = validators.String(if_missing=None)
434
        nocache = validators.String(if_missing=None)
435

    
436
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
437
    @validate(
438
        validators = SelectHostAndGraphSchema(),
439
        error_handler = process_form_errors)
440
    @expose('json')
441
    def selectHostAndGraph(self, host, graph, nocache):
442
        """
443
        Renvoie les valeurs à sélectionner dans les comboboxes
444
        de VigiGraph pour afficher les données de l'hôte ou du
445
        couple hôte/graphe sélectionné.
446

447
        La clé "items" du dictionnaire renvoyé contient une liste avec
448
        2 éléments, chacun de ces éléments étant lui-même une liste.
449
        La 1ère liste contient les noms des groupes d'hôtes à sélectionner.
450
        La 2ème liste contient la liste des groupes de graphes à sélectionner.
451

452
        Pour le moment, la 2ème liste contiendra au plus 1 élément car
453
        les groupes de graphes ne sont pas récursifs. L'utilisation d'une
454
        liste permet d'assurer facilement une évolution vers des groupes
455
        de graphes récursifs.
456
        """
457

    
458
        # Ce cas ne devrait pas se produire, mais on tente
459
        # d'avoir un comportement gracieux malgré tout.
460
        if (not host) and (not graph):
461
            return dict(items=[[], []])
462

    
463
        selected_hostgroups = []
464
        selected_graphgroups = []
465

    
466
        # @TODO: ajouter la gestion des permissions au code qui suit.
467
        # Pour le moment, la récupération de idsupitemgroup & idgraphgroup
468
        # ne prend pas en compte les permissions réelles de l'utilisateur.
469

    
470
        if host:
471
            # Sélectionne l'identifiant du premier SupItemGroup auquel
472
            # l'utilisateur a accès et auquel l'hôte donné appartient.
473
            idsupitemgroup = DBSession.query(
474
                    SupItemGroup.idgroup,
475
                ).distinct().join(
476
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idgroup == \
477
                        SupItemGroup.idgroup),
478
                    (Host, Host.idhost == SUPITEM_GROUP_TABLE.c.idsupitem),
479
                ).filter(Host.name == host
480
                ).scalar()
481

    
482
            # Si on a trouvé un tel groupe, on renvoie les noms des
483
            # groupes de la hiérarchie à sélectionner pour arriver
484
            # à celui-ci.
485
            if idsupitemgroup is not None:
486
                selected_hostgroups = DBSession.query(
487
                        SupItemGroup.name,
488
                    ).distinct().join(
489
                        (GroupHierarchy, GroupHierarchy.idparent == \
490
                            GraphGroup.idgroup),
491
                    ).filter(GroupHierarchy.idchild == idsupitemgroup
492
                    ).order_by(
493
                        GroupHierarchy.hops.desc()
494
                    ).all()
495

    
496
        if graph:
497
            # Le principe est le même que pour l'hôte, en considérant
498
            # cette fois les GraphGroup à la place des SupItemGroup.
499
            idgraphgroup = DBSession.query(
500
                    GraphGroup.idgroup,
501
                ).distinct().join(
502
                    (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
503
                        GraphGroup.idgroup),
504
                    (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
505
                ).filter(Graph.name == graph
506
                ).scalar()
507

    
508
            # Même principe que pour l'hôte.
509
            if idgraphgroup is not None:
510
                selected_graphgroups = DBSession.query(
511
                        GraphGroup.name,
512
                    ).distinct().join(
513
                        (GroupHierarchy, GroupHierarchy.idparent == \
514
                            GraphGroup.idgroup),
515
                    ).filter(GroupHierarchy.idchild == idgraphgroup
516
                    ).order_by(
517
                        GroupHierarchy.hops.desc()
518
                    ).all()
519

    
520
        hostgroups = [hg.name for hg in selected_hostgroups]
521
        graphgroups = [gg.name for gg in selected_graphgroups]
522
        return dict(items=[hostgroups, graphgroups])        
523

    
524
    @expose('graphslist.html')
525
    def graphsList(self, nocache=None, **kwargs):
526
        """
527
        Generation document avec url des graphes affiches
528
        (pour l impression )
529

530
        @param kwargs : arguments nommes
531
        @type kwargs  : dict
532

533
        @return: url de graphes
534
        @rtype: document html
535
        """
536
        if not kwargs:
537
            return dict(graphslist=[])
538

    
539
        # TRANSLATORS: Format Python de date/heure, lisible par un humain.
540
        format = _("%a, %d %b %Y %H:%M:%S")
541
        graphslist = []
542
        for url in kwargs.itervalues():
543
            parts = urlparse.urlparse(url)
544
            params = dict(parse_qsl(parts.query))
545

    
546
            graph = {}
547
            start = int(params.get('start', time.time() - 86400))
548
            duration = int(params.get('duration', 86400))
549

    
550
            graph['graph'] = params.get('graphtemplate')
551
            graph['start_date'] = time.strftime(format, time.localtime(start))
552
            graph['end_date'] = time.strftime(format,
553
                                    time.localtime(start + duration))
554
            graph['img_src'] = url
555
            graph['host'] = params['host']
556
            graphslist.append(graph)
557
        return dict(graphslist=graphslist)
558

    
559
    @expose(content_type='text/plain')
560
    def tempoDelayRefresh(self, nocache=None):
561
        """
562
        Determination valeur temporisation pour le rafraichissement automatique
563
        d un graphe
564

565
        @return: valeur de temporisation
566
        @rtype: C{str}
567
        """
568

    
569
        try:
570
            delay = int(config['delay_refresh'])
571
        except (ValueError, KeyError):
572
            delay = 36000
573
        return str(delay)
574

    
575
    class GetIndicatorsSchema(schema.Schema):
576
        """Schéma de validation pour la méthode L{getIndicators}."""
577
        graph = validators.String(not_empty=True)
578
        nocache = validators.String(if_missing=None)
579

    
580
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
581
    @validate(
582
        validators = GetIndicatorsSchema(),
583
        error_handler = process_form_errors)
584
    @expose('json')
585
    def getIndicators(self, graph, nocache):
586
        """
587
        Liste d indicateurs associes a un graphe
588

589
        @param graph : graphe
590
        @type graph  : C{str}
591

592
        @return: dictionnaire des indicateurs d un graphe
593
        @rtype: document json (sous forme de dict)
594
        """
595

    
596
        indicators = self.getListIndicators(graph)
597
        indicators = [ind.name for ind in indicators]
598
        return dict(items=indicators)
599

    
600

    
601
    class FullHostPageSchema(schema.Schema):
602
        """Schéma de validation pour la méthode L{fullHostPage}."""
603
        host = validators.String(not_empty=True)
604
        start = validators.Int(if_missing=None)
605
        duration = validators.Int(if_missing=86400)
606

    
607
    # VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
608
    @validate(
609
        validators = FullHostPageSchema(),
610
        error_handler = process_form_errors)
611
    @expose('fullhostpage.html')
612
    def fullHostPage(self, host, start=None, duration=86400):
613
        """
614
        Affichage de l'ensemble des graphes associes a un hote
615
        * d apres les donnees RRD
616
        * avec une date-heure de debut
617
        * pour une plage de temps 
618
        
619
        @param host : hôte
620
        @type host : C{str}
621
        @param start : date-heure de debut des donnees
622
        @type start : C{str}
623
        @param duration : plage de temps des données
624
        @type duration : C{str}
625
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
626

627
        @return: page avec les images des graphes et boutons de deplacement dans le temps
628
        @rtype: page html
629
        """
630

    
631
        if start is None:
632
            start = int(time.time()) - int(duration)
633

    
634
        start = int(start)
635
        duration = int(duration)
636

    
637
        user = get_current_user()
638
        if user is None:
639
            return dict(host=host, start=start, duration=duration,
640
                        presets=self.presets, graphs=[])
641

    
642
        # Récupération de la liste des noms des graphes,
643
        # avec vérification des permissions de l'utilisateur.
644
        graphs = DBSession.query(
645
                Graph.name
646
            ).distinct(
647
            ).join(
648
                (GRAPH_PERFDATASOURCE_TABLE,
649
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
650
                (PerfDataSource, PerfDataSource.idperfdatasource ==
651
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
652
                (Host, Host.idhost == PerfDataSource.idhost),
653
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
654
                    Host.idhost),
655
            )
656

    
657
        # Les managers ont accès à tout.
658
        # Les autres ont un accès restreint.
659
        is_manager = in_group('managers').is_met(request.environ)
660
        if not is_manager:
661
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
662
            graphs = graphs.filter(
663
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
664

    
665
        graphs = graphs.all()
666
        return dict(host=host, start=start, duration=duration,
667
                    presets=self.presets, graphs=graphs)
668

    
669

    
670
    class SingleGraphSchema(schema.Schema):
671
        """Schéma de validation pour la méthode L{singleGraph}."""
672
        host = validators.String(not_empty=True)
673
        graph = validators.String(not_empty=True)
674
        start = validators.Int(if_missing=None)
675
        duration = validators.Int(if_missing=86400)
676

    
677
    # VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes
678
    @validate(
679
        validators = SingleGraphSchema(),
680
        error_handler = process_form_errors)
681
    @expose('singlegraph.html')
682
    def singleGraph(self, host, graph, start, duration):
683
        """
684
        Affichage d un graphe associe a un hote et un graphe
685
        * d apres les donnees RRD
686
        * avec une date-heure de debut
687
        * pour une plage de temps 
688
        
689
        @param host : hôte
690
        @type host : C{str}
691
        @param graph : graphe
692
        @type graph  : C{str}
693
        @param start : date-heure de debut des donnees
694
        @type start : C{str}
695
        @param duration : plage de temps des données 
696
        @type duration : C{str}
697
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
698

699
        @return: page avec l image du graphe et boutons de deplacement dans le temps
700
        @rtype: page html
701
        """
702

    
703
        if start is None:
704
            start = int(time.time()) - int(duration)
705

    
706
        start = int(start)
707
        duration = int(duration)
708

    
709
        return dict(host=host, graph=graph, start=start, duration=duration, \
710
                    presets=self.presets)
711

    
712
    @expose('searchhostform.html')
713
    def searchHostForm(self):
714
        """
715
        Formulaire de recherche sur les hotes
716

717
        @return: page avec formulaire de recherche
718
        @rtype: page html
719
        """
720
        searchhostform = SearchHostForm('search_host_form', \
721
            submit_text=None)
722

    
723
        return dict(searchhostform=searchhostform)
724

    
725
    @expose('searchhost.html')
726
    @paginate('hosts', items_per_page=10)
727
    def searchHost(self, *args, **kwargs):
728
        """
729
        Affiche les résultats de la recherche par nom d'hôte.
730
        La requête de recherche (L{query}) correspond à un préfixe
731
        qui sera recherché dans le nom d'hôte. Ce préfixe peut
732
        contenir les caractères '*' et '?' qui agissent comme des
733
        "jokers".
734

735
        @param query: Prefixe de recherche sur les noms d'hôtes
736
        @type query: C{unicode}
737
        """
738
        query = kwargs.get('query')
739
        if not query:
740
            redirect("searchHostForm")
741

    
742
        query = sql_escape_like(query.strip())
743
        user = get_current_user()
744
        if user is None:
745
            return dict(items=[])
746

    
747
        # Récupère les hôtes auxquels l'utilisateur a réellement accès.
748
        hosts = DBSession.query(
749
                Host.name,
750
            ).distinct(
751
            ).join(
752
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
753
                    Host.idhost),
754
            ).filter(Host.name.like(query + '%')
755
            ).order_by(
756
                Host.name.asc(),
757
            )
758

    
759
        # Les managers ont accès à tout.
760
        # Les autres ont un accès restreint.
761
        is_manager = in_group('managers').is_met(request.environ)
762
        if not is_manager:
763
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
764
            hosts = hosts.filter(
765
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
766

    
767
        return dict(hosts=hosts)
768

    
769
    # VIGILO_EXIG_VIGILO_PERF_0030:Moteur de recherche des graphes
770
    @expose('getopensearch.xml', content_type='text/xml')
771
    def getOpenSearch(self):
772
        """
773
        Moteur de recherche des graphes
774

775
        @return: document
776
        @rtype: document xml
777
        """
778
        return dict()
779

    
780
    def getListIndicators(self, graph=None):
781
        """
782
        Liste d indicateurs associes a un graphe
783

784
        @param graph : graphe
785
        @type graph  : C{str}
786

787
        @return: liste d indicateurs
788
        @rtype  : list
789
        """
790

    
791
        indicators = []
792
        if graph is not None:
793
            indicators = DBSession.query(
794
                    PerfDataSource.name
795
                ).join(
796
                    (GRAPH_PERFDATASOURCE_TABLE, \
797
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
798
                        PerfDataSource.idperfdatasource),
799
                    (Graph, Graph.idgraph == \
800
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
801
                ).filter(Graph.name == graph
802
                ).all()
803
        return indicators
804