Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / controllers / vigiboard_ctl / vigiboard_ctl.py @ 35cea70e

History | View | Annotate | Download (12.2 KB)

1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4: 
3
"""Vigiboard Controller"""
4

    
5
import tg
6

    
7
from tg import expose, flash, require, request, redirect, \
8
                validate, tmpl_context
9

    
10
from tw.forms import validators 
11

    
12
from pylons.i18n import ugettext as _
13

    
14
from sqlalchemy import sql, asc
15

    
16
from vigiboard.lib.base import TGController
17
from vigiboard.model import DBSession
18

    
19
from vigiboard.model.vigiboard_bdd import ServiceHautNiveau, HostGroups, \
20
        Events, EventHistory
21

    
22
from repoze.what.predicates import Any, not_anonymous
23

    
24
from vigiboard.widgets.edit_event import edit_event_status_options
25

    
26
from vigiboard.controllers.vigiboard_ctl.userutils import get_user_groups
27
from vigiboard.controllers.vigiboard_ctl.vigiboardrequest import \
28
        VigiboardRequest, VigiboardRequestPlugin
29

    
30
__all__ = ['VigiboardController']
31

    
32
class VigiboardController(TGController):
33
    
34
    """
35
    Le controller général de vigiboard
36
    """
37

    
38
    @expose()
39
    def process_form_errors (self, *argv, **kwargv):
40

    
41
        """
42
        Gestion des erreurs de validation : On affiche les erreurs
43
        puis on redirige vers la dernière page accédée.
44
        """
45
        flash(tmpl_context.form_errors, 'error')
46
        if request.environ.get('HTTP_REFERER') :
47
            redirect(request.environ.get('HTTP_REFERER'
48
                ).split(request.environ.get('HTTP_HOST'))[1])
49
        else :
50
            redirect('/vigiboard')
51

    
52
    @validate(validators={'page':validators.Int(not_empty=False)},
53
            error_handler=process_form_errors)
54
    @expose('vigiboard.templates.vigiboard')
55
    @require(Any(not_anonymous(), msg="You need to be authenticated"))
56
    def default(self, page = 1, host = None, service = None, output = None,
57
            trouble_ticket=None):
58
            
59
        """
60
        Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée (page 1 par
61
        defaut), la liste des évènements, rangé par ordre de prise en compte puis de sévérité.
62
        Pour accéder à cette page, l'utilisateur doit être authentifié.
63

64
        @param page: numéro de la page souhaité, commence à 1
65
        @param host: Si l'utilisateur souhaite sélectionner seulement certains
66
                     évènments suivant leur hôte, il peut placer une expression
67
                     ici en suivant la structure du LIKE en SQL
68
        @param service: Idem que host mais sur les services
69
        @param output: Idem que host mais sur le text explicatif
70
        @param trouble_ticket: Idem que host mais sur les tickets attribués
71
        """
72

    
73
        if page < 1 :
74
            page = 1
75

    
76
        events = VigiboardRequest()
77

    
78
        # Création d'un plugin affichant le nombre de service impactés
79
        # par un évènement
80

    
81
        class PluginSHN (VigiboardRequestPlugin):
82
            
83
            """
84
            Plugin permettant de rajouter le nombre de SHNs impactés à
85
            l'affichage
86
            """
87

    
88
            def show(self, req):
89
                """Fonction d'affichage"""
90
                if req[1] : 
91
                    return req[2]
92
                else :
93
                    return None
94

    
95
        # Intégration de celui-ci à la requête en cours
96

    
97
        events.add_plugin(PluginSHN(
98
            table = [ServiceHautNiveau.servicename_dep,
99
                sql.func.count(Events.idevent)],
100
            outerjoin = [(ServiceHautNiveau,
101
                ServiceHautNiveau.servicename_dep == Events.servicename)],
102
            groupby = [(Events.idevent)],
103
            name = _(u'SHNs impacté'),
104
            style = {'style':'text-align:center'}
105
           ))
106

    
107
        # Application des filtres si nécessaire
