Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / controllers / root.py @ 8484b8bd

History | View | Annotate | Download (14.3 KB)

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

    
5
from tg import expose, validate, require, flash, \
6
    tmpl_context, request, config, session, redirect
7
from tw.forms import validators 
8
from pylons.i18n import ugettext as _
9
from pylons.controllers.util import abort
10
from sqlalchemy import asc
11
from vigiboard.model import DBSession
12
from vigiboard.model import Event, EventHistory, EventsAggregate, \
13
                            Host, HostGroup, \
14
                            User
15
from repoze.what.predicates import Any, not_anonymous
16
from vigiboard.widgets.edit_event import edit_event_status_options
17
from vigiboard.controllers.vigiboardrequest import VigiboardRequest
18
from vigiboard.controllers.vigiboard_controller import VigiboardRootController
19

    
20
__all__ = ['RootController']
21

    
22
class RootController(VigiboardRootController):
23
    
24
    """
25
    Le controller général de vigiboard
26
    """
27

    
28
    def process_form_errors(self, *argv, **kwargv):
29
        """
30
        Gestion des erreurs de validation : On affiche les erreurs
31
        puis on redirige vers la dernière page accédée.
32
        """
33
        for k in tmpl_context.form_errors:
34
            flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error')
35
        if request.environ.get('HTTP_REFERER') :
36
            redirect(request.environ.get('HTTP_REFERER'
37
                ).split(request.environ.get('HTTP_HOST'))[1])
38
        else :
39
            redirect('/')
40

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

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

    
62
        try:
63
            page = int(page)
64
        except ValueError:
65
            abort(404)
66

    
67
        if page < 1:
68
            page = 1
69

    
70
        events = VigiboardRequest()
71
        
72
        search = {'host':'', 'service':'', 'output':'', 'tt':''}
73
        # Application des filtres si nécessaire
74
        if host :
75
            search['host'] = host
76
            events.add_filter(Event.hostname.like('%%%s%%' % host))
77
        if service :
78
            search['service'] = service
79
            events.add_filter(Event.servicename.like('%%%s%%' % service))
80
        if output :
81
            search['output'] = output
82
            events.add_filter(Event.message.like('%%%s%%' % output))
83
        if trouble_ticket :
84
            search['tt'] = trouble_ticket
85
            events.add_filter(EventsAggregate.trouble_ticket.like(
86
                '%%%s%%' % trouble_ticket))
87

    
88
        # Calcul des éléments à afficher et du nombre de pages possibles
89
        total_rows = events.num_rows()
90
       
91
        item_per_page = int(config['vigiboard_item_per_page'])
92

    
93
        if total_rows <= item_per_page * (page-1) :
94
            page = 1
95
        id_first_row = item_per_page * (page-1)
96
        id_last_row = min(id_first_row + item_per_page, total_rows)
97

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

127
        @param id: identifiant de l'évènement
128
        """
129

    
130
        # Obtention de données sur l'évènement et sur son historique
131
        username = request.environ.get('repoze.who.identity'
132
                    ).get('repoze.who.userid')
133
        user = User.by_user_name(username)
134

    
135
        event = DBSession.query(
136
                        EventsAggregate.severity,
137
                        Event.hostname,
138
                        Event.servicename,
139
                 ).join(
140
                    (Event, EventsAggregate.idcause == Event.idevent),
141
                    (HostGroup, Event.hostname == HostGroup.hostname),
142
                 ).filter(HostGroup.groupname.in_(user.groups)
143
                 ).filter(EventsAggregate.idcause == idevent).one()
144

    
145
        initial_state = DBSession.query(
146
                    EventHistory,
147
                 ).filter(EventHistory.idevent == idevent
148
                 ).order_by(asc(EventHistory.timestamp)
149
                 ).order_by(asc(EventHistory.type_action))
150

    
151
        if initial_state.count() > 0 :
152
            for i in initial_state:
153
                if i.value != '' and i.value is not None:
154
                    initial_state = i.value
155
                    break
156
        else :
157
            initial_state = 0
158

    
159
        severity = { 0: _('None'), 1: _('OK'), 2: _('Suppressed'),
160
                3: _('Initial'), 4: _('Maintenance'), 5: _('Minor'),
161
                6: _('Major'), 7: _('Critical') }
162
        eventdetails = {}
163
        for edname, edlink in \
164
                config['vigiboard_links.eventdetails'].iteritems():
165

    
166
            eventdetails[edname] = edlink[1] % {
167
                    'idevent': idevent,
168
                    'host': event.hostname,
169
                    'service': event.servicename
170
                    }
171

    
172
        return dict(
173
                initial_state = severity[int(initial_state)],
174
                current_state = severity[event.severity],
175
                idevent = idevent,
176
                host = event.hostname,
177
                service = event.servicename,
178
                eventdetails = eventdetails
179
            )
180

    
181
    @validate(validators={'idevent':validators.String(not_empty=True)},
182
            error_handler=process_form_errors)
183
    @expose('vigiboard.templates.vigiboard')
184
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
185
    def event(self, idevent):
186
        """
