Project

General

Profile

Revision 20367931

ID20367931826425cf944d798b717c132dfae9ab42
Parent ed374445
Child 089dfbc2

Added by Thomas ANDREJAK almost 15 years ago

Réorganisation du code (controllers, etc)
Mise en place d'un système de plugin pour ajouter des colonnes à la volée
Internationalisation complète
Création de quelques tests

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

View differences:

README_jquery/ui_dialog.py
22 22
from tw.forms import FormField
23 23
from ui_core import jquery_ui_core_js
24 24
from ui import ui_dialog_js , ui_draggable_js, ui_resizable_js
25
__all__ = ["jquery_ui_dialog_js"]
26

  
27

  
28
# declare your static resources here
29 25

  
30
## JS dependencies can be listed at 'javascript' so they'll get included
31
## before
26
__all__ = ["jquery_ui_dialog_js"]
32 27

  
33 28
jquery_ui_dialog_css    = CSSLink(modname=__name__, filename='static/css/ui.all.css')
34
#jquery_ui_dialog_js    = JSLink(modname=__name__, filename='static/javascript/ui/ui.dialog.js', javascript=[jquery_ui_core_js,jquery_direction_js])
35

  
36
#jquery_ui_draggable_js =  JSLink(modname=__name__, filename='static/javascript/ui/ui.draggable.js')
37

  
38 29

  
39 30
jQuery = js_function('jQuery')
40 31

  
......
90 81
			stack = self.stack,
91 82
			title = self.title,
92 83
			width = self.width,
93
			zindex = self.zindex#,
94
			#open = js_callback('function(event,ui) { for ( i in event ) { alert(i);}}') # $(\'#%s\').dialog(\'option\' , \'position\' , \'top\')}' % d.id )
84
			zindex = self.zindex
95 85

  
96 86
			)
97 87
        self.add_call(jQuery("#%s" % d.id).dialog(dialog_params))
98
	
99
        