108
        if host :
109
            events.add_filter(Events.hostname.like('%%%s%%' % host))
110
        if service :
111
            events.add_filter(Events.servicename.like('%%%s%%' % service))
112
        if output :
113
            events.add_filter(Events.output.like('%%%s%%' % output))
114
        if trouble_ticket :
115
            events.add_filter(Events.trouble_ticket.like(
116
                '%%%s%%' % trouble_ticket))
117

    
118
        # Calcul des éléments à afficher et du nombre de pages possibles
119
        total_row = events.num_rows()
120
       
121
        item_per_page = int(tg.config['vigiboard_item_per_page'])
122

    
123
        if total_row <= item_per_page * (page-1) :
124
            page = 1
125
        id_first_row = item_per_page * (page-1)
126
        id_last_row = min(id_first_row + item_per_page, total_row)
127

    
128
        events.format_events(id_first_row, id_last_row)
129
        events.generate_tmpl_context() 
130

    
131
        return dict(
132
               events = events.events,
133
               id_first_row = id_first_row + 1,
134
               id_last_row = id_last_row,
135
               total_row = total_row,
136
               pages = range(1, (total_row / item_per_page) + 2),
137
               page = page,
138
               event_edit_status_options = edit_event_status_options,
139
               history = [],
140
               hist_error = False
141
            )
142
       
143
    @validate(validators={'idevent':validators.Int(not_empty=True)},
144
            error_handler=process_form_errors)
145
    @expose('json')
146
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
147
    def history_dialog (self, idevent) :
148
        
149
        """
150
        JSon renvoyant les éléments pour l'affichage de la fenêtre de dialogue
151
        contenant des liens internes et externes.
152
        Pour accéder à cette page, l'utilisateur doit être authentifié.
153

154
        @param id: identifiant de l'évènement
155
        """
156
        
157
        # Obtention de données sur l'évènement et sur son historique
158
        events = DBSession.query(Events.severity, Events.idevent,
159
                        Events.hostname, Events.servicename
160
                 ).join(( HostGroups , Events.hostname == HostGroups.hostname )
161
                 ).filter(HostGroups.groupname.in_(get_user_groups())
162
                 ).filter(Events.idevent == idevent)[0]
163

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

    
169
        if initial_state.count() > 0 :
170
            initial_state = initial_state[0].value
171
        else :
172
            initial_state = 0
173
        
174
        severity = { 0: _('None'), 1: _('OK'), 2: _('Suppressed'),
175
                3: _('Initial'), 4: _('Maintenance'), 5: _('Minor'),
176
                6: _('Major'), 7: _('Critical') }
177
        
178
        return dict(
179
                initial_state = severity[int(initial_state)],
180
                current_state = severity[events.severity],
181
                idevent = events.idevent,
182
                host = events.hostname,
183
                service = events.servicename,
184
                nagios_link = tg.config['vigiboard_links.nagios'] % \
185
                        {'idevent': events.idevent},
186
                metrology_link = tg.config['vigiboard_links.metrology'] % \
187
                        {'idevent': events.idevent},
188
                security_link = tg.config['vigiboard_links.security'] % \
189
                        {'idevent': events.idevent},
190
                servicetype_link = tg.config['vigiboard_links.servicetype'] % \
191
                        {'idevent': events.idevent}
192
            )
193

    
194
    @validate(validators={'idevent':validators.Int(not_empty=True)},
195
            error_handler=process_form_errors)
196
    @expose('vigiboard.templates.vigiboard')
197
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
198
    def event(self, idevent):
199
        """
200
        Affichage de l'historique d'un évènement.
201
        Pour accéder à cette page, l'utilisateur doit être authentifié.
202

203
        @param idevent: identifiant de l'évènement souhaité
204
        """
205

    
206
        events = VigiboardRequest()
207
        events.add_filter(Events.idevent == idevent)
208
        
209
        # Vérification que l'évènement existe
210
        if events.num_rows() != 1 :
211
            flash(_('Error in DB'), 'error')
