Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigigraph / vigigraph / controllers / rpc.py @ d19e6b55

History | View | Annotate | Download (30.8 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 to 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
        user = get_current_user()
458
        if user is None:
459
            return dict(items=[[], []])
460

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

    
466
        selected_hostgroups = []
467
        selected_graphgroups = []
468
        is_manager = in_group('managers').is_met(request.environ)
469

    
470
        supitemgroups = []
471
        if not is_manager:
472
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
473

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

    
485
            # On prend en compte les permissions de l'utilisateur.
486
            if not is_manager:
487
                idsuitemgroup = idsupitemgroup.filter(
488
                    SupItemGroup.idgroup.in_(supitemgroups))
489

    
490
            idsupitemgroup = idsupitemgroup.scalar()
491

    
492
            # Si on a trouvé un tel groupe, on renvoie les noms des
493
            # groupes de la hiérarchie à sélectionner pour arriver
494
            # à celui-ci.
495
            if idsupitemgroup is not None:
496
                selected_hostgroups = DBSession.query(
497
                        SupItemGroup.name,
498
                    ).distinct().join(
499
                        (GroupHierarchy, GroupHierarchy.idparent == \
500
                            GraphGroup.idgroup),
501
                    ).filter(GroupHierarchy.idchild == idsupitemgroup
502
                    ).order_by(
503
                        GroupHierarchy.hops.desc()
504
                    ).all()
505

    
506
        if graph:
507
            # Le principe est le même que pour l'hôte, en considérant
508
            # cette fois les GraphGroup à la place des SupItemGroup.
509
            idgraphgroup = DBSession.query(
510
                    GraphGroup.idgroup,
511
                ).join(
512
                    (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
513
                        GraphGroup.idgroup),
514
                    (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
515
                ).filter(Graph.name == graph)
516

    
517
            # On prend en compte les permissions de l'utilisateur.
518
            if not is_manager:
519
                idgraphgroup = idgraphgroup.filter(
520
                    GraphGroup.idgroup.in_(supitemgroups))
521

    
522
            idgraphgroup = idgraphgroup.scalar()
523

    
524
            # Même principe que pour l'hôte.
525
            if idgraphgroup is not None:
526
                selected_graphgroups = DBSession.query(
527
                        GraphGroup.name,
528
                    ).join(
529
                        (GroupHierarchy, GroupHierarchy.idparent == \
530
                            GraphGroup.idgroup),
531
                    ).filter(GroupHierarchy.idchild == idgraphgroup
532
                    ).order_by(
533
                        GroupHierarchy.hops.desc()
534
                    ).all()
535

    
536
        hostgroups = [hg.name for hg in selected_hostgroups]
537
        # @FIXME: Ce test est nécessaire tant que l'interface Qooxdoo
538
        # monolithique est conservée (ie: 2 niveaux de profondeur figés).
539
        if len(hostgroups) != 2:
540
            hostgroups.append(_('No subgroup'))
541
        graphgroups = [gg.name for gg in selected_graphgroups]
542
        return dict(items=[hostgroups, graphgroups])
543

    
544
    @expose('graphslist.html')
545
    def graphsList(self, nocache=None, **kwargs):
546
        """
547
        Generation document avec url des graphes affiches
548
        (pour l impression )
549

550
        @param kwargs : arguments nommes
551
        @type kwargs  : dict
552

553
        @return: url de graphes
554
        @rtype: document html
555
        """
556
        if not kwargs:
557
            return dict(graphslist=[])
558

    
559
        # TRANSLATORS: Format Python de date/heure, lisible par un humain.
560
        format = _("%a, %d %b %Y %H:%M:%S")
561
        graphslist = []
562
        for url in kwargs.itervalues():
563
            parts = urlparse.urlparse(url)
564
            params = dict(parse_qsl(parts.query))
565

    
566
            graph = {}
567
            start = int(params.get('start', time.time() - 86400))
568
            duration = int(params.get('duration', 86400))
569

    
570
            graph['graph'] = params.get('graphtemplate')
571
            graph['start_date'] = time.strftime(format, time.localtime(start))
572
            graph['end_date'] = time.strftime(format,
573
                                    time.localtime(start + duration))
574
            graph['img_src'] = url
575
            graph['host'] = params['host']
576
            graphslist.append(graph)
577
        return dict(graphslist=graphslist)
578

    
579
    @expose(content_type='text/plain')
580
    def tempoDelayRefresh(self, nocache=None):
581
        """
582
        Determination valeur temporisation pour le rafraichissement automatique
583
        d un graphe
584

585
        @return: valeur de temporisation
586
        @rtype: C{str}
587
        """
588

    
589
        try:
590
            delay = int(config['delay_refresh'])
591
        except (ValueError, KeyError):
592
            delay = 36000
593
        return str(delay)
594

    
595
    class GetIndicatorsSchema(schema.Schema):
596
        """Schéma de validation pour la méthode L{getIndicators}."""
597
        host = validators.String(not_empty=True)
598
        graph = validators.String(not_empty=True)
599
        nocache = validators.String(if_missing=None)
600

    
601
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
602
    @validate(
603
        validators = GetIndicatorsSchema(),
604
        error_handler = process_form_errors)
605
    @expose('json')
606
    def getIndicators(self, host, graph, nocache):
607
        """
608
        Liste d indicateurs associes a un graphe
609

610
        @param graph : graphe
611
        @type graph  : C{str}
612

613
        @return: dictionnaire des indicateurs d un graphe
614
        @rtype: document json (sous forme de dict)
615
        """
616

    
617
        indicators = self.getListIndicators(host, graph)
618
        indicators = [ind.name for ind in indicators]
619
        return dict(items=indicators)
620

    
621

    
622
    class FullHostPageSchema(schema.Schema):
623
        """Schéma de validation pour la méthode L{fullHostPage}."""
624
        host = validators.String(not_empty=True)
625
        start = validators.Int(if_missing=None)
626
        duration = validators.Int(if_missing=86400)
627

    
628
    # VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
629
    @validate(
630
        validators = FullHostPageSchema(),
631
        error_handler = process_form_errors)
632
    @expose('fullhostpage.html')
633
    def fullHostPage(self, host, start=None, duration=86400):
634
        """
635
        Affichage de l'ensemble des graphes associes a un hote
636
        * d apres les donnees RRD
637
        * avec une date-heure de debut
638
        * pour une plage de temps
639

640
        @param host : hôte
641
        @type host : C{str}
642
        @param start : date-heure de debut des donnees
643
        @type start : C{str}
644
        @param duration : plage de temps des données
645
        @type duration : C{str}
646
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
647

648
        @return: page avec les images des graphes et boutons de deplacement dans le temps
649
        @rtype: page html
650
        """
651

    
652
        if start is None:
653
            start = int(time.time()) - int(duration)
654

    
655
        start = int(start)
656
        duration = int(duration)
657

    
658
        user = get_current_user()
659
        if user is None:
660
            return dict(host=host, start=start, duration=duration,
661
                        presets=self.presets, graphs=[])
662

    
663
        # Récupération de la liste des noms des graphes,
664
        # avec vérification des permissions de l'utilisateur.
665
        graphs = DBSession.query(
666
                Graph.name
667
            ).distinct(
668
            ).join(
669
                (GRAPH_PERFDATASOURCE_TABLE,
670
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
671
                (PerfDataSource, PerfDataSource.idperfdatasource ==
672
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
673
                (Host, Host.idhost == PerfDataSource.idhost),
674
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
675
                    Host.idhost),
676
            )
677

    
678
        # Les managers ont accès à tout.
679
        # Les autres ont un accès restreint.
680
        is_manager = in_group('managers').is_met(request.environ)
681
        if not is_manager:
682
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
683
            graphs = graphs.filter(
684
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
685

    
686
        graphs = graphs.all()
687
        return dict(host=host, start=start, duration=duration,
688
                    presets=self.presets, graphs=graphs)
689

    
690

    
691
    class SingleGraphSchema(schema.Schema):
692
        """Schéma de validation pour la méthode L{singleGraph}."""
693
        host = validators.String(not_empty=True)
694
        graph = validators.String(not_empty=True)
695
        start = validators.Int(if_missing=None)
696
        duration = validators.Int(if_missing=86400)
697

    
698
    # VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes
699
    @validate(
700
        validators = SingleGraphSchema(),
701
        error_handler = process_form_errors)
702
    @expose('singlegraph.html')
703
    def singleGraph(self, host, graph, start, duration):
704
        """
705
        Affichage d un graphe associe a un hote et un graphe
706
        * d apres les donnees RRD
707
        * avec une date-heure de debut
708
        * pour une plage de temps
709

710
        @param host : hôte
711
        @type host : C{str}
712
        @param graph : graphe
713
        @type graph  : C{str}
714
        @param start : date-heure de debut des donnees
715
        @type start : C{str}
716
        @param duration : plage de temps des données
717
        @type duration : C{str}
718
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
719

720
        @return: page avec l image du graphe et boutons de deplacement dans le temps
721
        @rtype: page html
722
        """
723

    
724
        if start is None:
725
            start = int(time.time()) - int(duration)
726

    
727
        start = int(start)
728
        duration = int(duration)
729

    
730
        return dict(host=host, graph=graph, start=start, duration=duration, \
731
                    presets=self.presets)
732

    
733
    @expose('searchhostform.html')
734
    def searchHostForm(self):
735
        """
736
        Formulaire de recherche sur les hotes
737

738
        @return: page avec formulaire de recherche
739
        @rtype: page html
740
        """
741
        searchhostform = SearchHostForm('search_host_form', \
742
            submit_text=None)
743

    
744
        return dict(searchhostform=searchhostform)
745

    
746
    @expose('searchhost.html')
747
    @paginate('hosts', items_per_page=10)
748
    def searchHost(self, *args, **kwargs):
749
        """
750
        Affiche les résultats de la recherche par nom d'hôte.
751
        La requête de recherche (L{query}) correspond à un préfixe
752
        qui sera recherché dans le nom d'hôte. Ce préfixe peut
753
        contenir les caractères '*' et '?' qui agissent comme des
754
        "jokers".
755

756
        @param query: Prefixe de recherche sur les noms d'hôtes
757
        @type query: C{unicode}
758
        """
759
        query = kwargs.get('query')
760
        if not query:
761
            redirect("searchHostForm")
762

    
763
        query = sql_escape_like(query.strip())
764
        user = get_current_user()
765
        if user is None:
766
            return dict(items=[])
767

    
768
        # Récupère les hôtes auxquels l'utilisateur a réellement accès.
769
        hosts = DBSession.query(
770
                Host.name,
771
            ).distinct(
772
            ).join(
773
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
774
                    Host.idhost),
775
            ).filter(Host.name.like(query + '%')
776
            ).order_by(
777
                Host.name.asc(),
778
            )
779

    
780
        # Les managers ont accès à tout.
781
        # Les autres ont un accès restreint.
782
        is_manager = in_group('managers').is_met(request.environ)
783
        if not is_manager:
784
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
785
            hosts = hosts.filter(
786
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
787

    
788
        return dict(hosts=hosts)
789

    
790
    # VIGILO_EXIG_VIGILO_PERF_0030:Moteur de recherche des graphes
791
    @expose('getopensearch.xml', content_type='text/xml')
792
    def getOpenSearch(self):
793
        """
794
        Moteur de recherche des graphes
795

796
        @return: document
797
        @rtype: document xml
798
        """
799
        return dict()
800

    
801
    def getListIndicators(self, host, graph):
802
        """
803
        Liste d indicateurs associes a un graphe
804

805
        @param graph : graphe
806
        @type graph  : C{str}
807

808
        @return: liste d indicateurs
809
        @rtype  : list
810
        """
811

    
812
        indicators = []
813
        if graph is not None:
814
            indicators = DBSession.query(
815
                    PerfDataSource.name
816
                ).distinct(
817
                ).join(
818
                    (GRAPH_PERFDATASOURCE_TABLE, \
819
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
820
                        PerfDataSource.idperfdatasource),
821
                    (Graph, Graph.idgraph == \
822
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
823
                    (Host, Host.idhost == PerfDataSource.idhost),
824
                ).filter(Graph.name == graph
825
                ).filter(Host.name == host
826
                ).all()
827
        return indicators