Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / controllers / root.py @ 0f56fff9

History | View | Annotate | Download (13.4 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 Events, EventHistory, Host, User, HostGroups
13
from repoze.what.predicates import Any, not_anonymous
14
from vigiboard.widgets.edit_event import edit_event_status_options
15
from vigiboard.controllers.vigiboardrequest import VigiboardRequest
16
from vigiboard.controllers.vigiboard_controller import VigiboardRootController
17

    
18
__all__ = ['RootController']
19

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

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

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

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

    
60
        try:
61
            page = int(page)
62
        except ValueError:
63
            abort(404)
64

    
65
        if page < 1:
66
            page = 1
67

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

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

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

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

125
        @param id: identifiant de l'évènement
126
        """
127

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

    
133
        events = DBSession.query(Events.severity, Events.idevent,
134
                        Events.hostname, Events.servicename
135
                 ).join(( HostGroups , Events.hostname == HostGroups.hostname )
136
                 ).filter(HostGroups.groupname.in_(user.groups)
137
                 ).filter(Events.idevent == idevent)[0]
138
        initial_state = DBSession.query(EventHistory
139
                 ).filter(EventHistory.idevent == idevent
140
                 ).order_by(asc(EventHistory.timestamp)
141
                 ).order_by(asc(EventHistory.type_action))
142
        if initial_state.count() > 0 :
143
            for i in initial_state:
144
                if i.value != '' and i.value is not None:
145
                    initial_state = i.value
146
                    break
147
        else :
148
            initial_state = 0
149

    
150
        severity = { 0: _('None'), 1: _('OK'), 2: _('Suppressed'),
151
                3: _('Initial'), 4: _('Maintenance'), 5: _('Minor'),
152
                6: _('Major'), 7: _('Critical') }
153
        eventdetails = {}
154
        for edname, edlink in \
155
                config['vigiboard_links.eventdetails'].iteritems():
156

    
157
            eventdetails[edname] = edlink[1] % {
158
                    'idevent': events.idevent,
159
                    'host': events.hostname,
160
                    'service': events.servicename
161
                    }
162

    
163
        return dict(
164
                initial_state = severity[int(initial_state)],
165
                current_state = severity[events.severity],
166
                idevent = events.idevent,
167
                host = events.hostname,
168
                service = events.servicename,
169
                eventdetails = eventdetails
170
            )
171

    
172
    @validate(validators={'idevent':validators.Int(not_empty=True)},
173
            error_handler=process_form_errors)
174
    @expose('vigiboard.templates.vigiboard')
175
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
176
    def event(self, idevent):
177
        """
178
        Affichage de l'historique d'un évènement.
179
        Pour accéder à cette page, l'utilisateur doit être authentifié.
180

181
        @param idevent: identifiant de l'évènement souhaité
182
        """
183

    
184
        events = VigiboardRequest()
185
        events.add_filter(Events.idevent == idevent)
186
        
187
        # Vérification que l'évènement existe
188
        if events.num_rows() != 1 :
189
            flash(_('Error in DB'), 'error')
190
            redirect('/')
191
       
192
        events.format_events(0, 1)
193
        events.format_history()
194
        events.generate_tmpl_context() 
195

    
196
        return dict(
197
               events = events.events,
198
               id_first_row = 1,
199
               id_last_row = 1,
200
               total_row = 1,
201
               pages = [1],
202
               page = 1,
203
               event_edit_status_options = edit_event_status_options,
204
               history = events.hist,
205
               hist_error = True,
206
               plugin_context = events.context_fct,
207
               search = {'host':None,'service':None,'output':None,'tt':None}
208
            )
209

    
210
    @validate(validators={'host':validators.NotEmpty(),
211
        'service':validators.NotEmpty()}, error_handler=process_form_errors)
212
    @expose('vigiboard.templates.vigiboard')
213
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
214
    def host_service(self, host, service):
215
        
216
        """
217
        Affichage de l'historique de l'ensemble des évènements correspondant au
218
        host et service demandé.
219
        Pour accéder à cette page, l'utilisateur doit être authentifié.
220

221
        @param host: Nom de l'hôte souhaité.
222
        @param service: Nom du service souhaité
223
        """
224

    
225
        events = VigiboardRequest()
226
        events.add_filter(Events.hostname == host,
227
                Events.servicename == service)
228
        del events.filter[2]
229

    
230
        # Vérification qu'il y a au moins 1 évènement qui correspond
231
        if events.num_rows() == 0 :
232
            redirect('/')
233
       
234
        events.format_events(0, events.num_rows())
235
        events.format_history()
236
        events.generate_tmpl_context() 
237
        return dict(
238
               events = events.events,
239
               id_first_row = 1,
240
               id_last_row = 1,
241
               total_row = 1,
242
               pages = [1],
243
               page = 1,
244
               event_edit_status_options = edit_event_status_options,
245
               history = events.hist,
246
               hist_error = True,
247
               plugin_context = events.context_fct,
248
               search = {'host':None,'service':None,'output':None,'tt':None}
249
            )
250

    
251
    @validate(validators={
252
        "id":validators.Regex(r'^[0-9]+(,[0-9]*)*,?$'),
253
        "trouble_ticket":validators.Regex(r'^[0-9]*$'),
254
        "status":validators.OneOf(['NoChange', 'None', 'Acknowledged',
255
                'AAClosed'])
256
        }, error_handler=process_form_errors)
257
    @require(Any(not_anonymous(), msg=_("You need to be authenticated")))
258
    def update(self,**krgv):
259
        
260
        """
261
        Mise à jour d'un évènement suivant les arguments passés.
262
        Cela peut être un changement de ticket ou un changement de statu.
263
        
264
        @param krgv['id']: Le ou les identifiants des évènements à traiter
265
        @param krgv['tt']: Nouveau numéro du ticket associé.
266
        @param krgv['status']: Nouveau status de/des évènements.
267
        """
268
        
269
        # Si l'utilisateur édite plusieurs évènements à la fois,
270
        # il nous faut chacun des identifiants
271

    
272
        ids = krgv['id'].split(',')
273
       
274
        if len(ids) > 1 :
275
            ids = ids[:-1]
276
        
277
        events = VigiboardRequest()
278
        events.add_filter(Events.idevent.in_(ids))
279
        
280
        # Vérification que au moins un des identifiants existe et est éditable
281
        if events.num_rows() <= 0 :
282
            flash(_('No access to this event'), 'error')
283
            redirect('/')
284
        
285
        # Modification des évènements et création d'un historique
286
        # pour chacun d'eux
287
        
288
        username = request.environ.get('repoze.who.identity'
289
                ).get('repoze.who.userid')
290

    
291
        for req in events.req :
292
            if isinstance(req, Events):
293
                event = req
294
            else:
295
                event = req[0]
296
            if krgv['trouble_ticket'] != '' :
297
                event.trouble_ticket = krgv['trouble_ticket']
298
                history = EventHistory(type_action = "Ticket change",
299
                    idevent = event.idevent, value = '', text = '',
300
                    username = username)
301
                DBSession.add(history)   
302
            if krgv['status'] != 'NoChange' :
303
                event.status = krgv['status']
304
                history = EventHistory(
305
                        type_action = "Acknowlegement change state",
306
                        idevent = event.idevent, value = '', text = '',
307
                        username = username)
308
                DBSession.add(history)
309
       
310
        flash(_('Updated successfully'))
311
        # Redirection vers la dernière page accédée
312
        redirect(request.environ.get('HTTP_REFERER').split(
313
                    request.environ.get('HTTP_HOST') + \
314
                    config['base_url_filter.base_url'])[1])
315

    
316

    
317
    @validate(validators={"plugin_name":validators.OneOf(
318
        [i for [i,j] in config.get('vigiboard_plugins', [])])},
319
                error_handler = process_form_errors)
320
    @expose('json')
321
    def get_plugin_value(self, plugin_name, *arg, **krgv):
322
        """
323
        Permet aux plugins de pouvoir récupérer des valeurs Json
324
        """
325
        plugins = config['vigiboard_plugins']
326
        if plugins is None:
327
            return
328

    
329
        plugin = [i for i in plugins if i[0] == plugin_name][0]
330
        try:
331
            mypac = __import__(
332
                'vigiboard.controllers.vigiboard_plugin.' + plugin[0],
333
                globals(), locals(), [plugin[1]], -1)
334
            plug = getattr(mypac, plugin[1])()
335
            return plug.controller(*arg, **krgv)
336
        except:
337
            raise
338
    
339
    @validate(validators= {"fontsize": validators.Int()},
340
                    error_handler = process_form_errors)
341
    @expose('json')
342
    def set_fontsize(self, fontsize):
343
        """
344
        Save font size
345
        """
346
        session['fontsize'] = fontsize
347
        session.save()
348
        return dict(ret= 'ok')
349

    
350
    @validate(validators= {"refresh": validators.Int()},
351
            error_handler = process_form_errors)
352
    @expose('json')
353
    def set_refresh(self, refresh):
354
        """
355
        Save refresh time
356
        """
357
        session['refresh'] = refresh
358
        session.save()
359
        return dict(ret= 'ok')