Project

General

Profile

Revision 24334b4b

ID24334b4becf45c934bdbe348e5d4ae9af1f1b29b
Parent 3a32bf0a
Child 64ed9170

Added by Vincent QUEMENER over 14 years ago

Ajout de l'affichage des évènements corrélés causés par des incidents sur des hôtes.

git-svn-id: https://vigilo-dev.si.c-s.fr/svn@1714 b22e2e97-25c9-44ff-b637-2e5ceca36478

View differences:

vigiboard/controllers/root.py
8 8
from pylons.i18n import ugettext as _
9 9
from pylons.i18n import lazy_ugettext as l_
10 10
from pylons.controllers.util import abort
11
from sqlalchemy import not_, and_, asc
11
from sqlalchemy import not_, and_,  or_, asc
12 12
from sqlalchemy.orm import aliased
13 13
from sqlalchemy.sql import func
14 14
from datetime import datetime
......
20 20
from vigiboard.model import Event, EventHistory, CorrEvent, \
21 21
                            Host, HostGroup, ServiceGroup, \
22 22
                            StateName, User, ServiceLowLevel
23
from vigilo.models import SupItem                    
23 24
from repoze.what.predicates import Any, not_anonymous
24 25
from vigiboard.widgets.edit_event import edit_event_status_options
25 26
from vigiboard.controllers.vigiboardrequest import VigiboardRequest
......
103 104
        if hostgroup:
104 105
            search['hostgroup'] = hostgroup
105 106
            hostgroup = sql_escape_like(hostgroup)
106
            hg_alias = aliased(HostGroup)
107
            aggregates.add_outer_join((hg_alias, hg_alias.idgroup == \
108
                HOST_GROUP_TABLE.c.idgroup))
109
            aggregates.add_filter(hg_alias.name.ilike('%%%s%%' % hostgroup))
107
            aggregates.add_join((HostGroup, HostGroup.idgroup == \
108
                aggregates.items.c.idhostgroup))
109
            aggregates.add_filter(HostGroup.name.ilike('%%%s%%' % hostgroup))
110 110

  
111 111
        if servicegroup:
112 112
            search['servicegroup'] = servicegroup
113 113
            servicegroup = sql_escape_like(servicegroup)
114
            sg_alias = aliased(ServiceGroup)
115
            aggregates.add_outer_join((sg_alias, sg_alias.idgroup == \
116
                SERVICE_GROUP_TABLE.c.idgroup))
117
            aggregates.add_filter(sg_alias.name.ilike(
118
                '%%%s%%' % servicegroup))
114
            aggregates.add_join((ServiceGroup, ServiceGroup.idgroup == \
115
                aggregates.items.c.idservicegroup))
116
            aggregates.add_filter(ServiceGroup.name.ilike('%%%s%%' % servicegroup))
119 117

  
120 118
        if host:
121 119
            search['host'] = host
122 120
            host = sql_escape_like(host)
123
            aggregates.add_filter(Host.name.ilike('%%%s%%' % host))
121
            aggregates.add_filter(aggregates.items.c.hostname.ilike(
122
                '%%%s%%' % host))
124 123

  
125 124
        if service:
126 125
            search['service'] = service
127 126
            service = sql_escape_like(service)
128
            aggregates.add_filter(ServiceLowLevel.servicename.ilike(
127
            aggregates.add_filter(aggregates.items.c.servicename.ilike(
129 128
                '%%%s%%' % service))
130 129

  
131 130
        if output:
......
213 212
        user_groups = user.groups
214 213

  
215 214
#        try:
215
        
216
        lls_query = DBSession.query(
217
            ServiceLowLevel.idservice.label("idsupitem"),
218
            ServiceLowLevel.servicename,
219
            Host.name.label("hostname")
220
        ).join(
221
           (Host, Host.idhost == ServiceLowLevel.idhost),
222
        ).outerjoin(
223
            (HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == ServiceLowLevel.idservice),
224
            (SERVICE_GROUP_TABLE, SERVICE_GROUP_TABLE.c.idservice == ServiceLowLevel.idservice),
225
        ).filter(
226
            or_(
227
                HOST_GROUP_TABLE.c.idgroup.in_(user_groups),
228
                SERVICE_GROUP_TABLE.c.idgroup.in_(user_groups),
229
            ),
230
        )
231
                            
232
        host_query = DBSession.query(
233
            Host.idhost.label("idsupitem"),
234
            "NULL",
235
            Host.name.label("hostname")
236
        ).join((HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == Host.idhost)
237
        ).filter(HOST_GROUP_TABLE.c.idgroup.in_(user_groups),
238
        )
239

  
240
        items = lls_query.union(host_query).subquery()
241
                
216 242
        event = DBSession.query(
217 243
                        CorrEvent.priority,
218 244
                        Event,
245
                        items.c.hostname,
246
                        items.c.servicename,
219 247
                 ).join(
220 248
                    (Event, CorrEvent.idcause == Event.idevent),
221
                    (ServiceLowLevel, Event.idsupitem == \
222
                        ServiceLowLevel.idservice),
223
                    (Host, Host.idhost == ServiceLowLevel.idhost),
224
                    (HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == \
225
                        Host.idhost),
226
                    (SERVICE_GROUP_TABLE, SERVICE_GROUP_TABLE.c.idservice == \
227
                        ServiceLowLevel.idservice),
228
                 ).filter(HOST_GROUP_TABLE.c.idgroup.in_(user_groups)
229
                 ).filter(SERVICE_GROUP_TABLE.c.idgroup.in_(user_groups)
249
                    (items, Event.idsupitem == items.c.idsupitem),
230 250
                 ).filter(
231 251
                    # On masque les événements avec l'état OK
232 252
                    # et traités (status == u'AAClosed').
......
236 256
                    ))
237 257
                ).filter(CorrEvent.idcorrevent == idcorrevent
238 258
                ).one()
