Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigigraph / vigigraph / controllers / rpc.py @ 454df3f9

History | View | Annotate | Download (30.9 KB)

1
# -*- coding: utf-8 -*-
2
"""RPC controller for the combobox of vigigraph"""
3

    
4
import time
5
import urllib
6
import urllib2
7
import csv
8
import logging
9

    
10
from pylons.i18n import ugettext as _
11
from tg import expose, response, request, redirect, config, url, exceptions
12
from sqlalchemy.orm import aliased
13

    
14
from vigigraph.lib.base import BaseController
15

    
16
from vigilo.models.session import DBSession
17
from vigilo.models.tables import Service, LowLevelService, Host
18
from vigilo.models.tables import SupItemGroup, GroupHierarchy
19
from vigilo.models.tables import PerfDataSource
20
from vigilo.models.tables import Graph, GraphGroup
21
from vigilo.models.tables import Ventilation, VigiloServer, Application
22

    
23
from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE
24
from vigilo.models.tables.secondary_tables import GRAPH_GROUP_TABLE
25
from vigilo.models.tables.secondary_tables import GRAPH_PERFDATASOURCE_TABLE
26
from vigilo.models.functions import sql_escape_like
27
        
28
from vigilo.turbogears.rrdproxy import RRDProxy
29

    
30
from nagiosproxy import NagiosProxy
31
from searchhostform import SearchHostForm
32
from vigigraph.lib import graphs
33

    
34

    
35
LOGGER = logging.getLogger(__name__)
36

    
37
__all__ = ['RpcController']
38

    
39
# pylint: disable-msg=R0201
40
class RpcController(BaseController):
41
    """
42
    Class Controleur TurboGears
43
    """
44

    
45
    presets = [
46
        {"caption" : _("Last %s hours") % '12', "duration" : 43200},
47
        {"caption" : _("Last %s hours") % '24', "duration" : 86400},
48
        {"caption" : _("Last %s days") % '2',  "duration" : 192800},
49
        {"caption" : _("Last %s days") % '7',  "duration" : 604800},
50
        {"caption" : _("Last %s days") % '14', "duration" : 1209600},
51
        {"caption" : _("Last %s months") % '3', "duration" : 86400*31*3},
52
        {"caption" : _("Last %s months") % '6', "duration" : 86400*183},
53
        {"caption" : _("Last year"), "duration" : 86400*365},
54
    ]
55

    
56
    def _get_host(self, hostname):
57
        """
58
        Return Host object from hostname, None if not available
59
        """
60
        return DBSession.query(Host) \
61
                .filter(Host.name == hostname) \
62
                .first()
63

    
64
    @expose('json')
65
    def maingroups(self, nocache=None):
66
        """
67
        Determination des groupes principaux (sans parent)
68

69
        @return: groupes principaux
70
        @rtype: document json (sous forme de dict)
71
        """
72
        topgroups = [(tpg.name, str(tpg.idgroup)) \
73
                    for tpg in SupItemGroup.get_top_groups()]
74
        return dict(items=topgroups)
75

    
76
    @expose('json')
77
    def hostgroups(self, maingroupid, nocache=None):
78
        """
79
        Determination des groupes associes au groupe parent
80
        dont identificateur = argument
81

82
        @param maingroupid : identificateur d un groupe principal
83
        @type maingroupid : int
84

85
        @return: groupes
86
        @rtype: document json (sous forme de dict)
87
        """
88
        hostgroups = DBSession.query(
89
                SupItemGroup.name,
90
                SupItemGroup.idgroup,
91
            ).join(
92
                (GroupHierarchy, GroupHierarchy.idchild == \
93
                    SupItemGroup.idgroup),
94
            ).filter(GroupHierarchy.idparent == maingroupid
95
            ).filter(GroupHierarchy.hops == 1
96
            ).order_by(
97
                SupItemGroup.name.asc(),
98
            ).all()
99
        hostgroups = [(hg.name, str(hg.idgroup)) for hg in hostgroups]
100
        return dict(items=hostgroups)
101

    
102
    @expose('json')