187
        Affichage de l'historique d'un évènement.
188
        Pour accéder à cette page, l'utilisateur doit être authentifié.
189

190
        @param idevent: identifiant de l'évènement souhaité
191
        """
192

    
193
        events = VigiboardRequest()
194
        events.add_filter(EventsAggregate.idcause == idevent)
195
        
196
        # Vérification que l'évènement existe
197
        if events.num_rows() != 1 :
198
            flash(_('Error in DB'), 'error')
199
            redirect('/')
200
       
201
        events.format_events(0, 1)
202
        events.format_history()
203
        events.generate_tmpl_context() 
204

    
205
        return dict(
206
                    events = events.events,
207
                    rows_info = {
208
                        'id_first_row': 1,
209
                        'id_last_row': 1,
210
                        'total_rows': 1,
211
                    },
212
                    pages = [1],
213
                    page = 1,
214
                    event_edit_status_options = edit_event_status_options,
215
                    history = events.hist,
216
                    hist_error = True,
217
                    plugin_context = events.context_fct,
218
                    search = {
219
                        'host': None,
220
                        'service': None,
221
                        'output': None,
222
                        'tt': None
223
                    }
224
                )
225

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

237
        @param host: Nom de l'hôte souhaité.
238
        @param service: Nom du service souhaité
239
        """
240

    
241
        events = VigiboardRequest()
242
        events.add_filter(Event.hostname == host,
243
                Event.servicename == service)
244
        del events.filter[2]
245

    
246
        # Vérification qu'il y a au moins 1 évènement qui correspond
247
        if events.num_rows() == 0 :
248
            redirect('/')
249
       
250
        events.format_events(0, events.num_rows())
251
        events.format_history()
252
        events.generate_tmpl_context() 
253
        return dict(
254
                    events = events.events,
255
                    rows_info = {
256
                        'id_first_row': 1,
257
                        'id_last_row': 1,
258
                        'total_rows': 1,
259
                    },
260
                    pages = [1],
261
                    page = 1,
262
                    event_edit_status_options = edit_event_status_options,
263
                    history = events.hist,
264
                    hist_error = True,
265
                    plugin_context = events.context_fct,
266
                    search = {
267
                        'host': None,
268
                        'service': None,
269
                        'output': None,
270
                        'tt': None
271
                    }
272
                )
273

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

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

    
313
        for req in events.req :
314
            if isinstance(req, EventsAggregate):
315
                event = req
316
            else:
317
                event = req[0]
318

    
319
            if krgv['trouble_ticket'] != '' :
320
                event.trouble_ticket = krgv['trouble_ticket']
321
                history = EventHistory(
322
                        type_action="Ticket change",
323
                        idevent=event.idcause,
324
                        value='',
325
                        text='',
326
                        username=username,
327
                    )
328
                DBSession.add(history)   
329

    
330
            if krgv['status'] != 'NoChange' :
331
                event.status = krgv['status']
332
                history = EventHistory(
333
                        type_action="Acknowlegement change state",
334
                        idevent=event.idcause,
335
                        value='',
336
                        text='',
337
                        username=username,
338
                    )
339
                DBSession.add(history)
340
       
341
        flash(_('Updated successfully'))
342
        # Redirection vers la dernière page accédée
343
        redirect(request.environ.get('HTTP_REFERER').split(
344
                    request.environ.get('HTTP_HOST') + \
345
                    config['base_url_filter.base_url'])[1])
346

    
347

    
348
    @validate(validators={"plugin_name":validators.OneOf(
349
        [i for [i,j] in config.get('vigiboard_plugins', [])])},
350
                error_handler = process_form_errors)
351
    @expose('json')
352
    def get_plugin_value(self, plugin_name, *arg, **krgv):
353
        """
354
        Permet aux plugins de pouvoir récupérer des valeurs Json
355
        """
356
        plugins = config['vigiboard_plugins']
357
        if plugins is None:
358
            return
359

    
360
        plugin = [i for i in plugins if i[0] == plugin_name][0]
361
        try:
362
            mypac = __import__(
363
                'vigiboard.controllers.vigiboard_plugin.' + plugin[0],
364
                globals(), locals(), [plugin[1]], -1)
365
            plug = getattr(mypac, plugin[1])()
366
            return plug.controller(*arg, **krgv)
367
        except:
368
            raise
369
    
370
#    @validate(validators= {"fontsize": validators.Int()},
371
#                    error_handler = process_form_errors)
372
    @expose('json')
373
    def set_fontsize(self, fontsize):
374
        """
375
        Save font size
376
        """
377
        session['fontsize'] = fontsize
378
        session.save()
379
        return dict(ret= 'ok')
380

    
381
    @validate(validators= {"refresh": validators.Int()},
382
            error_handler = process_form_errors)
383
    @expose('json')
384
    def set_refresh(self, refresh):
385
        """
386
        Save refresh time
387
        """
388
        session['refresh'] = refresh
389
        session.save()
390
        return dict(ret= 'ok')