212
            redirect('/vigiboard')
213
       
214
        events.format_events(0, 1)
215
        events.format_history()
216
        events.generate_tmpl_context() 
217

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

    
230
    @validate(validators={'host':validators.NotEmpty(),
231
        'service':validators.NotEmpty()}, error_handler=process_form_errors)
232
    @expose('vigiboard.templates.vigiboard')
233
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
234
    def host_service(self, host, service):
235
        
236
        """
237
        Affichage de l'historique de l'ensemble des évènements correspondant au
238
        host et service demandé.
239
        Pour accéder à cette page, l'utilisateur doit être authentifié.
240

241
        @param host: Nom de l'hôte souhaité.
242
        @param service: Nom du service souhaité
243
        """
244

    
245
        events = VigiboardRequest()
246
        events.add_filter(Events.hostname == host,
247
                Events.servicename == service)
248
        
249
        # Vérification qu'il y a au moins 1 évènement qui correspond
250
        if events.num_rows() == 0 :
251
            redirect('/vigiboard')
252
       
253
        events.format_events(0, events.num_rows())
254
        events.format_history()
255
        events.generate_tmpl_context() 
256

    
257
        return dict(
258
               events = events.events,
259
               id_first_row = 1,
260
               id_last_row = 1,
261
               total_row = 1,
262
               pages = [1],
263
               page = 1,
264
               event_edit_status_options = edit_event_status_options,
265
               history = events.hist,
266
               hist_error = True
267
            )
268

    
269
    @expose('vigiboard.templates.vigiboard_update')
270
    @validate(validators={
271
        "id":validators.Regex(r'^[0-9]+(,[0-9]*)*,?$'),
272
        "trouble_ticket":validators.Regex(r'^[0-9]*$'),
273
        "status":validators.OneOf(['NoChange', 'None', 'Acknowledged',
274
                'AAClosed'])
275
        }, error_handler=process_form_errors)
276
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
277
    def update(self,**krgv):
278
        
279
        """
280
        Mise à jour d'un évènement suivant les arguments passés.
281
        Cela peut être un changement de ticket ou un changement de statu.
282
        
283
        @param krgv['id']: Le ou les identifiants des évènements à traiter
284
        @param krgv['tt']: Nouveau numéro du ticket associé.
285
        @param krgv['status']: Nouveau status de/des évènements.
286
        """
287
        
288
        # Si l'utilisateur édite plusieurs évènements à la fois,
289
        # il nous faut chacun des identifiants
290

    
291
        ids = krgv['id'].split(',')
292
       
293
        if len(ids) > 1 :
294
            ids = ids[:-1]
295
        
296
        events = VigiboardRequest()
297
        events.add_filter(Events.idevent.in_(ids))
298
        
299
        # Vérification que au moins un des identifiants existe et est éditable
300
        if events.num_rows() <= 0 :
301
            flash(_('No access to this event'), 'error')
302
            redirect('/vigiboard')
303
        
304
        # Modification des évènements et création d'un historique
305
        # pour chacun d'eux
306
        
307
        username = request.environ.get('repoze.who.identity'
308
                ).get('repoze.who.userid')
309

    
310
        for event in events.req :
311
            if krgv['trouble_ticket'] != '' :
312
                event.trouble_ticket = krgv['trouble_ticket']
313
                history = EventHistory(type_action = "Ticket change",
314
                    idevent = event.idevent, value = '', text = '',
315
                    username = username)
316
                DBSession.add(history)   
317
            if krgv['status'] != 'NoChange' :
318
                event.status = krgv['status']
319
                history = EventHistory(
320
                        type_action = "Acknowlegement change state",
321
                        idevent = event.idevent, value = '', text = '',
322
                        username = username)
323
                DBSession.add(history)
324
       
325
        flash(_('Updated successfully'))
326

    
327
        # Redirection vers la dernière page accédée
328
        redirect(request.environ.get('HTTP_REFERER').split(
329
            request.environ.get('HTTP_HOST'))[1])
330