259
                
260
                
239 261
#        except:
240 262
#            # XXX Raise some HTTP error.
241 263
#            return None
......
253 275
            # Rappel:
254 276
            # event[0] = priorité de l'alerte corrélée.
255 277
            # event[1] = alerte brute.
278
            if event[3]:
279
                service = urllib.quote(event[3])
280
            else:
281
                service = None
256 282
            eventdetails[edname] = edlink[1] % {
257 283
                'idcorrevent': idcorrevent,
258
                'host': urllib.quote(event[1].supitem.host.name),
259
                'service': urllib.quote(event[1].supitem.servicename),
284
                'host': urllib.quote(event[2]),
285
                'service': service,
260 286
                'message': urllib.quote(event[1].message),
261 287
            }
262 288

  
......
268 294
                peak_state = StateName.value_to_statename(
269 295
                                    event[1].peak_state),
270 296
                idcorrevent = idcorrevent,
271
                host = event[1].supitem.host.name,
272
                service = event[1].supitem.servicename,
297
                host = event[2],
298
                service = event[3],
273 299
                eventdetails = eventdetails,
274 300
            )
275 301

  
......
324 350
                   refresh_times=config['vigiboard_refresh_times'],
325 351
                )
326 352

  
327
    @validate(validators={'host': validators.NotEmpty(),
328
        'service': validators.NotEmpty()}, error_handler=process_form_errors)
353
    @validate(
354
        validators={
355
            'host': validators.NotEmpty(),
356
#            'service': validators.NotEmpty()
357
        }, 
358
        error_handler=process_form_errors)
329 359
    @expose('vigiboard.html')
330 360
    @require(Any(not_anonymous(), msg=l_("You need to be authenticated")))
331
    def host_service(self, host, service):
361
    def host_service(self, host, service=None):
332 362
        
333 363
        """
334 364
        Affichage de l'historique de l'ensemble des événements correspondant
......
339 369
        @param service: Nom du service souhaité
340 370
        """
341 371

  
372
        idsupitem = SupItem.get_supitem(host, service)
373

  
342 374
        username = request.environ['repoze.who.identity']['repoze.who.userid']
343 375
        events = VigiboardRequest(User.by_user_name(username))
344
        events.add_join((ServiceLowLevel, ServiceLowLevel.idservice == \
345
            Event.idsupitem))
346
        events.add_join((Host, ServiceLowLevel.idhost == Host.idhost))
347
        events.add_filter(Host.name == host,
348
                ServiceLowLevel.servicename == service)
376
        events.add_filter(events.items.c.idsupitem == idsupitem)
349 377

  
350 378
        # XXX On devrait avoir une autre API que ça !!!
351 379
        # Supprime le filtre qui empêche d'obtenir des événements fermés
352 380
        # (ie: ayant l'état Nagios 'OK' et le statut 'AAClosed').
353
        if len(events.filter) > 2:
354
            del events.filter[2]
381
        if len(events.filter) > 0:
382
            del events.filter[0]
355 383

  
356 384
        # Vérification qu'il y a au moins 1 événement qui correspond
357 385
        if events.num_rows() == 0 :
......
419 447
        
420 448
        # Si des changements sont survenus depuis que la 
421 449
        # page est affichée, on en informe l'utilisateur.
422
        if datetime.fromtimestamp(float(krgv['last_modification'])) \
423
                                        < get_last_modification_timestamp(ids):
424
            flash(_('Changes have occurred since the page was last displayed, '
450
        last_modification = get_last_modification_timestamp(ids, None)
451
        if last_modification and datetime.fromtimestamp(\
452
            float(krgv['last_modification'])) < last_modification:
453
            flash(_('Changes have occurred since the page was displayed, '
425 454
                    'your changes HAVE NOT been saved.'), 'warning')
455
            print "\n\n\n\n\n"
456
            print datetime.fromtimestamp(float(krgv['last_modification']))
457
            print get_last_modification_timestamp(ids)
458
            print "\n\n\n\n\n"
459
                        
426 460
            raise redirect(request.environ.get('HTTP_REFERER', url('/')))
427 461

  
428 462
        # Si l'utilisateur édite plusieurs événements à la fois,
......
538 572
        session.save()
539 573
        return dict()
540 574
    
541
def get_last_modification_timestamp(event_id_list):
575
def get_last_modification_timestamp(event_id_list, 
576
                                                value_if_none=datetime.now()):
542 577
    """
543 578
    Récupère le timestamp de la dernière modification 
544 579
    opérée sur l'un des événements dont l'identifiant
......
548 583
                                func.max(EventHistory.timestamp),
549 584
                         ).filter(EventHistory.idevent.in_(event_id_list)
550 585
                         ).scalar()
551
                         
552 586
    if not last_modification_timestamp:
553
        last_modification_timestamp = datetime.now()
554
    # On élimine la fraction (microsecondes) de l'objet datetime.
555
    # XXX Dans l'idéal, on devrait gérer les microsecondes.
556
    # Problème: les erreurs d'arrondis empêchent certaines modifications.
587
        if not value_if_none:
588
            return None
589
        else:
590
            last_modification_timestamp = value_if_none
557 591
    return datetime.fromtimestamp(mktime(
558 592
        last_modification_timestamp.timetuple()))
559

  
vigiboard/controllers/vigiboardrequest.py
11 11
from tg import url, config, tmpl_context
12 12
from vigiboard.model import DBSession
13 13
from sqlalchemy import not_, and_, asc, desc, sql
14
from sqlalchemy.sql.expression import or_
14
from sqlalchemy.sql.expression import or_, null as expr_null, union
15 15
from sqlalchemy.orm import aliased
16 16
from vigiboard.widgets.edit_event import EditEventForm
17 17
from vigiboard.widgets.search_form import SearchForm
......
54 54
        self.lang = lang
55 55
        self.generaterq = False
56 56
        
57
        associated_host = aliased(Host)
58
        lls_query = DBSession.query(ServiceLowLevel.idservice.label("idsupitem"),
59
                                    ServiceLowLevel.servicename,
60
                                    associated_host.name.label("hostname")
61
                            ).join((associated_host, 
62
                                    associated_host.idhost == ServiceLowLevel.idhost),
63
                            )     
57
        lls_query = DBSession.query(
58
            ServiceLowLevel.idservice.label("idsupitem"),
59
            ServiceLowLevel.servicename.label("servicename"),
60
            Host.name.label("hostname"),
61
            SERVICE_GROUP_TABLE.c.idgroup.label("idservicegroup"),
62
            HOST_GROUP_TABLE.c.idgroup.label("idhostgroup"),
63
        ).join(
64
           (Host, Host.idhost == ServiceLowLevel.idhost),
65
        ).outerjoin(
66
            (HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == ServiceLowLevel.idservice),
67
            (SERVICE_GROUP_TABLE, SERVICE_GROUP_TABLE.c.idservice == ServiceLowLevel.idservice),
68
        ).filter(
69
            or_(
70
                HOST_GROUP_TABLE.c.idgroup.in_(self.user_groups),
71
                SERVICE_GROUP_TABLE.c.idgroup.in_(self.user_groups),
72
            ),
73
        )
64 74
                            
65
        host_query = DBSession.query(Host.idhost.label("idsupitem"),
66
                                     "NULL",
67
                                     Host.name.label("hostname"))  
68
        
69
        items = lls_query.union(host_query).subquery()
75
        host_query = DBSession.query(
76
            Host.idhost.label("idsupitem"),
77
            expr_null().label("servicename"),
78
            Host.name.label("hostname"),
79
            expr_null().label("idservicegroup"),
80
            HOST_GROUP_TABLE.c.idgroup.label('idhostgroup'),
81
        ).join((HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == Host.idhost)
82
        ).filter(HOST_GROUP_TABLE.c.idgroup.label('idhostgroup').in_(self.user_groups),
83
        )
84

  
85
        # On est obligés d'utiliser sqlalchemy.sql.expression.union
86
        # pour indiquer à SQLAlchemy de NE PAS regrouper les tables
87
        # dans la requête principale, sans quoi les résultats sont
88
        # incorrects.
89
        self.items = union(lls_query, host_query, correlate=False).alias()
70 90

  
71 91
        self.table = [
72 92
            CorrEvent,
73 93
            sql.func.count(CorrEvent.idcorrevent),
74
            items.hostname,
75
            items.servicename,
94
            self.items.c.hostname,
95
            self.items.c.servicename,
76 96
        ]
77 97

  
78
#        self.join = [
79
#            (Event, CorrEvent.idcause == Event.idevent),
80
#            (ServiceLowLevel, Event.idsupitem == ServiceLowLevel.idservice),
81
#            (Host, Host.idhost == ServiceLowLevel.idhost),
82
#            (StateName, StateName.idstatename == Event.current_state),
83
#        ]
84
#
85
#        self.outerjoin = [
86
#            (HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == Host.idhost),
87
#            (SERVICE_GROUP_TABLE, SERVICE_GROUP_TABLE.c.idservice == \
88
#                ServiceLowLevel.idservice),
89
#        ]
90

  
91 98
        self.join = [
92 99
            (Event, CorrEvent.idcause == Event.idevent),
93
            (items, Event.idsupitem == items.c.idsupitem),
100
            (self.items, Event.idsupitem == self.items.c.idsupitem),
94 101
            (StateName, StateName.idstatename == Event.current_state),
95 102
        ]
96

  
97
        self.outerjoin = [
98
            (HOST_GROUP_TABLE, HOST_GROUP_TABLE.c.idhost == items.c.idsupitem),
99
            (SERVICE_GROUP_TABLE, SERVICE_GROUP_TABLE.c.idservice == \
100
                items.c.idsupitem),
101
        ]
103
        
104
        self.outerjoin = []
102 105

  
103 106
        self.filter = [
104
                or_(
105
                    HOST_GROUP_TABLE.c.idgroup.in_(self.user_groups),
106
                    SERVICE_GROUP_TABLE.c.idgroup.in_(self.user_groups),
107
                ),
108

  
109
                # On masque les événements avec l'état OK
110
                # et traités (status == u'AAClosed').
111
                not_(and_(
112
                    StateName.statename == u'OK',
113
                    CorrEvent.status == u'AAClosed'
114
                )),
115
                CorrEvent.timestamp_active != None,
116
            ]
107
            # On masque les événements avec l'état OK
108
            # et traités (status == u'AAClosed').
109
            not_(and_(
110
                StateName.statename == u'OK',
111
                CorrEvent.status == u'AAClosed'
112
            )),
113
            CorrEvent.timestamp_active != None,
114
        ]
117 115

  
118 116
        # Permet de définir le sens de tri pour la priorité.
119 117
        if config['vigiboard_priority_order'] == 'asc':
......
122 120
            priority_order = desc(CorrEvent.priority)
123 121

  
124 122
        self.orderby = [
125
                desc(CorrEvent.status),   # None, Acknowledged, AAClosed
126
                priority_order,                 # Priorité ITIL (entier).
127
                desc(StateName.order),          # Etat courant (entier).
128
                desc(Event.timestamp),
129
                asc(items.c.hostname),
130
            ]
123
            desc(CorrEvent.status),         # None, Acknowledged, AAClosed
124
            priority_order,                 # Priorité ITIL (entier).
125
            desc(StateName.order),          # Etat courant (entier).
126
            desc(Event.timestamp),
127
            asc(self.items.c.hostname),
128
        ]
131 129

  
132 130
        self.groupby = [
133
                CorrEvent.idcorrevent,
134 131
                CorrEvent,
135
                items.c.hostname,
132
                self.items.c.hostname,
133
                self.items.c.servicename,
136 134
                StateName.order,
137 135
                Event.timestamp,
138 136
            ]
......
193 191
            self.req = self.req.group_by(i)
194 192
        for i in self.orderby:
195 193
            self.req = self.req.order_by(i)
196
#        raise ValueError, self.req.statement
197 194

  
198 195
    def num_rows(self):
199 196

  
......
391 388
                event = req
392 389
            else:
393 390
                event = req[0]
391
                hostname = req[2]
392
                servicename = req[3]
394 393
            ids.append(event.idcause)
395 394

  
396 395
            # La liste pour l'événement actuel comporte dans l'ordre :
......
407 406

  
408 407
            events.append([
409 408
                    event,
409
                    hostname,
410
                    servicename,
410 411
                    {'class': class_tr[i % 2]},
411 412
                    {'class': StateName.value_to_statename(
412 413
                        cause.initial_state) +

Also available in: Unified diff