bdd.sql
1
REATE TABLE IF NOT EXISTS `graph` (
2
  `name` varchar(100) NOT NULL,
3
  `template` varchar(2500) NOT NULL,
4
  `vlabel` varchar(2500) NOT NULL,
5
  PRIMARY KEY (`name`)
6
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
7

  
8

  
9

  
10

  
11

  
12
CREATE TABLE IF NOT EXISTS `graphgroups` (
13
  `graphname` varchar(100) NOT NULL,
14
  `idgraphgroup` int(10) unsigned NOT NULL,
15
  `parent` int(10) unsigned NOT NULL,
16
  PRIMARY KEY (`graphname`,`idgraphgroup`),
17
  FOREIGN KEY (graphname) REFERENCES graph(name)
18
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
19

  
20

  
21

  
22

  
23

  
24

  
25
CREATE TABLE IF NOT EXISTS `host` (
26
  `name` varchar(255) NOT NULL,
27
  `checkhostcmd` varchar(255) NOT NULL,
28
  `community` varchar(255) NOT NULL,
29
  `fqhn` varchar(255) NOT NULL,
30
  `hosttpl` varchar(255) NOT NULL,
31
  `mainip` varchar(255) NOT NULL,
32
  `port` int(10) unsigned NOT NULL,
33
  `snmpoidsperpdu` int(10) unsigned DEFAULT NULL,
34
  `snmpversion` varchar(255) DEFAULT NULL,
35
  PRIMARY KEY (`name`)
36
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
37

  
38

  
39

  
40

  
41

  
42
CREATE TABLE IF NOT EXISTS `service` (
43
  `name` varchar(255) NOT NULL,
44
  `type` varchar(255) NOT NULL,
45
  `command` varchar(255) NOT NULL,
46
  PRIMARY KEY (`name`)
47
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
48

  
49

  
50

  
51

  
52

  
53
CREATE TABLE IF NOT EXISTS `events` (
54
  `idevent` int(10) unsigned NOT NULL AUTO_INCREMENT,
55
  `hostname` varchar(100) NOT NULL,
56
  `servicename` varchar(100) DEFAULT NULL,
57
  `service_source` varchar(100) NOT NULL,
58
  `severity` int(10) unsigned NOT NULL,
59
  `status` enum( 'None', 'Acknowledged', 'Closed' ) NOT NULL DEFAULT 'None',
60
  `active` bool DEFAULT TRUE,
61
  `timestamp` datetime DEFAULT NULL,
62
  `output` text NOT NULL,
63
  `event_timestamp` datetime DEFAULT NULL,
64
  `last_check` datetime DEFAULT NULL,
65
  `recover_output` text,
66
  `timestamp_active` datetime DEFAULT NULL,
67
  `timestamp_cleared` datetime DEFAULT NULL,
68
  `trouble_ticket` varchar(20) DEFAULT NULL,
69
  `occurence` int(10) unsigned DEFAULT NULL,
70
  PRIMARY KEY (`idevent`),
71
  FOREIGN KEY (`servicename`) REFERENCES service(name),
72
  FOREIGN KEY (`hostname`) REFERENCES host(name),
73
  INDEX (`hostname`,`servicename`)
74
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
75

  
76

  
77

  
78

  
79
CREATE TABLE IF NOT EXISTS `event_history` (
80
  `idhistory` int(10) unsigned NOT NULL AUTO_INCREMENT,
81
  `type_action` varchar(50) NOT NULL,
82
  `idevent` int(10) unsigned NOT NULL,
83
  `key` varchar(255) DEFAULT NULL,
84
  `value` text,
85
  `timestamp` datetime DEFAULT NULL,
86
  `username` varchar(255) DEFAULT NULL,
87
  PRIMARY KEY (`idhistory`),
88
  INDEX (`idevent`),
89
  FOREIGN KEY ( idevent) REFERENCES events(idevent)
90
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
91

  
92

  
93

  
94

  
95

  
96

  
97
CREATE TABLE IF NOT EXISTS `groups` (
98
  `name` varchar(100) NOT NULL,
99
  `parent` varchar(100) DEFAULT NULL,
100
  PRIMARY KEY (`name`),
101
  FOREIGN KEY (parent) REFERENCES groups(name)
102
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
103
CREATE TABLE IF NOT EXISTS `grouppermissions` (
104
  `groupname` varchar(100) NOT NULL,
105
  `idpermission` int(10) unsigned NOT NULL,
106
  FOREIGN KEY (groupname) REFERENCES groups(name),
107
   PRIMARY KEY (groupname,idpermission)
108
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
109

  
110

  
111

  
112

  
113

  
114

  
115
CREATE TABLE IF NOT EXISTS `hostgroups` (
116
  `hostname` varchar(100) NOT NULL,
117
  `groupname` varchar(100) NOT NULL,
118
  PRIMARY KEY (`hostname`,`groupname`),
119
  FOREIGN KEY (hostname) REFERENCES host(name),
120
  FOREIGN KEY (groupname) REFERENCES groups(name)
121
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
122

  
123

  
124

  
125

  
126

  
127
CREATE TABLE IF NOT EXISTS `servicegroups` (
128
  `servicename` varchar(100) NOT NULL,
129
  `groupname` varchar(100) NOT NULL,
130
  PRIMARY KEY (`servicename`,`groupname`),
131
  FOREIGN KEY (servicename) REFERENCES service(name),
132
  FOREIGN KEY (groupname) REFERENCES groups(name)
133
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
134

  
135

  
136

  
137

  
138

  
139

  
140

  
141
CREATE TABLE IF NOT EXISTS `perfdatasource` (
142
  `hostname` varchar(100) NOT NULL,
143
  `servicename` varchar(100) NOT NULL,
144
  `graphname` varchar(100) NOT NULL,
145
  `type` varchar(100) NOT NULL,
146
  `label` varchar(255) DEFAULT NULL,
147
  `factor` float NOT NULL,
148
  PRIMARY KEY (`hostname`,`servicename`),
149
  FOREIGN KEY (hostname) REFERENCES host(name),
150
  FOREIGN KEY (servicename) REFERENCES service(name),
151
  FOREIGN KEY (graphname) REFERENCES graph(name)
152
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
153

  
154

  
155

  
156

  
157
CREATE TABLE IF NOT EXISTS `servicehautniveau` (
158
  `servicename` varchar(100) NOT NULL,
159
  `servicename_dep` varchar(100) NOT NULL,
160
  PRIMARY KEY (`servicename`,`servicename_dep`),
161
  FOREIGN KEY (servicename) REFERENCES service(name),
162
  FOREIGN KEY (servicename_dep) REFERENCES service(name)
163
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
164

  
165

  
166

  
167

  
168

  
169

  
170
CREATE TABLE IF NOT EXISTS `servicetopo` (
171
  `servicename` varchar(100) NOT NULL,
172
  `function` varchar(50) NOT NULL,
173
  PRIMARY KEY (`servicename`),
174
  FOREIGN KEY (servicename) REFERENCES servicehautniveau(servicename)
175
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
176

  
development.ini
22 22
[app:main]
23 23
use = egg:vigiboard
24 24
full_stack = true
25
#lang = ru
25
#lang = zh_tw 
26 26
cache_dir = %(here)s/data
27 27
beaker.session.key = vigiboard
28 28
beaker.session.secret = somesecret
......
34 34
#beaker.session.data_dir = %(here)s/data/sessions
35 35

  
36 36
# DB
37
sqlalchemy.url=mysql://root:tandreja@localhost:3306/newdb
37
sqlalchemy.url=mysql://root:tandreja@localhost:3306/vigiboard
38 38
#echo shouldn't be used together with the logging module.
39 39
sqlalchemy.echo = false
40 40
sqlalchemy.echo_pool = false
production.ini
21 21
[app:main]
22 22
use = egg:vigiboard
23 23
full_stack = true
24
#lang = ru
24
#lang = fr
25 25
cache_dir = %(here)s/data
26 26
beaker.session.key = vigiboard
27 27
beaker.session.secret = somesecret
......
33 33
#beaker.session.data_dir = %(here)s/data/sessions
34 34

  
35 35
# DB
36
sqlalchemy.url=mysql://root:tandreja@localhost:3306/newdb
36
sqlalchemy.url=mysql://root:tandreja@localhost:3306/vigiboard
37 37
#echo shouldn't be used together with the logging module.
38 38
sqlalchemy.echo = false
39 39
sqlalchemy.echo_pool = false
test.ini
16 16
port = 5000
17 17

  
18 18
[app:main]
19
sqlalchemy.url = sqlite:///:memory:
19
sqlalchemy.url=mysql://root:tandreja@localhost:3306/vigiboard_test
20
#sqlalchemy.url = sqlite:///:memory:
20 21
use = config:development.ini
21 22

  
22 23
[app:main_without_authn]
23 24
use = main
24 25
skip_authentication = True
25 26

  
26
# Add additional test specific configuration options as necessary.
vigiboard/config/middleware.py
33 33
   
34 34
    """
35 35

  
36
    # Petit hack permettant d'importer la configuration de vigiboard
37

  
36 38
    for i in vigiboard_config :
37 39
	app_conf[i] = vigiboard_config[i]
38 40

  
vigiboard/config/vigiboard_config.py
1 1
# -*- coding: utf-8 -*-
2
"""Configuration for Vigiboard."""
2
# vim:set expandtab tabstop=4 shiftwidth=4:
3
"""Configuration de Vigiboard."""
3 4

  
4 5
vigiboard_config = {
5
        'vigiboard_links.nagios' : 'http://example1.com/%(idevent)d',
6
        'vigiboard_links.metrology' : 'http://example2.com/%(idevent)d',
7
        'vigiboard_links.security' : 'http://example3.com/%(idevent)d',
8
        'vigiboard_links.servicetype' : 'http://example4.com/%(idevent)d',
9
        'vigiboard_item_per_page' : '15',
6
    
7
    # Affichage, lien disponibles dans la fenêtre de détail d'un évènement
8
    'vigiboard_links.nagios' : 'http://example1.com/%(idevent)d',
9
    'vigiboard_links.metrology' : 'http://example2.com/%(idevent)d',
10
    'vigiboard_links.security' : 'http://example3.com/%(idevent)d',
11
    'vigiboard_links.servicetype' : 'http://example4.com/%(idevent)d',
12
    
13
    # Nombre d'évènments par pages
14
    'vigiboard_item_per_page' : '15',
15

  
16
    # Nom de base des tables de la base de données
10 17
	'vigiboard_bdd.basename' : ''
11 18
}
12 19

  
vigiboard/controllers/root.py
1 1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4: 
2 3
"""Main Controller"""
3 4

  
4
import tg
5
from tg import expose, flash, require, url, request, redirect, validate, tmpl_context
6

  
7
from tw.forms import validators 
8

  
9
from sets import Set
5
from tg import expose, flash, require, url, request, redirect
10 6

  
11 7
import pylons
12 8
from pylons.i18n import ugettext as _, lazy_ugettext as l_
13 9
from catwalk.tg2 import Catwalk
14 10
from repoze.what import predicates
15 11

  
16
from sqlalchemy import not_ , and_ , asc , desc, or_
17

  
18
from tw.jquery import JQueryUIDialog
19

  
20 12
from vigiboard.lib.base import BaseController
21
from vigiboard.model import DBSession, metadata
13
from vigiboard.model import DBSession 
22 14
from vigiboard.controllers.error import ErrorController
23 15
from vigiboard import model
24 16
from vigiboard.controllers.secure import SecureController
25 17

  
26
from vigiboard.model.vigiboard_bdd import *
27
from vigiboard.model.auth import Permission
28
from repoze.what.predicates import Any,not_anonymous
29

  
30
from vigiboard.widgets.edit_event import Edit_Event_Form , Search_Form , edit_event_status_options
18
from vigiboard.controllers.vigiboard_ctl import VigiboardController
31 19

  
32 20
__all__ = ['RootController']
33 21

  
34
def GetUserGroups():
35
	
36
	gr = DBSession.query(Groups.name).join(
37
	    ( GroupPermissions , Groups.name == GroupPermissions.groupname ),
38
	    ( Permission , Permission.permission_id == GroupPermissions.idpermission )
39
	    ).filter(Permission.permission_name.in_(request.environ.get('repoze.who.identity').get('permissions')))
40
	  
41
	lst_grp = Set([i.name for i in gr])
42
	lst_tmp = lst_grp
43
	  
44
	while len(lst_tmp) > 0:
45
		gr = DBSession.query(Groups.name).filter(Groups.parent.in_(lst_tmp))
46
		tmp = Set([])
47
		for i in gr :
48
			tmp.add(i.name)
49
			lst_grp.add(i.name)
50
		lst_tmp = tmp
51
	
52
	return lst_grp
53

  
54
def FormatEventsImgStatu (event):
55
	if event.active and event.status == 'AAClosed':
56
		return { 'src': url('/images/vigiboard/crossed.png') }
57
	elif event.status == 'Acknowledged' :
58
		return { 'src': url('/images/vigiboard/checked.png') }
59
	else:
60
		return None
61

  
62

  
63
def FormatEvents(events,first_row,last_row):
64
	ev = []
65
	i=0
66
	severity = { 0 : 'Minor' , 1 : 'Minor', 2 : 'Minor', 3 : 'Minor', 4 : 'Minor', 5 : 'Minor' , 6 : 'Major' , 7 : 'Critical' }
67
	class_tr = ['odd','even']
68
	class_ack = { 'Acknowledged' : 'Ack' , 'None' : '' , 'AAClosed' : 'Ack' }
69
	ids = []
70
	for event in events[first_row : last_row]:
71
		ids.append(event.idevent)
72
		if event.active :
73
			ev.append([
74
				event,
75
				{'class': class_tr[i%2]},
76
				{'class' : severity[event.severity] + class_ack[event.status]},
77
				{'class' : severity[event.severity] + class_ack[event.status] },
78
				{'src' : url('/images/vigiboard/%s2.png' % severity[event.severity].upper())},
79
				FormatEventsImgStatu(event)
80
				])
81
		else :
82
			ev.append([
83
				event,
84
				{'class': class_tr[i%2]},
85
				{'class' : severity[event.severity] + class_ack[event.status] },
86
				{'class' : 'Cleared' + class_ack[event.status] },
87
				{'src' : url('/images/vigiboard/%s2.png' % severity[event.severity].upper())},
88
				FormatEventsImgStatu(event)
89
				])
90

  
91
		i=i+1
92
	return ev,ids
93

  
94
def FormatHistory (idevents,hostname,servicename):
95
	history = DBSession.query(EventHistory).filter(EventHistory.idevent.in_(idevents)).order_by(desc(EventHistory.timestamp))
96
	severity = { 0 : 'None' , 1 : 'OK', 2 : 'Suppressed', 3 : 'Initial', 4 : 'Maintenance', 5 : 'Minor' , 6 : 'Major' , 7 : 'Critical' }
97
	hist = []
98
	i = 0
99
	class_tr = ['odd','even']
100
	for h in history :
101
		if h.value :
102
			hist.append([
103
				h.idhistory,
104
				hostname,
105
				servicename,
106
				h.timestamp,
107
				h.username,
108
				h.type_action,
109
				severity[min(int(h.value),7)],
110
				h.text,
111
				{'class' : class_tr[i%2]},
112
				{'class':severity[min(int(h.value),7)]}
113
			])
114
		else:
115
			hist.append([
116
				h.idhistory,
117
				hostname,
118
				servicename,
119
				h.timestamp,
120
				h.username,
121
				h.type_action,
122
				severity[0],
123
				h.text,
124
				{'class' : class_tr[i%2]},
125
				{'class':severity[0]}
126
			])	
127
		i = i+1
128
	
129
	return hist
130

  
131
def GenerateTmplContext():
132
	tmpl_context.edit_eventdialog = JQueryUIDialog(id='Edit_EventsDialog',autoOpen=False,title='Edit Event')
133
        tmpl_context.searchdialog = JQueryUIDialog(id='SearchDialog',autoOpen=False,title='Search Event')
134
        tmpl_context.historydialog = JQueryUIDialog(id='HistoryDialog',autoOpen=False,title='History')
135
        tmpl_context.edit_event_form = Edit_Event_Form('edit_event_form',action=url('/update_event'))
136
        tmpl_context.search_form = Search_Form('search_form',action=url('/vigiboard'))
137

  
138 22
class RootController(BaseController):
139 23
    """
140 24
    The root controller for the vigiboard application.
......
155 39
    
156 40
    error = ErrorController()
157 41

  
42
    vigiboard = VigiboardController()
43

  
158 44
    @expose('vigiboard.templates.index')
159 45
    def index(self):
160 46
        """Handle the front-page."""
......
214 100
        """
215 101
        flash(_('We hope to see you soon!'))
216 102
        redirect(came_from)
217

  
218
    @expose('vigiboard.templates.vigiboard')
219
    @require(Any(not_anonymous(),msg="You need to be authenticated"))
220
    def vigiboard(self,page='1',host=None,service=None,output=None,trouble_ticket=None):
221
	   try :
222
	   	page = int(page)
223
	   except :
224
		page = 1
225
	   if page < 1 :
226
		  page = 1
227
	   
228
	   events = DBSession.query(Events).join(
229
		( Host, Events.hostname == Host.name ),
230
		( Service, Events.servicename == Service.name ),
231
		( HostGroups , Host.name == HostGroups.hostname )
232
		).filter(HostGroups.groupname.in_(GetUserGroups())
233
		).filter(not_(and_(Events.active == False,Events.status == 'AAClosed'))
234
		).filter(Events.timestamp_active != None
235
		).filter(not_(Events.timestamp_active.like('0000-00-00 00:00:00'))
236
		)
237

  
238
	   if host :
239
		   events = events.filter(Events.hostname.like('%%%s%%' % host))
240
	   if service :
241
		   events = events.filter(Events.servicename.like('%%%s%%' % service))
242
	   if output :	
243
		   events = events.filter(Events.output.like('%%%s%%' % output))
244
	   if trouble_ticket :
245
		   events = events.filter(Events.trouble_ticket.like('%%%s%%' % trouble_ticket))
246

  
247
	   events= events.order_by(asc(Events.status)
248
		).order_by(desc(Events.active)
249
		).order_by(desc(Events.severity)
250
		).order_by(asc(Events.hostname)
251
		).order_by(desc(Events.timestamp))
252

  
253
	   total_row = events.count()
254
	   
255
	   item_per_page = int(tg.config['vigiboard_item_per_page'])
256

  
257
	   if total_row <= item_per_page * (page-1) :
258
		page = 1
259
	   id_first_row = item_per_page * (page-1)
260
	   id_last_row = min(id_first_row + item_per_page,total_row)
261
	   
262
	   GenerateTmplContext()
263
	   events , ids = FormatEvents(events,id_first_row,id_last_row)
264
	   return dict(
265
			   events=events,
266
			   id_first_row=id_first_row,
267
			   id_last_row=id_last_row,
268
			   total_row=total_row,
269
			   pages=range(1,(total_row/item_per_page) + 2),
270
			   page=page,
271
			   event_edit_status_options=edit_event_status_options,
272
			   history=[],
273
			   hist_error = False
274
		)
275
   	
276
  
277
    @expose('json')
278
    def vigiboard_HistoryDialog ( self , id ) :
279
	    events = DBSession.query(Events.severity,Events.idevent,Events.hostname,Events.servicename).filter(Events.idevent == id)[0]
280
	    initial_state = DBSession.query(EventHistory).filter(EventHistory.idevent == id).order_by(asc(EventHistory.timestamp)).order_by(asc(EventHistory.type_action))
281
	    if initial_state.count() > 0 :
282
		    initial_state = initial_state[0].value
283
	    else :
284
		    initial_state = 0
285
	    severity = { 0 : 'None' , 1 : 'OK', 2 : 'Suppressed', 3 : 'Initial', 4 : 'Maintenance', 5 : 'Minor' , 6 : 'Major' , 7 : 'Critical' }
286
	    return dict(
287
		initial_state=severity[int(initial_state)],
288
		current_state=severity[events.severity],
289
		idevent = events.idevent,
290
		host = events.hostname,
291
		service = events.servicename,
292
		nagios_link = tg.config['vigiboard_links.nagios'] % {'idevent':events.idevent},
293
		metrology_link = tg.config['vigiboard_links.metrology'] % {'idevent':events.idevent},
294
		security_link = tg.config['vigiboard_links.security'] % {'idevent':events.idevent},
295
		servicetype_link = tg.config['vigiboard_links.servicetype'] % {'idevent':events.idevent}
296
		)
297
	
298
    @expose('vigiboard.templates.vigiboard')
299
    @require(Any(not_anonymous(),msg="You need to be authenticated"))
300
    def vigiboard_event(self,idevent):
301
	   
302
	   events = DBSession.query(Events).join(
303
		( Host, Events.hostname == Host.name ),
304
		( Service, Events.servicename == Service.name ),
305
		( HostGroups , Host.name == HostGroups.hostname )
306
		).filter(HostGroups.groupname.in_(GetUserGroups())
307
	   	).filter(not_(and_(Events.active == False,Events.status == 'AAClosed'))
308
		).filter(Events.timestamp_active != None
309
		).filter(not_(Events.timestamp_active.like('0000-00-00 00:00:00'))
310
		).filter(Events.idevent == idevent)
311

  
312
	   if events.count() != 1 :
313
		flash(_('Error in DB'),'error')
314
		redirect('/vigiboard')
315
	   
316
   	   GenerateTmplContext()
317
	   events , ids = FormatEvents(events,0,1)
318
	   return dict(
319
			   events=events,
320
			   id_first_row=1,
321
			   id_last_row=1,
322
			   total_row=1,
323
			   pages=[1],
324
			   page=1,
325
			   event_edit_status_options=edit_event_status_options,
326
			   history=FormatHistory(ids,events[0][0].hostname,events[0][0].servicename),
327
			   hist_error = True
328
		)
329
 	
330
    @expose('vigiboard.templates.vigiboard')
331
    @require(Any(not_anonymous(),msg="You need to be authenticated"))
332
    def vigiboard_host_service(self,host,service):
333
	   
334
	   events = DBSession.query(Events).join(
335
		( Host, Events.hostname == Host.name ),
336
		( Service, Events.servicename == Service.name ),
337
		( HostGroups , Host.name == HostGroups.hostname )
338
		).filter(HostGroups.groupname.in_(GetUserGroups())
339
	   	).filter(not_(and_(Events.active == False,Events.status == 'AAClosed'))
340
		).filter(Events.timestamp_active != None
341
		).filter(not_(Events.timestamp_active.like('0000-00-00 00:00:00'))
342
		).filter(Events.hostname == host
343
		).filter(Events.servicename == service)
344

  
345
	   if events.count() == 0 :
346
		redirect('/vigiboard')
347
	   
348
	   GenerateTmplContext()
349

  
350
	   events , ids = FormatEvents(events,0,events.count())
351

  
352
	   return dict(
353
			   events=events,
354
			   id_first_row=1,
355
			   id_last_row=1,
356
			   total_row=1,
357
			   pages=[1],
358
			   page=1,
359
			   event_edit_status_options=edit_event_status_options,
360
			   history=FormatHistory(ids,host,service),
361
			   hist_error = True
362
		)
363

  
364
    def edit_event_form_errors (self,**argv):
365
	    flash(_(tmpl_context.form_errors),'error')
366
	    redirect(request.environ.get('HTTP_REFERER').split(request.environ.get('HTTP_HOST'))[1])
367

  
368
    @expose('vigiboard.templates.vigiboard_update')
369
    @validate(validators={
370
	    "id":validators.Regex(r'^[0-9]+(,[0-9]*)*,?$'),
371
	    "tt":validators.Regex(r'^[0-9]*$'),
372
	    "status":validators.OneOf(['None', 'Acknowledged', 'AAClosed'])
373
	    },error_handler=edit_event_form_errors)
374
    @require(Any(not_anonymous(),msg="You need to be authenticated"))
375
    def update_event(self,*argv,**krgv):
376
	   
377
           ids = krgv['id'].split(',')
378
	   
379
	   if len(ids) > 1 :
380
		   ids = ids[:-1]
381

  
382
	   events = DBSession.query(Events).join(
383
		( Host, Events.hostname == Host.name ),
384
		( Service, Events.servicename == Service.name ),
385
		( HostGroups , Host.name == HostGroups.hostname )
386
		).filter(HostGroups.groupname.in_(GetUserGroups())
387
		).filter(Events.idevent.in_(ids))
388
	   
389
	   if events.count() <= 0 :
390
		   flash(_('No access to this event'),'error')
391
		   redirect('/vigiboard')
392
	   
393
	   for event in events :
394
		   if krgv['tt'] != '' :
395
		   	event.trouble_ticket = krgv['tt']
396
		   	history = EventHistory(type_action="Ticket change",idevent=event.idevent,value='',text='',username=request.environ.get('repoze.who.identity').get('repoze.who.userid'))
397
		   	DBSession.add(history)	
398
	   
399
		   if events[0].status != krgv['status'] :
400
		   	event.status = krgv['status']
401
                   	history = EventHistory(type_action="Acknowlegement change state",idevent=event.idevent,value='',text='',username=request.environ.get('repoze.who.identity').get('repoze.who.userid'))
402
                   	DBSession.add(history)
403
	   
404
   	   flash(_('Updated successfully'))
405
	   redirect(request.environ.get('HTTP_REFERER').split(request.environ.get('HTTP_HOST'))[1])
vigiboard/controllers/vigiboard_ctl/__init__.py
1
from vigiboard.controllers.vigiboard_ctl.userutils import GetUserGroups
2
from vigiboard.controllers.vigiboard_ctl.vigiboardrequest import VigiboardRequest, VigiboardRequestPlugin
3
from vigiboard.controllers.vigiboard_ctl.vigiboard_ctl import VigiboardController
vigiboard/controllers/vigiboard_ctl/userutils.py
1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4:
3
"""Fonctions utiles en rapport avec l'utilisateur"""
4

  
5
from vigiboard.model import DBSession, Permission, Groups, GroupPermissions
6
from sets import Set
7
import tg 
8

  
9
def GetUserGroups():
10
    
11
    """
12
    Permet de connaître l'ensemble des groups d'hôte et de service de vigiboard
13
    auquel l'utilisateur appartient
14

  
15
    @return: Liste des groups
16
    """
17

  
18
    # Requête permettant d'obtenir les groups directs de l'utilisateur
19
    gr = DBSession.query(Groups.name).join(
20
        ( GroupPermissions , Groups.name == GroupPermissions.groupname ),
21
        ( Permission , Permission.permission_id == GroupPermissions.idpermission )
22
        ).filter(Permission.permission_name.in_(tg.request.environ.get('repoze.who.identity').get('permissions')))
23

  
24
    lst_grp = Set([i.name for i in gr])
25
    lst_tmp = lst_grp
26
    
27
    # On recherche maintenant les groupes indirect
28
    while len(lst_tmp) > 0:
29
        gr = DBSession.query(Groups.name).filter(Groups.parent.in_(lst_tmp))
30
        tmp = Set([])
31
        for i in gr :
32
            tmp.add(i.name)
33
            lst_grp.add(i.name)
34
        lst_tmp = tmp
35

  
36
    return lst_grp
vigiboard/controllers/vigiboard_ctl/vigiboard_ctl.py
1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4: 
3
"""Vigiboard Controller"""
4

  
5
import tg
6
from tg import expose, flash, require, url, request, redirect, validate, tmpl_context
7

  
8
from tw.forms import validators 
9

  
10
from pylons.i18n import ugettext as _, lazy_ugettext as l_
11

  
12
from sqlalchemy import sql, not_ , and_ , asc , desc, or_
13

  
14
from vigiboard.lib.base import TGController
15
from vigiboard.model import DBSession
16

  
17
from vigiboard.model.vigiboard_bdd import *
18
from vigiboard.controllers.vigiboard_ctl.userutils import GetUserGroups
19
from repoze.what.predicates import Any,not_anonymous
20

  
21
from vigiboard.widgets.edit_event import edit_event_status_options
22

  
23
from vigiboard.controllers.vigiboard_ctl import VigiboardRequest, VigiboardRequestPlugin
24

  
25
__all__ = ['VigiboardController']
26

  
27
class VigiboardController(TGController):
28

  
29
    @expose()
30
    def process_form_errors (self,*argv,**kwargv):
31

  
32
        """
33
        Gestion des erreurs de validation : On affiche les erreurs
34
        puis on redirige vers la dernière page accédée.
35
        """
36
        flash(tmpl_context.form_errors,'error')
37
        if request.environ.get('HTTP_REFERER') :
38
            redirect(request.environ.get('HTTP_REFERER').split(request.environ.get('HTTP_HOST'))[1])
39
        else :
40
            redirect('1')
41

  
42
    @validate(validators={'page':validators.Int(not_empty=False)},error_handler=process_form_errors)
43
    @expose('vigiboard.templates.vigiboard')
44
    @require(Any(not_anonymous(),msg="You need to be authenticated"))
45
    def default(self,page=1,host=None,service=None,output=None,trouble_ticket=None):
46
            
47
        """
48
        Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée (page 1 par
49
        defaut), la liste des évènements, rangé par ordre de prise en compte puis de sévérité.
50
        Pour accéder à cette page, l'utilisateur doit être authentifié.
51

  
52
        @param page: numéro de la page souhaité, commence à 1
53
        @param host: Si l'utilisateur souhaite sélectionner seulement certains
54
                     évènments suivant leur hôte, il peut placer une expression
55
                     ici en suivant la structure du LIKE en SQL
56
        @param service: Idem que host mais sur les services
57
        @param output: Idem que host mais sur le text explicatif
58
        @param trouble_ticket: Idem que host mais sur les tickets attribués
59
        """
60

  
61
        if page < 1 :
62
            page = 1
63

  
64
        ev = VigiboardRequest()
65

  
66
        # Création d'un plugin affichant le nombre de service impactés par un évènement
67
        class PluginSHN (VigiboardRequestPlugin):
68
            def show(self,rq):
69
                if rq[1] : 
70
                    return rq[2]
71
                else :
72
                    return None
73

  
74
        # Intégration de celui-ci à la requête en cours
75
        ev.AddPlugin(PluginSHN(
76
            table=[ServiceHautNiveau.servicename_dep,sql.func.count(Events.idevent)],
77
            outerjoin=[(ServiceHautNiveau,ServiceHautNiveau.servicename_dep == Events.servicename)],
78
            groupby=[(Events.idevent)],
79
            name=_(u'SHNs impacté'),
80
            style={'style':'text-align:center'}
81
           ))
82

  
83
        # Application des filtres si nécessaire
84
        if host :
85
            ev.AddFilter(Events.hostname.like('%%%s%%' % host))
86
        if service :
87
            ev.AddFilter(Events.servicename.like('%%%s%%' % service))
88
        if output :
89
            ev.AddFilter(Events.output.like('%%%s%%' % output))
90
        if trouble_ticket :
91
            ev.AddFilter(Events.trouble_ticket.like('%%%s%%' % trouble_ticket))
92

  
93
        # Calcul des éléments à afficher et du nombre de pages possibles
94
        total_row = ev.NumRows()
95
       
96
        item_per_page = int(tg.config['vigiboard_item_per_page'])
97

  
98
        if total_row <= item_per_page * (page-1) :
99
           page = 1
100
        id_first_row = item_per_page * (page-1)
101
        id_last_row = min(id_first_row + item_per_page,total_row)
102

  
103
        ev.FormatEvents(id_first_row,id_last_row)
104
        ev.GenerateTmplContext() 
105

  
106
        return dict(
107
               events=ev.events,
108
               id_first_row=id_first_row+1,
109
               id_last_row=id_last_row,
110
               total_row=total_row,
111
               pages=range(1,(total_row/item_per_page) + 2),
112
               page=page,
113
               event_edit_status_options=edit_event_status_options,
114
               history=[],
115
               hist_error = False
116
            )
117
       
118
    @validate(validators={'id':validators.Int(not_empty=True)},error_handler=process_form_errors)
119
    @expose('json')
120
    @require(Any(not_anonymous(),msg=_("You need to be authenticated")))
121
    def HistoryDialog ( self , id ) :
122
        
123
        """
124
        JSon renvoyant les éléments pour l'affichage de la fenêtre de dialogue
125
        contenant des liens internes et externes.
126
        Pour accéder à cette page, l'utilisateur doit être authentifié.
127

  
128
        @param id: identifiant de l'évènement
129
        """
130
        
131
        # Obtention de données sur l'évènement et sur son historique
132
        events = DBSession.query(Events.severity,Events.idevent,Events.hostname,Events.servicename
133
                        ).join(( HostGroups , Events.hostname == HostGroups.hostname )
134
                        ).filter(HostGroups.groupname.in_(GetUserGroups())
135
                        ).filter(Events.idevent == id)[0]
136

  
137
        initial_state = DBSession.query(EventHistory).filter(EventHistory.idevent == id).order_by(asc(EventHistory.timestamp)).order_by(asc(EventHistory.type_action))
138

  
139
        if initial_state.count() > 0 :
140
            initial_state = initial_state[0].value
141
        else :
142
            initial_state = 0
143
        
144
        severity = { 0 : _('None') , 1 : _('OK'), 2 : _('Suppressed'), 3 : _('Initial'), 4 : _('Maintenance'), 5 : _('Minor') , 6 : _('Major') , 7 : _('Critical') }
145
        
146
        return dict(
147
                initial_state=severity[int(initial_state)],
148
                current_state=severity[events.severity],
149
                idevent = events.idevent,
150
                host = events.hostname,
151
                service = events.servicename,
152
                nagios_link = tg.config['vigiboard_links.nagios'] % {'idevent':events.idevent},
153
                metrology_link = tg.config['vigiboard_links.metrology'] % {'idevent':events.idevent},
154
                security_link = tg.config['vigiboard_links.security'] % {'idevent':events.idevent},
155
                servicetype_link = tg.config['vigiboard_links.servicetype'] % {'idevent':events.idevent}
156
        )
157

  
158
    @validate(validators={'idevent':validators.Int(not_empty=True)},error_handler=process_form_errors)
159
    @expose('vigiboard.templates.vigiboard')
160
    @require(Any(not_anonymous(),msg=_("You need to be authenticated")))
161
    def event(self,idevent):
162
        """
163
        Affichage de l'historique d'un évènement.
164
        Pour accéder à cette page, l'utilisateur doit être authentifié.
165

  
166
        @param idevent: identifiant de l'évènement souhaité
167
        """
168

  
169
        ev = VigiboardRequest()
170
        ev.AddFilter(Events.idevent == idevent)
171
        
172
        # Vérification que l'évènement existe
173
        if ev.NumRows() != 1 :
174
            flash(_('Error in DB'),'error')
175
            redirect('1')
176
       
177
        ev.FormatEvents(0,1)
178
        ev.FormatHistory()
179
        ev.GenerateTmplContext() 
180

  
181
        return dict(
182
               events=ev.events,
183
               id_first_row=1,
184
               id_last_row=1,
185
               total_row=1,
186
               pages=[1],
187
               page=1,
188
               event_edit_status_options=edit_event_status_options,
189
               history=ev.hist,
190
               hist_error = True
191
            )
192
    @validate(validators={'host':validators.NotEmpty(),'service':validators.NotEmpty()},error_handler=process_form_errors)
193
    @expose('vigiboard.templates.vigiboard')
194
    @require(Any(not_anonymous(),msg=_("You need to be authenticated")))
195
    def host_service(self,host,service):
196
        
197
        """
198
        Affichage de l'historique de l'ensemble des évènements correspondant au
199
        host et service demandé.
200
        Pour accéder à cette page, l'utilisateur doit être authentifié.
201

  
202
        @param host: Nom de l'hôte souhaité.
203
        @param service: Nom du service souhaité
204
        """
205

  
206
        ev = VigiboardRequest()
207
        ev.AddFilter(Events.hostname == host,Events.servicename == service)
208
        
209
        # Vérification qu'il y a au moins 1 évènement qui correspond
210
        if ev.NumRows() == 0 :
211
            redirect('1')
212
       
213
        ev.FormatEvents(0,ev.NumRows())
214
        ev.FormatHistory()
215
        ev.GenerateTmplContext() 
216

  
217
        return dict(
218
               events=ev.events,
219
               id_first_row=1,
220
               id_last_row=1,
221
               total_row=1,
222
               pages=[1],
223
               page=1,
224
               event_edit_status_options=edit_event_status_options,
225
               history=ev.hist,
226
               hist_error = True
227
            )
228

  
229
    @expose('vigiboard.templates.vigiboard_update')
230
    @validate(validators={
231
        "id":validators.Regex(r'^[0-9]+(,[0-9]*)*,?$'),
232
        "trouble_ticket":validators.Regex(r'^[0-9]*$'),
233
        "status":validators.OneOf(['NoChange','None', 'Acknowledged', 'AAClosed'])
234
        },error_handler=process_form_errors)
235
    @require(Any(not_anonymous(),msg=_("You need to be authenticated")))
236
    def update(self,*argv,**krgv):
237
        
238
        """
239
        Mise à jour d'un évènement suivant les arguments passés.
240
        Cela peut être un changement de ticket ou un changement de statu.
241
        
242
        @param krgv['id']: Le ou les identifiants des évènements à traiter
243
        @param krgv['tt']: Nouveau numéro du ticket associé.
244
        @param krgv['status']: Nouveau status de/des évènements.
245
        """
246
        
247
        # Si l'utilisateur édite plusieurs évènements à la fois, il nous faut chacun
248
        # des identifiants
249

  
250
        ids = krgv['id'].split(',')
251
       
252
        if len(ids) > 1 :
253
            ids = ids[:-1]
254
        
255
        ev = VigiboardRequest()
256
        ev.AddFilter(Events.idevent.in_(ids))
257
        
258
        # Vérification que au moins un des identifiants existe et est éditable
259
        if ev.NumRows() <= 0 :
260
            flash(_('No access to this event'),'error')
261
            redirect('1')
262
        
263
        # Modification des évènements et création d'un historique pour chacun d'eux
264
        for event in ev.rq :
265
            if krgv['trouble_ticket'] != '' :
266
                event.trouble_ticket = krgv['trouble_ticket']
267
                history = EventHistory(type_action="Ticket change",idevent=event.idevent,value='',text='',username=request.environ.get('repoze.who.identity').get('repoze.who.userid'))
268
                DBSession.add(history)   
269
            if krgv['status'] != 'NoChange' :
270
                event.status = krgv['status']
271
                history = EventHistory(type_action="Acknowlegement change state",idevent=event.idevent,value='',text='',username=request.environ.get('repoze.who.identity').get('repoze.who.userid'))
272
                DBSession.add(history)
273
       
274
        flash(_('Updated successfully'))
275

  
276
        # Redirection vers la dernière page accédée
277
        redirect(request.environ.get('HTTP_REFERER').split(request.environ.get('HTTP_HOST'))[1])
278

  
vigiboard/controllers/vigiboard_ctl/vigiboardrequest.py
1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4: 
3
"""Gestion de la requête, des plugins et de l'affichage du Vigiboard"""
4

  
5
from vigiboard.model.vigiboard_bdd import *
6
from tg import request, tmpl_context, url
7
from vigiboard.model import DBSession
8
from sqlalchemy import not_ , and_ , asc , desc, or_, sql
9
from tw.jquery import JQueryUIDialog
10
from vigiboard.widgets.edit_event import Edit_Event_Form , Search_Form
11
from vigiboard.controllers.vigiboard_ctl.userutils import GetUserGroups
12
from pylons.i18n import ugettext as _, lazy_ugettext as l_
13

  
14
class VigiboardRequest():
15
    
16
    """
17
    Classe gérant la génération de la requête finale,
18
    le préformatage des évènements et celui des historiques
19
    """
20

  
21
    def __init__(self):
22

  
23
        """
24
        Initialisation de toutes les variables nécessaires: Liste des groupes de
25
        l'utilisateur, les classes à appliquer suivant la sévérité, les différentes
26
        étapes de la génération de la requête et la liste des plugins appliqués.
27
        """
28

  
29
        self.user_groups = GetUserGroups()
30
        self.bouton_severity = { 0 : 'Minor' , 1 : 'Minor', 2 : 'Minor', 3 : 'Minor', 4 : 'Minor', 5 : 'Minor' , 6 : 'Major' , 7 : 'Critical' }
31
        self.class_severity = { 0 : 'None' , 1 : 'None', 2 : 'None', 3 : 'None', 4 : 'None', 5 : 'Minor' , 6 : 'Major' , 7 : 'Critical' }
32
        self.severity = { 0 : _('None') , 1 : _('OK'), 2 : _('Suppressed'), 3 : _('Initial'), 4 : _('Maintenance'), 5 : _('Minor') , 6 : _('Major') , 7 : _('Critical') }
33

  
34
        self.class_ack = { 'Acknowledged' : 'Ack' , 'None' : '' , 'AAClosed' : 'Ack' }
35

  
36
        self.generaterq= False
37
        self.table = [Events]
38
        self.join = [( Host, Events.hostname == Host.name ),
39
                ( Service, Events.servicename == Service.name ),
40
                ( HostGroups , Host.name == HostGroups.hostname ),
41
                ( ServiceGroups , Service.name == ServiceGroups.servicename )]
42
        self.outerjoin = []
43
        self.filter = [HostGroups.groupname.in_(self.user_groups),
44
                        ServiceGroups.groupname.in_(self.user_groups),
45
                       not_(and_(Events.active == False,Events.status == 'AAClosed')),
46
                   Events.timestamp_active != None,
47
                   not_(Events.timestamp_active.like('0000-00-00 00:00:00'))]
48
        self.orderby = [asc(Events.status),
49
                                desc(Events.active),
50
                                desc(Events.severity),
51
                                asc(Events.hostname),
52
                                desc(Events.timestamp)]
53
        self.groupby = []
54
        self.plugin = []
55
        
56
    def AddPlugin(self,*argv):
57
        
58
        """
59
        Ajout d'un plugin, on lui prélève ses ajouts dans la requête
60
        """
61
        for i in argv :
62
            if isinstance(i,VigiboardRequestPlugin):
63
                self.AddTable(*i.table)
64
                self.AddJoin(*i.join)
65
                self.AddOuterJoin(*i.outerjoin)
66
                self.AddFilter(*i.filter)
67
                self.AddGroupBy(*i.groupby)
68
                self.AddOrderBy(*i.orderby)
69
                self.plugin.append(i)
70

  
71
    def GenerateRequest(self):
72
        
73
        """
74
        Génération de la requête avec l'ensemble des données stockées
75
        et la place dans la variable rq de la classe
76
        """
77
        
78
        # query et join ont besoin de referrence
79
        self.rq = DBSession.query(*self.table)
80
        self.rq = self.rq.join(*self.join)
81

  
82
        # le reste, non
83
        for i in self.outerjoin:
84
            self.rq = self.rq.outerjoin(i)
85
        for i in self.filter:
86
            self.rq = self.rq.filter(i)
87
        for i in self.groupby:
88
            self.rq = self.rq.group_by(i)
89
        for i in self.orderby:
90
            self.rq = self.rq.order_by(i)
91

  
92
    def NumRows(self):
93

  
94
        """
95
        Retourne le nombre de lignes de la requête.
96
        Si celle-ci n'est pas encore générée, on le fait.
97

  
98
        @return: Nombre de ligne
99
        """
100

  
101
        if not self.generaterq :
102
            self.GenerateRequest()
103
            self.generaterq = True
104
        return self.rq.count()
105

  
106
    def AddTable(self,*argv):
107
        
108
        """
109
        Ajoute une ou plusieurs tables/élément d'une table à
110
        la requête.
111

  
112
        @param argv: Liste des tables à ajouter
113
        """
114
        
115
        #On vérifi qu'il n'y a pas de doublons dans la liste des
116
        #tables finale
117
        
118
        for i in argv :
119
            for j in self.table:
120
                if str(i) == str(j):
121
                    break
122
            self.table.append(i)
123

  
124
    def AddJoin(self,*argv):
125
        
126
        """
127
        Ajoute une ou plusieurs jointures à
128
        la requête.
129

  
130
        @param argv: Liste des jointures à ajouter
131
        """
132
        
133
        #On vérifi qu'il n'y a pas de doublons dans la liste des
134
        #jointures finale
135
        
136
        for i in argv:
137
            for j in self.join:
138
                if str(i) == str(j):
139
                    break
140
            self.join.append(i)
141

  
142
    def AddOuterJoin(self,*argv):
143
        
144
        """
145
        Ajoute une ou plusieurs jointures externes à
146
        la requête.
147

  
148
        @param argv: Liste des jointures externes à ajouter
149
        """
150
        
151
        #On vérifi qu'il n'y a pas de doublons dans la liste des
152
        #jointures externes finale
153
        
154
        for i in argv:
155
            for j in self.outerjoin:
156
                if str(i) == str(j):
157
                    break
158
            self.outerjoin.append(i)    
159

  
160
    def AddFilter(self,*argv):
161

  
162
        """
163
        Ajoute un ou plusieurs filtres à la requête.
164

  
165
        @param argv: Liste des filtres à ajouter
166
        """
167
        
168
        #On vérifi qu'il n'y a pas de doublons dans la liste des
169
        #filtres finale
170
        
171
        for i in argv:
172
            for j in self.filter:
173
                if str(i) == str(j):
174
                    break
175
            self.filter.append(i)
176

  
177
    def AddGroupBy(self,*argv):
178

  
179
        """
180
        Ajoute un ou plusieurs groupements à la requête.
181

  
182
        @param argv: Liste des groupements à ajouter
183
        """
184
        
185
        #On vérifi qu'il n'y a pas de doublons dans la liste des
186
        #groupements finale
187
        
188
        for i in argv:
189
            for j in self.groupby:
190
                if str(i) == str(j):
191
                    break
192
            self.groupby.append(i)
193

  
194
    def AddOrderBy(self,*argv):
195

  
196
        """
197
        Ajoute un ou plusieurs orders à la requête.
198

  
199
        @param argv: Liste des ordres à ajouter
200
        """
201
        
202
        #On vérifi qu'il n'y a pas de doublons dans la liste des
203
        #ordres finale
204
        
205
        for i in argv:
206
            for j in self.orderby:
207
                if str(i) == str(j):
208
                    break
209
            self.orderby.append(i)
210

  
211
    def FormatEventsImgStatu (self,event):
212
        
213
        """
214
        Suivant l'état de l'évènement, retourne la classe à appliquer
215
        à l'image indiquant si l'évènement est pris en compte ou non.
216

  
217
        @param event: l'évènement à analyser
218

  
219
        @return: Dictionnaire représentant la classe à appliquer
220
        """
221

  
222
        if event.active and event.status == 'AAClosed':
223
            return { 'src': url('/images/vigiboard/crossed.png') }
224
        elif event.status == 'Acknowledged' :
225
            return { 'src': url('/images/vigiboard/checked.png') }
226
        else:
227
            return None
228

  
229
    def FormatEvents(self,first_row,last_row):
230
        
231
        """
232
        Formate la réponse de la requête et y applique les plugins
233
        pour un affichage simple du résultat par Genshi.
234
        On génère une liste de liste, chaqu'une étant la description de l'affichage pour un
235
        évènement donné.
236

  
237
        @param first_row: Indice de début de la liste des évènements
238
        @param last_row: Indice de fin de la liste des évènements
239
        """
240
        
241
        # Si la requête n'est pas générée, on le fait
242
        if not self.generaterq :
243
            self.GenerateRequest()
244
            self.generaterq = True
245

  
246
        # Liste des éléments pour la tête du tableau
247

  
248
        lst_title = ['',_('Date<br />[Duration]'),'#',_('Host'),_('Service Type<br />Service Name'),_('Output')]
249
        lst_title.extend([plug.name for plug in self.plugin])
250
        lst_title.extend(['[T T]',''])
251
        
252
        ev = [lst_title]
253
        i=0
254
        class_tr = ['odd','even']
255
        ids = []
256
        for rq in self.rq[first_row : last_row]:
257

  
258
            # Si il y a plus d'un élément dans la liste des tables, rq devient une liste plutôt
259
            # que d'être directement la table souhaité
260
            
261
            if isinstance(rq,Events) :
262
                event = rq
263
            else :
264
                event = rq[0]
265
            ids.append(event.idevent)
266
            # La liste pour l'évènement actuel comporte dans l'ordre :
267
            #   L'évènment en lui même
268
            #   La classe à appliquer sur la ligne (permet d'alterner les couleurs suivant les lignes)
269
            #   La classe pour la case comportant la flèche de détails
270
            #   La classe pour la date, l'occurrence et l'édition
271
            #   L'image a affiche pour la flèche de détails
272
            #   Une liste (une case par plugin) de ce que le plugin souhaite afficher en fonction de l'évènement
273
            if event.active :
274
                ev.append([
275
                    event,
276
                    {'class': class_tr[i%2]},
277
                    {'class' : self.bouton_severity[event.severity] + self.class_ack[event.status]},
278
                    {'class' : self.bouton_severity[event.severity] + self.class_ack[event.status] },
279
                    {'src' : '/images/vigiboard/%s2.png' % self.bouton_severity[event.severity].upper()},
280
                    self.FormatEventsImgStatu(event),
281
                    [[j.__show__(rq),j.style] for j in self.plugin]
282
                    ])
283
            else :
284
                ev.append([
285
                    event,
286
                    {'class': class_tr[i%2]},
287
                    {'class' : self.bouton_severity[event.severity] + self.class_ack[event.status] },
288
                    {'class' : 'Cleared' + self.class_ack[event.status] },
289
                    {'src' : '/images/vigiboard/%s2.png' % self.bouton_severity[event.severity].upper()},
290
                    self.FormatEventsImgStatu(event),
291
                    [[j.__show__(rq),j.style] for j in self.plugin]
292
                    ])
293
            i=i+1
294
        # On sauvegarde la liste précédemment créée puis rempli le TmplContext
295
        self.events = ev
296
        self.idevents = ids
297

  
298
    def FormatHistory (self):
299
        
300
        """
301
        Formate les historiques correspondant aux évènements sélectionnés
302
        pour un affichage simple du résultat par Genshi.
303
        On génère une liste de liste, chaqu'une étant la description de l'affichage pour un
304
        historique donné.
305
        """
306

  
307
        history = DBSession.query(EventHistory).filter(EventHistory.idevent.in_(self.idevents)).order_by(desc(EventHistory.timestamp)).order_by(desc(EventHistory.idhistory))
308
        if history.count() == 0:
309
            self.hist=[]
310
            return
311
        hist = []
312
        i = 0
313
        class_tr = ['odd','even']
314
        hostname = self.events[1][0].hostname
315
        servicename = self.events[1][0].servicename
316
        for h in history :
317
            # La liste pour l'historique actuel comporte dans l'ordre :
318
            #   Son identifiant
319
            #   Son nom d'hôte
320
            #   Son nom de service
321
            #   Le moment où il a été généré
322
            #   Qui l'a généré
323
            #   Le type d'action qui a été appliqué
324
            #   La sévérité de l'action si besoin est
325
            #   Le détail de l'action
326
            #   La classe à appliquer à la ligne (permet d'alterner les couleurs)
327
            #   La classe de la sévérité s'il y a
328
            if h.value :
329
                hist.append([
330
                    h.idhistory,
331
                    hostname,
332
                    servicename,
333
                    h.timestamp,
334
                    h.username,
335
                    h.type_action,
336
                    self.severity[min(int(h.value),7)],
337
                    h.text,
338
                    {'class' : class_tr[i%2]},
339
                    {'class':self.class_severity[min(int(h.value),7)]}
340
                ])
341
            else:
342
                hist.append([
343
                    h.idhistory,
344
                    hostname,
345
                    servicename,
346
                    h.timestamp,
347
                    h.username,
348
                    h.type_action,
349
                    self.severity[0],
350
                    h.text,
351
                    {'class' : class_tr[i%2]},
352
                    {'class':self.class_severity[0]}
353
                ])    
354
            i = i+1
355
        
356
        self.hist = hist
357

  
358
    def GenerateTmplContext(self):
359
        """
360
        Génère et peuple la variable tmpl_context avec les Dialogs et formulaires
361
        nécessaire au fonctionnement de Vigiboard
362
        """
363
        # Dialogue d'édition
364
        tmpl_context.edit_event_form = Edit_Event_Form('edit_event_form',action=url('update'))
365
        tmpl_context.edit_eventdialog = JQueryUIDialog(id='Edit_EventsDialog',autoOpen=False,title=_('Edit Event'))
366
    
367
        # Dialogue de recherche
368
        tmpl_context.search_form = Search_Form('search_form',action=url('1'))
369
        tmpl_context.searchdialog = JQueryUIDialog(id='SearchDialog',autoOpen=False,title=_('Search Event'))
370
        
371
        # Dialogue de détail d'un évènement
372
        tmpl_context.historydialog = JQueryUIDialog(id='HistoryDialog',autoOpen=False,title=_('History'))
373

  
374
class VigiboardRequestPlugin():
375

  
376
    """
377
    Classe dont les plugins utilisé dans VigiboardRequest doivent étendre.
378
    """
379
    
380
    def __init__ (self,table=[],join=[],outerjoin=[],filter=[],groupby=[],orderby=[],name='',style={}):
381
        self.table = table
382
        self.join = join
383
        self.outerjoin = outerjoin
384
        self.filter = filter
385
        self.orderby = orderby
386
        self.name = name
387
        self.groupby = groupby
388
        self.style = style
389

  
390
    def __show__ (self,event):
391
        
392
        """
393
        Permet d'éviter toutes erreurs d'affichage.
394
        C'est la fonction appelé par le formateur d'évènements.
395
        """
396

  
397
        s = self.show(event)
398
        
399
        if s != None :
400
            try:
401
                return str(s)
402
            except:
403
                return _('Error')
404
    
405
    def show(self, event):
406
        
407
        """
408
        Fonction qui affichera par défaut une chaîne de
409
        caractères vide dans la colonne attribué au plugin.
410

  
411
        En général, les plugins devront redéfinir cette fonction
412
        pour afficher ce qu'ils souhaitent.
413
        """
414
        
415
        return ''
vigiboard/i18n/en
1
en_US
vigiboard/i18n/en_US/LC_MESSAGES/vigiboard.po
1
# English (United States) translations for vigiboard.
2
# Copyright (C) 2009 ORGANIZATION
3
# This file is distributed under the same license as the vigiboard project.
4
# FIRST AUTHOR <EMAIL@ADDRESS>, 2009.
5
#
6
msgid ""
7
msgstr ""
8
"Project-Id-Version: vigiboard 0.1\n"
9
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10
"POT-Creation-Date: 2009-07-06 11:19+0200\n"
11
"PO-Revision-Date: 2009-07-06 11:44+0100\n"
12
"Last-Translator: Thomas ANDREJAK <thomas.andrejak@c-s.fr>\n"
13
"Language-Team: en_US <LL@li.org>\n"
14
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
15
"MIME-Version: 1.0\n"
16
"Content-Type: text/plain; charset=utf-8\n"
17
"Content-Transfer-Encoding: 8bit\n"
18
"Generated-By: Babel 0.9.4\n"
19

  
20
#: vigiboard/controllers/root.py:60
21
msgid "Only for managers"
22
msgstr ""
23

  
24
#: vigiboard/controllers/root.py:66
25
msgid "Only for the editor"
26
msgstr ""
27

  
28
#: vigiboard/controllers/root.py:76
29
msgid "Wrong credentials"
30
msgstr ""
31

  
32
#: vigiboard/controllers/root.py:91
33
#, python-format
34
msgid "Welcome back, %s!"
35
msgstr ""
36

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff