Project

General

Profile

Revision 3d0d254c

ID3d0d254cf9f9d1b45e6a3e56a7fcbaad4cc344e4
Parent be29aa96
Child c49defb8

Added by Francois POIROTTE over 14 years ago

Utilisation de idaggregate de préférence par rapport à idevent (permet d'obtenir plus d'informations).
On suppose que la base de données génère les id des events (le corrélateur et le connector-db sont en train d'être modifiés pour suivre ce changement).
Utilisation de HighLevelService plutôt que ServiceHautNiveau.

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

View differences:

development.ini
39 39
; - %(host)s
40 40
; - %(service)s
41 41
; - %(tt)s
42
vigiboard_links.tt = http://example4.com/%%(idevent)s/%%(tt)s
42
vigiboard_links.tt = http://example4.com/%%(idaggregate)d/%%(tt)s
43 43

  
44 44
; Default font size, must be a valid size as per the CSS 2.1 specification.
45 45
; See http://www.w3.org/TR/CSS21/fonts.html#font-size-props
......
111 111

  
112 112
# If you create additional loggers, add them as a key to [loggers]
113 113
[logger_root]
114
level = DEBUG
115
handlers = root_log
114
level = INFO
115
handlers = console
116 116

  
117 117
[logger_vigiboard]
118 118
level = DEBUG
......
120 120
qualname = vigiboard
121 121

  
122 122
[logger_sqlalchemy]
123
level = DEBUG
123
level = INFO
124 124
handlers = sql_log
125 125
qualname = sqlalchemy.engine
126 126

  
127 127
# A logger for authentication, identification and authorization -- this is
128 128
# repoze.who and repoze.what:
129 129
[logger_auth]
130
level = DEBUG
130
level = WARN
131 131
handlers = auth_log
132 132
qualname = auth
133 133

  
vigiboard/config/app_cfg.py
88 88
# Links configuration
89 89
# XXX Should be part of ini settings.
90 90
base_config['vigiboard_links.eventdetails'] = {
91
        'nagios': ['Nagios host details', 'http://example1.com/%(idevent)s'],
92
        'metrology': ['Metrology details', 'http://example2.com/%(idevent)s'],
93
        'security': ['Security details', 'http://example3.com/%(idevent)s'],
94
        'servicetype': ['Service Type', 'http://example4.com/%(idevent)s'],
91
    'nagios': ['Nagios host details', 'http://example1.com/%(idaggregate)d'],
92
    'metrology': ['Metrology details', 'http://example2.com/%(idaggregate)d'],
93
    'security': ['Security details', 'http://example3.com/%(idaggregate)d'],
94
    'servicetype': ['Service Type', 'http://example4.com/%(idaggregate)d'],
95 95
}
96 96

  
97 97
# Plugins to use
vigiboard/controllers/root.py
17 17
from vigiboard.controllers.vigiboardrequest import VigiboardRequest
18 18
from vigiboard.controllers.vigiboard_controller import VigiboardRootController
19 19

  
20
__all__ = ['RootController']
20
__all__ = ('RootController', )
21 21

  
22 22
class RootController(VigiboardRootController):
23 23
    
......
69 69
            page = 1
70 70

  
71 71
        username = request.environ['repoze.who.identity']['repoze.who.userid']
72
        events = VigiboardRequest(User.by_user_name(username))
72
        aggregates = VigiboardRequest(User.by_user_name(username))
73 73
        
74 74
        search = {
75 75
            'host': '',
......
82 82
            search['host'] = host
83 83
            host = host.replace('%', '\\%').replace('_', '\\_') \
84 84
                    .replace('*', '%').replace('?', '_')
85
            events.add_filter(Event.hostname.like('%%%s%%' % host))
85
            aggregates.add_filter(Event.hostname.like('%%%s%%' % host))
86 86

  
87 87
        if service :
88 88
            search['service'] = service
89 89
            service = service.replace('%', '\\%').replace('_', '\\_') \
90 90
                    .replace('*', '%').replace('?', '_')
91
            events.add_filter(Event.servicename.like('%%%s%%' % service))
91
            aggregates.add_filter(Event.servicename.like('%%%s%%' % service))
92 92

  
93 93
        if output :
94 94
            search['output'] = output
95 95
            output = output.replace('%', '\\%').replace('_', '\\_') \
96 96
                    .replace('*', '%').replace('?', '_')
97
            events.add_filter(Event.message.like('%%%s%%' % output))
97
            aggregates.add_filter(Event.message.like('%%%s%%' % output))
98 98

  
99 99
        if trouble_ticket :
100 100
            search['tt'] = trouble_ticket
101 101
            trouble_ticket = trouble_ticket.replace('%', '\\%') \
102 102
                    .replace('_', '\\_').replace('*', '%').replace('?', '_')
103
            events.add_filter(EventsAggregate.trouble_ticket.like(
103
            aggregates.add_filter(EventsAggregate.trouble_ticket.like(
104 104
                '%%%s%%' % trouble_ticket))
105 105

  
106 106
        # Calcul des éléments à afficher et du nombre de pages possibles
107
        total_rows = events.num_rows()
108
       
107
        total_rows = aggregates.num_rows()
109 108
        item_per_page = int(config['vigiboard_item_per_page'])
110 109

  
111
        if total_rows <= item_per_page * (page-1) :
110
        if total_rows <= item_per_page * (page-1):
112 111
            page = 1
113 112
        id_first_row = item_per_page * (page-1)
114 113
        id_last_row = min(id_first_row + item_per_page, total_rows)
115 114

  
116
        events.format_events(id_first_row, id_last_row)
117
        events.generate_tmpl_context() 
115
        aggregates.format_events(id_first_row, id_last_row)
116
        aggregates.generate_tmpl_context()
117

  
118 118
        return dict(
119
               events = events.events,
119
               events = aggregates.events,
120 120
               rows_info = {
121
                'id_first_row': id_first_row + 1,
122
                'id_last_row': id_last_row,
123
                'total_rows': total_rows,
121
                   'id_first_row': id_first_row + 1,
122
                   'id_last_row': id_last_row,
123
                   'total_rows': total_rows,
124 124
               },
125 125
               pages = range(1, (total_rows / item_per_page) + 2),
126 126
               page = page,
127 127
               event_edit_status_options = edit_event_status_options,
128 128
               history = [],
129 129
               hist_error = False,
130
               plugin_context = events.context_fct,
130
               plugin_context = aggregates.context_fct,
131 131
               search = search,
132 132
            )
133 133
      
134
    @validate(validators={'idevent':validators.String(not_empty=True)},
134
    @validate(validators={'idaggregate':validators.Int(not_empty=True)},
135 135
            error_handler=process_form_errors)
136 136
    @expose('json')
137 137
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
138
    def history_dialog(self, idevent):
138
    def history_dialog(self, idaggregate):
139 139
        
140 140
        """
141 141
        JSon renvoyant les éléments pour l'affichage de la fenêtre de dialogue
......
154 154
                        EventsAggregate.severity,
155 155
                        Event.hostname,
156 156
                        Event.servicename,
157
                        Event.idevent
157 158
                 ).join(
158 159
                    (Event, EventsAggregate.idcause == Event.idevent),
159 160
                    (HostGroup, Event.hostname == HostGroup.hostname),
160 161
                 ).filter(HostGroup.groupname.in_(user.groups)
161
                 ).filter(EventsAggregate.idcause == idevent).one()
162
                 ).filter(EventsAggregate.idaggregate == idaggregate).one()
162 163

  
163 164
        initial_state = DBSession.query(
164 165
                    EventHistory,
165
                 ).filter(EventHistory.idevent == idevent
166
                 ).filter(EventHistory.idevent == event.idevent
166 167
                 ).order_by(asc(EventHistory.timestamp)
167 168
                 ).order_by(asc(EventHistory.type_action))
168 169

  
......
183 184
                config['vigiboard_links.eventdetails'].iteritems():
184 185

  
185 186
            eventdetails[edname] = edlink[1] % {
186
                    'idevent': idevent,
187
                    'idaggregate': idaggregate,
187 188
                    'host': event.hostname,
188 189
                    'service': event.servicename
189 190
                    }
......
191 192
        return dict(
192 193
                initial_state = severity[int(initial_state)],
193 194
                current_state = severity[event.severity],
194
                idevent = idevent,
195
                idaggregate = idaggregate,
195 196
                host = event.hostname,
196 197
                service = event.servicename,
197 198
                eventdetails = eventdetails
198 199
            )
199 200

  
200
    @validate(validators={'idevent':validators.String(not_empty=True)},
201
    @validate(validators={'idaggregate':validators.Int(not_empty=True)},
201 202
            error_handler=process_form_errors)
202 203
    @expose('vigiboard.templates.vigiboard')
203 204
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
204
    def event(self, idevent):
205
    def event(self, idaggregate):
205 206
        """
206 207
        Affichage de l'historique d'un évènement.
207 208
        Pour accéder à cette page, l'utilisateur doit être authentifié.
......
211 212

  
212 213
        username = request.environ['repoze.who.identity']['repoze.who.userid']
213 214
        events = VigiboardRequest(User.by_user_name(username))
214
        events.add_filter(EventsAggregate.idcause == idevent)
215
        events.add_filter(EventsAggregate.idaggregate == idaggregate)
215 216
        
216 217
        # Vérification que l'évènement existe
217 218
        if events.num_rows() != 1 :
......
293 294
                )
294 295

  
295 296
    @validate(validators={
296
        "id":validators.Regex(r'^[^,]+(,[^,]*)*,?$'),
297
        "trouble_ticket":validators.Regex(r'^[0-9]*$'),
297
        "id":validators.Regex(r'^[0-9]+(,[0-9]*)*,?$'),
298
#        "trouble_ticket":validators.Regex(r'^[0-9]*$'),
298 299
        "status":validators.OneOf(['NoChange', 'None', 'Acknowledged',
299 300
                'AAClosed'])
300 301
        }, error_handler=process_form_errors)
......
320 321
        
321 322
        username = request.environ['repoze.who.identity']['repoze.who.userid']
322 323
        events = VigiboardRequest(User.by_user_name(username))
323
        events.add_filter(EventsAggregate.idcause.in_(ids))
324
        events.add_filter(EventsAggregate.idaggregate.in_(ids))
324 325
        
325 326
        # Vérification que au moins un des identifiants existe et est éditable
326 327
        if events.num_rows() <= 0 :
......
332 333
        
333 334
        username = request.environ['repoze.who.identity']['repoze.who.userid']
334 335

  
335
        for req in events.req :
336
        for req in events.req:
336 337
            if isinstance(req, EventsAggregate):
337 338
                event = req
338 339
            else:
......
359 360
                        username=username,
360 361
                    )
361 362
                DBSession.add(history)
362
       
363

  
364
        DBSession.flush()       
363 365
        flash(_('Updated successfully'))
364 366
        redirect(request.environ.get('HTTP_REFERER', url('/')))
365 367

  
366 368

  
367 369
    @validate(validators={"plugin_name":validators.OneOf(
368
        [i for [i,j] in config.get('vigiboard_plugins', [])])},
370
        [i for [i, j] in config.get('vigiboard_plugins', [])])},
369 371
                error_handler = process_form_errors)
370 372
    @expose('json')
371 373
    def get_plugin_value(self, plugin_name, *arg, **krgv):
vigiboard/controllers/vigiboard_plugin/__init__.py
26 26
        self.style = style
27 27
        self.object_name = object_name
28 28

  
29
    def __show__ (self, event):
29
    def __show__ (self, aggregate):
30 30

  
31 31
        """
32 32
        Permet d'éviter toutes erreurs d'affichage.
33 33
        C'est la fonction appelée par le formateur d'évènements.
34 34
        """
35 35

  
36
        show = self.show(event)
36
        show = self.show(aggregate)
37 37

  
38
        if show != None :
38
        if show != None:
39 39
            try:
40 40
                return str(show)
41 41
            except:
42 42
                return _('Error')
43 43

  
44
    def show(self, event):
44
    def show(self, aggregate):
45 45

  
46 46
        """
47 47
        Fonction qui affichera par défaut une chaîne de
vigiboard/controllers/vigiboard_plugin/shn.py
6 6

  
7 7
from vigiboard.controllers.vigiboard_plugin import \
8 8
        VigiboardRequestPlugin
9
from vigiboard.model import DBSession, ServiceHautNiveau, Event
10
from sqlalchemy import sql
9
from vigiboard.model import DBSession, EventsAggregate#, HighLevelService
11 10
from pylons.i18n import gettext as _
12 11
from tg import tmpl_context, url
13 12
from tw.jquery.ui_dialog import JQueryUIDialog
......
16 15

  
17 16
    """
18 17
    Plugin permettant de rajouter le nombre de SHNs impactés à
19
    l'affichage
18
    l'affichage et d'obtenir une liste détaillée de ces SHNs.
20 19
    """
21 20

  
22 21
    def __init__(self):
23 22
        super(PluginSHN, self).__init__(
24
            table = [ServiceHautNiveau.servicename_dep,
25
                sql.func.count(Event.idevent)],
26
            outerjoin = [(ServiceHautNiveau,
27
                ServiceHautNiveau.servicename_dep == Event.servicename)],
28
            groupby = [(Event),(ServiceHautNiveau.servicename_dep)],
29 23
            name = _(u'Impacted HLS'),
30 24
            style = {'title': _(u'Impacted High-Level Services'),
31 25
                'style': 'text-align:center'},
32 26
            object_name = "shn"
33 27
        )
34 28
    
35
    def show(self, req):
29
    def show(self, aggregate):
36 30
        """Fonction d'affichage"""
37
        if not req[1] is None:
38
            dico = {
39
                'baseurl': url('/'),
40
                'idevent': req[0].idcause,
41
                'impacted_hls': req[2],
42
            }
43
            return '<a href="javascript:vigiboard_shndialog(\'%(baseurl)s\','\
44
                    '\'%(idevent)s\')" class="SHNLien">%(impacted_hls)d</a>' % \
45
                    dico
46
        else:
47
            return ""
31
        dico = {
32
            'baseurl': url('/'),
33
            'idaggregate': aggregate.idaggregate,
34
            'impacted_hls': len(aggregate.highlevel),
35
        }
36
        # XXX Il faudrait échapper l'URL contenue dans baseurl
37
        # pour éviter des attaques de type XSS.
38
        res = ('<a href="javascript:vigiboard_shndialog(' + \
39
                '\'%(baseurl)s\',\'%(idaggregate)d\')" ' + \
40
                'class="SHNLien">%(impacted_hls)d</a>') % dico
41
        return res
48 42

  
49 43
    def context(self, context):
50 44
        """Fonction de context"""
51 45

  
52
        # XXX We insert 10 unbreakable spaces (&#160;) to workaround a bug
53
        # in JQuery where the dialog's width is incorrectly set.
46
        # On ajoute 10 espaces insécables pour éviter un bug de JQueryUIDialog:
47
        # le calcul de la taille de la boîte de dialogue ne tient pas compte
48
        # de l'espace occupé par la croix permettant de fermer le dialogue.
49
        # Du coup, elle se retrouve superposée au titre de la boîte.
54 50
        tmpl_context.shndialog = JQueryUIDialog(id='SHNDialog',
55 51
                autoOpen=False, title='%s%s' % (_(u'High-Level Service'),
56 52
                '&#160;' * 10))
......
58 54

  
59 55
    def controller(self, *argv, **krgv):
60 56
        """Ajout de fonctionnalités au contrôleur"""
61
        idevent = krgv['idevent']
62
        service = DBSession.query(Event.servicename
63
                ).filter(Event.idevent == idevent).one().servicename
57
        idaggregate = krgv['idaggregate']
58
        aggregate = DBSession.query(EventsAggregate) \
59
                .filter(EventsAggregate.idaggregate == idaggregate).one()
60
        shns = aggregate.highlevel
64 61

  
65
        shns = DBSession.query(ServiceHautNiveau.servicename
66
                ).filter(ServiceHautNiveau.servicename_dep == service)
67
        return dict( shns = [shn.servicename for shn in shns]) 
62
        return dict(shns=[shn.servicename for shn in shns]) 
68 63

  
vigiboard/controllers/vigiboard_plugin/tests.py
19 19
            groupby=[EventHistory.idevent],
20 20
        )
21 21

  
22
    def show(self, req):
22
    def show(self, aggregate):
23 23
        """Fonction d'affichage"""
24
        return req[1]
24
        return aggregate
25 25

  
vigiboard/controllers/vigiboardrequest.py
6 6
        Host, HostGroup, Service, ServiceGroup
7 7
from tg import tmpl_context, url, config
8 8
from vigiboard.model import DBSession
9
from sqlalchemy import not_ , and_ , asc , desc
9
from sqlalchemy import not_, and_, asc, desc, sql
10 10
from tw.jquery.ui_dialog import JQueryUIDialog
11 11
from vigiboard.widgets.edit_event import EditEventForm , SearchForm
12 12
from vigiboard.controllers.vigiboard_plugin import VigiboardRequestPlugin
......
59 59

  
60 60
        self.generaterq = False
61 61

  
62
        self.table = [EventsAggregate]
62
        self.table = [
63
            EventsAggregate,
64
            sql.func.count(EventsAggregate.idaggregate)
65
        ]
63 66

  
64 67
        self.join = [
65 68
                (Event, EventsAggregate.idcause == Event.idevent),
......
75 78
                HostGroup.groupname.in_(self.user_groups),
76 79
                ServiceGroup.groupname.in_(self.user_groups),
77 80
                not_(and_(Event.active == False,
78
                    EventsAggregate.status == 'AAClosed')),
81
                    EventsAggregate.status == u'AAClosed')),
79 82
                EventsAggregate.timestamp_active != None#,
80 83
                #not_(Event.timestamp_active.like('0000-00-00 00:00:00'))
81 84
            ]
......
134 137
            try:
135 138
                mypac = __import__(
136 139
                    'vigiboard.controllers.vigiboard_plugin.' +\
137
                            plug[0],globals(), locals(), [plug[1]],-1)
140
                            plug[0], globals(), locals(), [plug[1]], -1)
138 141
                self.add_plugin(getattr(mypac, plug[1])())
139 142
            except:
140 143
                raise
......
162 165
        @return: Nombre de ligne
163 166
        """
164 167

  
165
        if not self.generaterq :
168
        if not self.generaterq:
166 169
            self.generate_request()
167 170
            self.generaterq = True
168 171
        return self.req.count()
......
329 332
        for req in self.req[first_row : last_row]:
330 333
            # Si il y a plus d'un élément dans la liste des tables,
331 334
            # rq devient une liste plutôt que d'être directement la
332
            # table souhaité
333
            
334
            if isinstance(req, EventsAggregate) :
335
            # table souhaitée
336

  
337
            if isinstance(req, EventsAggregate):
335 338
                event = req
336 339
            else:
337 340
                event = req[0]
......
358 361
                        {'src' : '/images/%s2.png' % \
359 362
                                self.bouton_severity[event.severity].upper()},
360 363
                        self.format_events_img_status(event),
361
                        [[j.__show__(req), j.style] for j in self.plugin]
364
                        [[j.__show__(event), j.style] for j in self.plugin]
362 365
                    ])
363 366

  
364 367
            else:
......
371 374
                        {'src' : '/images/%s2.png' % \
372 375
                                self.bouton_severity[event.severity].upper()},
373 376
                        self.format_events_img_status(event),
374
                        [[j.__show__(req), j.style] for j in self.plugin]
377
                        [[j.__show__(event), j.style] for j in self.plugin]
375 378
                    ])
376 379
            i += 1
377 380

  
vigiboard/model/__init__.py
12 12
from vigilo.models import Graph, GraphGroup, GraphToGroups
13 13
from vigilo.models import Version, PerfDataSource, Group
14 14
from vigilo.models import Host, HostGroup
15
from vigilo.models import Service, ServiceGroup, \
16
                            ServiceHautNiveau, ServiceTopo
15
from vigilo.models import Service, ServiceGroup, HighLevelService
17 16

  
vigiboard/public/javascript/vigiboard_plugin/shn.js
1 1

  
2 2
function vigiboard_shndialog(url,idd) {
3
	$.getJSON(url+'/get_plugin_value',{plugin_name:'shn',idevent:idd},function(json){ 				
3
	$.getJSON(url+'get_plugin_value',{plugin_name:'shn',idaggregate:idd},function(json){ 				
4 4
		var ht = '';
5 5
		for (var i = 0; i < json.shns.length; i++) {
6 6
			ht += '<li>' + json.shns[i] + '</li>';
vigiboard/templates/vigiboard_event_table.html
10 10

  
11 11
<py:if test="len(events) > 1">
12 12
<table class="vigitable" summary="Event table">
13
	
14 13
	<thead>
15 14
		<tr >
16 15
			<td style="width:26px;border-right: solid 1px #4682b4">
......
47 46
	<tbody>
48 47
		<py:for each="(event,class_tr,class_td_severity,class_td_date,img_fleche,img_statu,plugin) in events[1:]">
49 48
		<tr py:attrs="class_tr">
50
			<td style="padding: 3px;" py:attrs="class_td_severity"><a href="javascript:vigiboard_historydialog('${event.idcause}')" class="HistoryLien"><img src="${tg.url(img_fleche['src'])}" style="width:20px" alt="Details" title="Event details" /></a></td>
51
			<td py:attrs="class_td_date"><span style="font-weight: bold;">${event.get_date('timestamp_active')}</span><br />[${event.get_since_date('timestamp_active')}]</td>
49
			<td style="padding: 3px;" py:attrs="class_td_severity">
50
			    <a href="javascript:vigiboard_historydialog('${event.idaggregate}')" class="HistoryLien"><img src="${tg.url(img_fleche['src'])}" style="width:20px" alt="Details" title="Event details" /></a>
51
		    </td>
52
			<td py:attrs="class_td_date">
53
			    <span style="font-weight: bold;">${event.get_date('timestamp_active')}</span>
54
			    <br />[${event.get_since_date('timestamp_active')}]
55
			 </td>
52 56
			<td py:attrs="class_td_date" style="text-align:center">${event.occurrences}</td>
53 57
			<td>${event.cause.hostname}</td>
54 58
			<td>${event.cause.servicename}</td>
......
56 60
			<td py:for="plug in plugin" py:attrs="plug[1]">${HTML(plug[0])}</td>
57 61
			<td style="text-align: center"><a py:if="event.trouble_ticket is not None" href="${
58 62
					tg.config['vigiboard_links.tt'] % {
59
						'idevent' : event.idcause,
60
						'host' : event.cause.hostname,
61
						'service' : event.cause.servicename,
62
						'tt' : event.trouble_ticket }}">[${event.trouble_ticket}]</a></td>
63
						'idaggregate': event.idaggregate,
64
						'host': event.cause.hostname,
65
						'service': event.cause.servicename,
66
						'tt': event.trouble_ticket }}">[${event.trouble_ticket}]</a></td>
63 67
			<td style="text-align: center"><img py:attrs="img_statu" py:if="img_statu != None" alt="Status" title="Event status"/></td>
64
			<td py:attrs="class_td_date" style="padding: 0px;text-align: center"><a class="Edit_EventsLien" href="javascript:vigiboard_edit_eventdialog('${event.idcause}')"><img src="${tg.url('/images/icon_page_edit.png')}" alt="Edit" title="Edit this event"/></a></td>
65
			<td py:attrs="class_td_date" style="padding:0px;text-align: center"><input type="checkbox" class="Edit_EventsCheckBox" value="${event.idcause}"/></td>
68
			<td py:attrs="class_td_date" style="padding: 0px;text-align: center"><a class="Edit_EventsLien" href="javascript:vigiboard_edit_eventdialog('${event.idaggregate}')"><img src="${tg.url('/images/icon_page_edit.png')}" alt="Edit" title="Edit this event"/></a></td>
69
			<td py:attrs="class_td_date" style="padding:0px;text-align: center"><input type="checkbox" class="Edit_EventsCheckBox" value="${event.idaggregate}"/></td>
66 70
		</tr>
67 71

  
68 72
    		<py:if test="hist_error == True">
......
86 90

  
87 91
<script type="text/javascript">
88 92
	function vigiboard_historydialog(idd) {
89
		$.getJSON("${tg.url('/history_dialog')}",{idevent:idd},function(json){
93
		$.getJSON("${tg.url('/history_dialog')}",{idaggregate:idd},function(json){
90 94
			$('#HistoryDialog_initial_state').html(json.initial_state);
91 95
			$('#HistoryDialog_current_state').html(json.current_state);
92
			$('#HistoryDialog_detailed_event').attr('href' , '${tg.url('/event/')}' + json.idevent);
96
			$('#HistoryDialog_detailed_event').attr('href', '${tg.url('/event/')}' + json.idaggregate);
93 97
			$('#HistoryDialog_detailed_host').attr('href', '${tg.url('/host_service/')}' + json.host + "/" + json.service);
94 98
			<py:for each="edname, edit in tg.config['vigiboard_links.eventdetails'].iteritems()">
95 99
			$('#HistoryDialog_${edname}').attr('href', json.eventdetails['${edname}']);
vigiboard/tests/functional/test_vigiboardrequest.py
84 84
            'message': u'foo',
85 85
        }
86 86

  
87
        event1 = Event(idevent=u'foo42', hostname=u'monhost',
87
        event1 = Event(hostname=u'monhost',
88 88
            servicename=u'monservice', **event_template)
89
        event2 = Event(idevent=u'foo43', hostname=u'monhostuser',
89
        event2 = Event(hostname=u'monhostuser',
90 90
            servicename=u'monservice', **event_template)
91
        event3 = Event(idevent=u'foo44', hostname=u'monhost',
91
        event3 = Event(hostname=u'monhost',
92 92
            servicename=u'monserviceuser', **event_template)
93
        event4 = Event(idevent=u'foo45', hostname=u'monhostuser',
93
        event4 = Event(hostname=u'monhostuser',
94 94
            servicename=u'monserviceuser', **event_template)
95 95

  
96 96
        DBSession.add(event1)
......
125 125
            'severity': 0,
126 126
            'status': u'None',
127 127
        }
128
        self.aggregate1 = EventsAggregate(idcause=u'foo42', **aggregate_template)
129
        self.aggregate2 = EventsAggregate(idcause=u'foo45', **aggregate_template)
128
        self.aggregate1 = EventsAggregate(
129
            idcause=event1.idevent, **aggregate_template)
130
        self.aggregate2 = EventsAggregate(
131
            idcause=event4.idevent, **aggregate_template)
132

  
130 133
        self.aggregate1.events.append(event1)
131 134
        self.aggregate1.events.append(event3)
132 135
        self.aggregate2.events.append(event4)

Also available in: Unified diff