103
    def hosts(self, othergroupid, nocache=None):
104
        """
105
        Determination des hotes associes au groupe
106
        dont identificateur = argument
107

108
        @param othergroupid : identificateur d un groupe
109
        @type othergroupid : int
110

111
        @return: hotes
112
        @rtype: document json (sous forme de dict)
113
        """
114
        hosts = DBSession.query(
115
                Host.name,
116
                Host.idhost,
117
            ).join(
118
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost),
119
                (SupItemGroup, SupItemGroup.idgroup == SUPITEM_GROUP_TABLE.c.idgroup),
120
            ).filter(SupItemGroup.idgroup == othergroupid
121
            ).order_by(
122
                Host.name.asc(),
123
            ).all()
124
            
125
        hosts = [(h.name, str(h.idhost)) for h in hosts]
126
        return dict(items=hosts)
127

    
128
    @expose('json')
129
    def graphgroups(self, idhost, nocache=None):
130
        """
131
        Determination des groupes de graphes associes a l hote
132
        dont identificateur = argument
133

134
        @param idhost : identificateur d un hote
135
        @type idhost : int
136

137
        @return: groupes de service
138
        @rtype: document json (sous forme de dict)
139
        """
140
        graphgroups = DBSession.query(
141
                GraphGroup.name,
142
                GraphGroup.idgroup,
143
            ).distinct(
144
            ).join(
145
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
146
                    GraphGroup.idgroup),
147
                (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
148
                (GRAPH_PERFDATASOURCE_TABLE, \
149
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
150
                (PerfDataSource, PerfDataSource.idperfdatasource == \
151
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
152
                (LowLevelService, LowLevelService.idservice == \
153
                    PerfDataSource.idservice),
154
            ).filter(
155
                LowLevelService.idhost == idhost
156
            ).order_by(
157
                GraphGroup.name.asc()
158
            )
159
        
160
        print "@@@\n%s\n@@@" % graphgroups
161
        graphgroups = graphgroups.all()
162

    
163
        graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups]
164
        return dict(items=graphgroups)
165

    
166
    @expose('json')
167
    def graphs(self, idgraphgroup, idhost, nocache=None):
168
        """
169
        Determination des graphes
170
        avec un service dont identificateur = argument
171

172
        @param idgraph : identificateur d un service
173
        @type idgraph : int
174

175
        @return: graphes
176
        @rtype: document json (sous forme de dict)
177
        """
178
        graphs_l = DBSession.query(
179
                Graph.name,
180
                Graph.idgraph,
181
            ).distinct().join(
182
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgraph == \
183
                    Graph.idgraph),
184
                (GraphGroup, GraphGroup.idgroup == \
185
                    GRAPH_GROUP_TABLE.c.idgroup),
186
                (GRAPH_PERFDATASOURCE_TABLE, \
187
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
188
                (PerfDataSource, PerfDataSource.idperfdatasource == \
189
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
190
                (LowLevelService, LowLevelService.idservice == \
191
                    PerfDataSource.idservice),
192
            ).filter(GraphGroup.idgroup == idgraphgroup
193
            ).filter(LowLevelService.idhost == idhost
194
            ).order_by(
195
                Graph.name.asc()
196
            )
197

    
198
        print "@@@\n%s\n@@@" % graphs_l
199
        graphs_l = graphs_l.all()
200

    
201
        graphs_l = [(pds.name, str(pds.idgraph)) for pds in graphs_l]
202
        return dict(items=graphs_l)
203

    
204
    @expose('json')
205
    def searchHostAndGraph(self, **kwargs):
206
        """
207
        Determination des couples (hote-graphe) repondant aux criteres de
208
        recherche sur hote et/ou graphe.
209

210
        Un critere peut correspondre a un intitule complet hote ou graphe
211
        ou a un extrait.
212

213
        @param kwargs : arguments nommes
214
        @type kwargs : dict
215
                         ( arguments nommes -> host et graphe )
216

217
        @return: couples hote-graphe
218
        @rtype: document json (sous forme de dict)
219
        """
220
        host = kwargs.get('host')
221
        graph = kwargs.get('graph')
222
        items = None
223

    
224
        # On a un nom d'indicateur, mais pas de nom d'hôte,
225
        # on considère que l'utilisateur veut tous les indicateurs
226
        # correspondant au motif, quelque soit l'hôte.
227
        if graph is not None:
228
            if host is None:
229
                host = '*'
230

    
231
            host = sql_escape_like(host)
232
            graph = sql_escape_like(graph)
233

    
234
            items = DBSession.query(
235
                    Host.name.label('hostname'),
236
                    Graph.name.label('graphname'),
237
                ).distinct().join(
238
                    (LowLevelService, LowLevelService.idhost == Host.idhost),
239
                    (PerfDataSource, PerfDataSource.idservice == \
240
                        LowLevelService.idservice),
241
                    (GRAPH_PERFDATASOURCE_TABLE, \
242
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
243
                        PerfDataSource.idperfdatasource),
244
                    (Graph, Graph.idgraph == \
245
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
246
                ).filter(Host.name.ilike('%' + host + '%')
247
                ).filter(Graph.name.ilike('%' + graph + '%')
248
                ).order_by(
249
                    Host.name.asc(),
250
                    Graph.name.asc(),
251
                )
252

    
253
        # On a ni hôte, ni indicateur. On renvoie une liste vide.
254
        # Si l'utilisateur voulait vraiment quelque chose,
255
        # il n'avait qu'à le demander.
256
        elif host is None:
257
            return []
258

    
259
        # Sinon, on a juste un motif pour un hôte.
260
        # On renvoie la liste des hôtes correspondant.
261
        else:
262
            host = sql_escape_like(host)
263
            items = DBSession.query(
264
                    Host.name.label('hostname'),
265
                ).filter(
266
                    Host.name.ilike('%' + host + '%')
267
                ).order_by(Host.name.asc())
268

    
269
        items = items.limit(100).all()
270
        if graph is None:
271
            items = [(item.hostname, "") for item in items]
272
        else:
273
            items = [(item.hostname, item.graphname) for item in items]
274
        return dict(items=items)
275

    
276
    @expose('json')
277
    def selectHostAndGraph(self, host=None, graph=None, nocache=None):
278
        """
279
        Renvoie les valeurs à sélectionner dans les comboboxes
280
        de VigiGraph pour afficher les données de l'hôte ou du
281
        couple hôte/graphe sélectionné.
282

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

288
        Pour le moment, la 2ème liste contiendra au plus 1 élément car
289
        les groupes de graphes ne sont pas récursifs. L'utilisation d'une
290
        liste permet d'assurer facilement une évolution vers des groupes
291
        de graphes récursifs.
292
        """
293

    
294
        # Ce cas ne devrait pas se produire, mais on tente
295
        # d'avoir un comportement gracieux malgré tout.
296
        if (not host) and (not graph):
297
            return dict(items=[[], []])
298

    
299
        # Groupe principal de l'hôte.
300
        mhg = aliased(SupItemGroup)
301
        # Groupe secondaire de l'hôte.
302
        shg = aliased(SupItemGroup)
303

    
304
        selected_hostgroups = []
305
        selected_graphgroups = []
306

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

    
311
        if host:
312
            # Sélectionne l'identifiant du premier SupItemGroup auquel
313
            # l'utilisateur a accès et auquel l'hôte donné appartient.
314
            idsupitemgroup = DBSession.query(
315
                    SupItemGroup.idgroup,
316
                ).join(
317
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idgroup == \
318
                        SupItemGroup.idgroup),
319
                    (Host, Host.idhost == SUPITEM_GROUP_TABLE.c.idsupitem),
320
                ).filter(Host.name == host
321
                ).scalar()
322

    
323
            # Si on a trouvé un tel groupe, on renvoie les noms des
324
            # groupes de la hiérarchie à sélectionner pour arriver
325
            # à celui-ci.
326
            if idsupitemgroup is not None:
327
                selected_hostgroups = DBSession.query(
328
                        SupItemGroup.name,
329
                    ).join(
330
                        (GroupHierarchy, GroupHierarchy.idparent == \
331
                            GraphGroup.idgroup),
332
                    ).filter(GroupHierarchy.idchild == idsupitemgroup
333
                    ).order_by(
334
                        GroupHierarchy.hops.desc()
335
                    ).all()
336

    
337
        if graph:
338
            # Le principe est le même que pour l'hôte, en considérant
339
            # cette fois les GraphGroup à la place des SupItemGroup.
340
            idgraphgroup = DBSession.query(
341
                    GraphGroup.idgroup,
342
                ).join(
343
                    (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
344
                        GraphGroup.idgroup),
345
                    (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
346
                ).filter(Graph.name == graph
347
                ).scalar()
348

    
349
            # Même principe que pour l'hôte.
350
            if idgraphgroup is not None:
351
                selected_graphgroups = DBSession.query(
352
                        GraphGroup.name,
353
                    ).join(
354
                        (GroupHierarchy, GroupHierarchy.idparent == \
355
                            GraphGroup.idgroup),
356
                    ).filter(GroupHierarchy.idchild == idgraphgroup
357
                    ).order_by(
358
                        GroupHierarchy.hops.desc()
359
                    ).all()
360

    
361
        hostgroups = [hg.name for hg in selected_hostgroups]
362
        graphgroups = [gg.name for gg in selected_graphgroups]
363
        return dict(items=[hostgroups, graphgroups])        
364

    
365
    @expose(content_type='text/plain')
366
    def getImage(self, host, start=None, duration=86400, graph=None, \
367
    details=1, nocache=0):
368
        """
369
        Determination de l url d un graphe
370
        (via proxy RRD)
371

372
        @param host : hôte
373
        @type host : C{str}
374
        @param start : date-heure de debut des donnees
375
        @type start : C{str}
376
        @param duration : plage de temps des données
377
        @type duration : C{str}
378
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
379
        @param details : indicateur affichage details dans graphe (legende)
380
        @type details : int
381
        @param graph : graphe
382
        @type graph : C{str}
383

384
        @return: url du graphe
385
        @rtype: C{str}
386
        """
387

    
388
        result = None
389

    
390
        if start is None:
391
            start = int(time.time()) - 24*3600
392

    
393
        # valeurs particulieres
394
        direct = 1
395
        rrdserver = self.getRRDServer(host)
396

    
397
        if rrdserver is not None:
398
            # url
399
            url_web_path = config.get('rrd_web_path')
400
            url_l = '%s%s' % (rrdserver, url_web_path)
401

    
402
            # proxy
403
            rrdproxy = RRDProxy(url_l)
404
            try:
405
                result = rrdproxy.get_img_name_with_params(host, graph, \
406
                direct, duration, start, int(details))
407
            except urllib2.URLError:
408
                txt = _("Can't get RRD graph \"%s\" on host \"%s\"") \
409
                    % (graph, host)
410
                LOGGER.error(txt)
411
                exceptions.HTTPNotFound(comment=txt)
412

    
413
        return result
414

    
415
    # VIGILO_EXIG_VIGILO_PERF_0020:Visualisation unitaire des graphes
416
    @expose(content_type='image/png')
417
    def getImage_png(self, host, start=None, duration=86400, graph=None, \
418
    details=1):
419
        """
420
        Affichage de l image d un graphe
421
        (via proxy RRD)
422

423
        @param host : hôte
424
        @type host : C{str}
425
        @param start : date-heure de debut des donnees
426
        @type start : C{str}
427
        @param duration : plage de temps des données
428
        @type duration : C{str}
429
                      (parametre optionnel, initialise a 86400 = plage de 1 jour)
430
        @param graph : graphe
431
        @type graph : C{str}
432
        @param details : indicateur affichage details dans graphe (legende)
433
        @type details : int
434

435
        @return: image du graphe
436
        @rtype: image png
437
        """
438
        result = None
439

    
440
        if start is None:
441
            start = int(time.time()) - 24*3600
442

    
443
        # valeurs particulieres
444
        direct = 1
445
        rrdserver = self.getRRDServer(host)
446
        
447
        if rrdserver is not None:
448
            # url
449
            url_web_path = config.get('rrd_web_path')
450
            url_l = '%s%s' % (rrdserver, url_web_path)
451

    
452
            # proxy
453
            rrdproxy = RRDProxy(url_l)
454
            try:
455
                result = rrdproxy.get_img_with_params(host, graph, direct, \
456
                duration, start, int(details))
457
            except urllib2.URLError:
458
                txt = _("Can't get RRD graph \"%s\" on host \"%s\"") \
459
                    % (graph, host)
460
                LOGGER.error(txt)
461
                exceptions.HTTPNotFound(comment=txt)
462

    
463
        return result
464

    
465
    @expose()
466
    def imagePage(self, server, graphtemplate):
467
        """
468
        Affichage de l image d un graphe
469

470
        @param server : hôte
471
        @type server : C{str}
472
        @param graphtemplate : graphe
473
        @type graphtemplate : C{str}
474

475
        @return: page avec l image du graphe (redirection sur getImage_png)
476
        @rtype: page
477
        """
478
        redirect('getImage_png?host=%s&graph=%s' % (server, graphtemplate))
479

    
480
    @expose()
481
    def getStartTime(self, host, nocache=None):
482
        """
483
        Determination de la date-heure de debut des donnees RRD d un hote
484
        (via proxy RRD)
485

486
        @param host : hôte
487
        @type host : C{str}
488

489
        @return: date-heure de debut des donnees RRD
490
        @rtype: C{str}
491
        """
492

    
493
        result = None
494
        getstarttime = 1
495
        rrdserver = self.getRRDServer(host)
496

    
497
        if rrdserver is not None:
498
            # url
499
            url_web_path = config.get('rrd_web_path')
500
            url_l = '%s%s' % (rrdserver, url_web_path)
501
    
502
            # proxy
503
            rrdproxy = RRDProxy(url_l)
504
            try:
505
                result = rrdproxy.get_starttime(host, getstarttime)
506
            except urllib2.URLError:
507
                txt = _("Can't get RRD data on host \"%s\"") \
508
                    % (host)
509
                LOGGER.error(txt)
510
                exceptions.HTTPNotFound(comment=txt)
511

    
512
        return result
513

    
514
    @expose()
515
    def supPage(self, host):
516
        """
517
        Affichage page supervision Nagios pour un hote
518
        (appel fonction status via proxy Nagios)
519
        
520
        @param host : hôte
521
        @type host : C{str}
522

523
        @return: page de supervision Nagios
524
        @rtype: page
525
        """
526
        result = None
527

    
528
        nagiosserver = self.getNagiosServer(host)
529
        if nagiosserver is not None:
530
            # url
531
            url_web_path = config.get('nagios_web_path')
532
            url_l = '%s%s' % (nagiosserver, url_web_path)
533

    
534
            # proxy
535
            nagiosproxy = NagiosProxy(url_l)
536
            try:
537
                result = nagiosproxy.get_status(host)
538
            except urllib2.URLError:
539
                txt = _("Can't get Nagios data on host \"%s\"") \
540
                    % (host)
541
                LOGGER.error(txt)
542
                error_url = '../error/nagios_host_error?host=%s'
543
                redirect(error_url % host)
544

    
545
        return result
546

    
547
    @expose()
548
    def servicePage(self, host, service=None):
549
        """
550
        Affichage page supervision Nagios pour un hote
551
        (appel fonction get_extinfo via proxy Nagios)
552

553
        @param host : hôte
554
        @type host : C{str}
555
        @param service : service
556
        @type service : C{str}
557

558
        @return: page de supervision Nagios
559
        @rtype: page
560
        """
561
        result = None
562

    
563
        nagiosserver = self.getNagiosServer(host)
564
        if nagiosserver is not None:
565
            # url
566
            url_web_path = config.get('nagios_web_path')
567
            url_l = '%s%s' % (nagiosserver, url_web_path)
568

    
569
            # proxy
570
            nagiosproxy = NagiosProxy(url_l)
571
            try:
572
                result = nagiosproxy.get_extinfo(host, service)
573
            except urllib2.URLError:
574
                txt = _("Can't get Nagios data on host \"%s\" service \"%s\"")\
575
                    % (host, service)
576
                LOGGER.error(txt)
577

    
578
                error_url = '../error'
579
                error_url += '/nagios_host_service_error?host=%s&service=%s'
580
                redirect(error_url % (host, service))
581

    
582
        return result
583

    
584
    @expose()
585
    def metroPage(self, host):
586
        """
587
        Affichage page metrologie pour un hote
588
        (via proxy RRD)
589

590
        @param host : hôte
591
        @type host : C{str}
592

593
        @return: page de metrologie
594
        @rtype: page
595
        """
596
        result = None
597

    
598
        rrdserver = self.getRRDServer(host)
599
        if rrdserver is not None:
600
            # url
601
            url_web_path = config.get('rrd_web_path')
602
            url_l = '%s%s' % (rrdserver, url_web_path)
603

    
604
            # proxy
605
            rrdproxy = RRDProxy(url_l)
606
            try:
607
                result = rrdproxy.get_hostC(host)
608
            except urllib2.URLError:
609
                txt = _("Can't get RRD data on host \"%s\"") \
610
                    % (host)
611
                LOGGER.error(txt)
612
                error_url = '../error/rrd_error?host=%s'
613
                redirect(error_url % host)
614

    
615
        return result
616

    
617
    @expose('graphslist.html', content_type='text/html')
618
    def graphsList(self, nocache=None, **kwargs):
619
        """
620
        Generation document avec url des graphes affiches
621
        (pour l impression )
622

623
        @param kwargs : arguments nommes
624
        @type kwargs  : dict
625

626
        @return: url de graphes
627
        @rtype: document html
628
        """
629
        graphslist = graphs.graphsList(**kwargs)
630
        return dict(graphslist=graphslist)
631

    
632
    @expose(content_type='text/plain')
633
    def tempoDelayRefresh(self, nocache=None):
634
        """
635
        Determination valeur temporisation pour le rafraichissement automatique
636
        d un graphe
637

638
        @return: valeur de temporisation
639
        @rtype: C{str}
640
        """
641

    
642
        delay = graphs.tempoDelayRefresh()
643
        return delay
644

    
645
    @expose('json')
646
    def getIndicators(self, nocache=None, graph=None):
647
        """
648
        Liste d indicateurs associes a un graphe
649

650
        @param graph : graphe
651
        @type graph  : C{str}
652

653
        @return: dictionnaire des indicateurs d un graphe
654
        @rtype: document json (sous forme de dict)
655
        """
656

    
657
        indicators = self.getListIndicators(graph)
658
        indicators = [(ind.name, ind.idperfdatasource) for ind in indicators]
659
        return dict(items=indicators)
660

    
661
    def getListIndicators(self, graph=None):
662
        """
663
        Liste d indicateurs associes a un graphe
664

665
        @param graph : graphe
666
        @type graph  : C{str}
667

668
        @return: liste d indicateurs
669
        @rtype  : list
670
        """
671

    
672
        indicators = []
673
        if graph is not None:
674
            indicators = DBSession.query \
675
              (PerfDataSource.name, PerfDataSource.idperfdatasource) \
676
              .join((GRAPH_PERFDATASOURCE_TABLE, \
677
              GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
678
              PerfDataSource.idperfdatasource)) \
679
              .join((Graph, \
680
              Graph.idgraph == GRAPH_PERFDATASOURCE_TABLE.c.idgraph)) \
681
              .filter(Graph.name == graph) \
682
              .all()
683
        return indicators
684

    
685
    # VIGILO_EXIG_VIGILO_PERF_0040:Export des donnees d'un graphe au format CSV
686
    @expose(content_type='text/csv')
687
    def exportCSV(self, nocache=None, host=None, graph=None, indicator=None, \
688
    start=None, end=None):
689
        """
690
        Export CSV sous forme de fichier
691
        pour un hote et un graphe et pour l'indicateur suivant
692
        * soit un des indicateurs associes au graphe
693
        * soit l ensemble des indicateurs -> valeur argument = All
694

695
        @param host : hôte
696
        @type host : C{str}
697
        @param graph : graphe
698
        @type graph : C{str}
699
        @param indicator : indicateur graphe
700
        @type indicator : C{str}
701
        @param start : date-heure de debut des donnees
702
        @type start : C{str}
703

704
        @return: fichier genere avec les donnees RRD repondant aux criteres
705
        @rtype  : fichier CSV
706
        """
707

    
708
        result = None
709
        filename = None
710

    
711
        # indicateurs
712
        if indicator is None:
713
            raise ValueError
714

    
715
        rrdserver = self.getRRDServer(host)
716
        if not rrdserver:
717
            raise ValueError, host
718

    
719
        indicators = [ind[0] for ind in self.getListIndicators(graph)]
720
        if indicator != "All":
721
            if indicator not in indicators:
722
                raise ValueError, indicator
723
            indicators = [indicator]
724
            filename = graphs.getExportFileName(host, indicator, start, end)
725

    
726
        else:
727
            filename = graphs.getExportFileName(host, graph, start, end)
728

    
729
        indicators.insert(0, "Timestamp")
730

    
731
        url_web_path = config.get('rrd_web_path', '')
732
        url = '%s%s' % (rrdserver, url_web_path)
733
        rrdproxy = RRDProxy(url)
734

    
735
        try:
736
            result = rrdproxy.exportCSV(server=host, graph=graph, \
737
                indicator=indicator, start=start, end=end)
738
        except urllib2.URLError:
739
            # @TODO utiliser des dicos pour faciliter la traduction.
740
            txt = _("Can't get RRD data on host \"%s\" "
741
                    "graph \"%s\" indicator \"%s\" ") % (host, graph, indicator)
742
            LOGGER.error(txt)
743

    
744
            error_url = '../error'
745
            error_url += '/rrd_exportCSV_error'
746
            error_url += '?host=%s&graph=%s&indicator=%s'
747
            redirect(error_url % (host, graph, indicator))
748
        else:
749
            response.headerlist.append(('Content-Disposition',
750
                'attachment;filename=%s' % filename))
751
            return result
752

    
753

    
754
    # VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
755
    @expose('fullhostpage.html')
756
    def fullHostPage(self, host, start=None, duration=86400):
757
        """
758
        Affichage de l'ensemble des graphes associes a un hote
759
        * d apres les donnees RRD
760
        * avec une date-heure de debut
761
        * pour une plage de temps 
762
        
763
        @param host : hôte
764
        @type host : C{str}
765
        @param start : date-heure de debut des donnees
766
        @type start : C{str}
767
        @param duration : plage de temps des données
768
        @type duration : C{str}
769
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
770

771
        @return: page avec les images des graphes et boutons de deplacement dans le temps
772
        @rtype: page html
773
        """
774

    
775
        if start is None:
776
            start = int(time.time()) - int(duration)
777

    
778
        # graphes pour hote
779
        hgs = DBSession.query(Graph.name) \
780
              .join((GRAPH_PERFDATASOURCE_TABLE, \
781
              GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph)) \
782
              .join((PerfDataSource, \
783
              GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
784
              PerfDataSource.idperfdatasource)) \
785
              .join((LowLevelService, \
786
              PerfDataSource.idservice == LowLevelService.idservice)) \
787
              .join((Host, \
788
              LowLevelService.idhost == Host.idhost)) \
789
              .filter(Host.name == host) \
790
              .all()
791

    
792
        # dictionnaire -> {0 : [hote, graph_0], ..., n: [hote, graph_n] }
793
        i = 0
794
        dhgs = {}
795
        for hg in hgs:
796
            elt = [host, hg]
797
            dhgs[i] = elt
798
            i += 1
799

    
800
        return dict(host=host, start=start, duration=duration, \
801
                    presets=self.presets, dhgs=dhgs)
802

    
803
    @expose ('singlegraph.html')
804
    def singleGraph(self, host, graph, start=None, duration=86400):
805
        """
806
        Affichage d un graphe associe a un hote et un graphe
807
        * d apres les donnees RRD
808
        * avec une date-heure de debut
809
        * pour une plage de temps 
810
        
811
        @param host : hôte
812
        @type host : C{str}
813
        @param graph : graphe
814
        @type graph  : C{str}
815
        @param start : date-heure de debut des donnees
816
        @type start : C{str}
817
        @param duration : plage de temps des données 
818
        @type duration : C{str}
819
                         (parametre optionnel, initialise a 86400 = plage de 1 jour)
820

821
        @return: page avec l image du graphe et boutons de deplacement dans le temps
822
        @rtype: page html
823
        """
824

    
825
        if start is None:
826
            start = int(time.time()) - int(duration)
827

    
828
        return dict(host=host, graph=graph, start=start, duration=duration, \
829
                    presets=self.presets)
830

    
831
    @expose('searchhostform.html')
832
    def searchHostForm(self):
833
        """
834
        Formulaire de recherche sur les hotes
835

836
        @return: page avec formulaire de recherche
837
        @rtype: page html
838
        """
839
        searchhostform = SearchHostForm('search_host_form', \
840
            submit_text=None)
841

    
842
        return dict(searchhostform=searchhostform)
843

    
844
    @expose ('searchhost.html')
845
    def searchHost(self, query=None):
846
        """
847
        Affichage page pour hotes repondant au critere de recherche
848
        * dans cette page, lien sur pages de metrologie et de supervision
849

850
        @param query : prefixe de recherche sur les hotes
851
        @type query : C{str}
852

853
        @return: page
854
        @rtype: page html
855
        """
856

    
857
        hosts = []
858

    
859
        if query:
860
            r = urllib.unquote_plus(query.strip())
861
            rl = r.split(',')
862

    
863
            # hotes
864
            for part in rl:
865
                hosts += DBSession.query(Host.name) \
866
                        .filter(Host.name.like(part.strip() + '%')) \
867
                        .all()
868
            return dict(hosts=hosts)
869
        else:
870
            redirect("searchHostForm")
871

    
872
    # VIGILO_EXIG_VIGILO_PERF_0030:Moteur de recherche des graphes
873
    @expose('getopensearch.xml', content_type='text/xml')
874
    def getOpenSearch(self):
875
        """
876
        Moteur de recherche des graphes
877

878
        @return: document
879
        @rtype: document xml
880
        """
881

    
882
        here = "http://"
883
        here += request.host
884
        dir_l = url('/public')
885

    
886
        result = dict(here=here, dir=dir_l)
887

    
888
        return result
889

    
890
    def getRRDServer(self, host=None):
891
        """
892
        Determination Serveur RRD pour l hote courant
893
        (Serveur RRD -> nom de l application associee = rrdgraph)
894

895
        @param host : hôte
896
        @type host : C{str}
897

898
        @return: serveur RRD
899
        @rtype: C{str}
900
        """
901

    
902
        result = DBSession.query \
903
            (VigiloServer.name) \
904
            .filter(VigiloServer.idvigiloserver == Ventilation.idvigiloserver) \
905
            .filter(Ventilation.idhost == Host.idhost) \
906
            .filter(Ventilation.idapp == Application.idapp) \
907
            .filter(Host.name == host) \
908
            .filter(Application.name == 'rrdgraph') \
909
            .scalar()
910
        return result
911

    
912
    def getNagiosServer(self, host=None):
913
        """
914
        Determination Serveur Nagios pour l hote courant
915
        (Server Nagios -> nom de l application associee = nagios)
916

917
        @param host : hôte
918
        @type host : C{str}
919

920
        @return: serveur Nagios
921
        @rtype: C{str}
922
        """
923

    
924
        result = DBSession.query \
925
            (VigiloServer.name) \
926
            .filter(VigiloServer.idvigiloserver == Ventilation.idvigiloserver) \
927
            .filter(Ventilation.idhost == Host.idhost) \
928
            .filter(Ventilation.idapp == Application.idapp) \
929
            .filter(Host.name == host) \
930
            .filter(Application.name == 'nagios') \
931
            .scalar()
932
        return result