Project

General

Profile

Revision d5a41c9b

IDd5a41c9b5f30ed08c33f60992aebca4597aabfc7
Parent 32b2c767
Child 703bd599

Added by Vincent QUEMENER over 10 years ago

Inhibition des alertes (#1187).

Refs: #1187
Change-Id: I87a9c86eb2ecd344b31e092d9dbd645d79ea4cba
Reviewed-on: https://vigilo-dev.si.c-s.fr/review/1293
Tested-by: Build system <>
Reviewed-by: Francois POIROTTE <>

View differences:

doc/util.rst
334 334

  
335 335

  
336 336

  
337
Inhibition des alertes
338
------------------------------------
339
Cette fonctionnalité permet d'empêcher l'apparition de nouvelles alertes dans
340
VigiBoard pour un hôte ou un service donné. La page listant les règles
341
d'inhibition (aussi appelées règles de mise en silence) actives est accessible
342
en cliquant sur l'icône ci-dessous située en haut à droite de l'interface :
343

  
344
.. figure:: img/silence_rules.png
345

  
346
Les règles sont triées par défaut par ordre décroissant de dernière mise à jour,
347
comme on peut le voir sur la capture ci-dessous :
348

  
349
.. Capture à ajouter
350

  
351
Depuis cette page, il est alors possible d'éditer ou de supprimer une règle
352
existante en cliquant sur l'une des deux icônes située en début de ligne :
353

  
354
.. figure:: img/silence_update_delete.png
355

  
356
L'utilisateur est également en mesure d'ajouter une nouvelle règle en cliquant
357
sur le bouton prévu à cet effet situé juste au-dessus du tableau :
358

  
359
.. figure:: img/silence_add.png
360

  
361
..  note::
362
    Les alertes déjà traitées (c'est à dire soit déjà ignorées, soit déjà
363
    affichées dans VigiBoard) ne sont pas impactées par les modifications faites
364
    sur les règles (ie. aucun traitement n'est réalisé a posteriori pour générer
365
    des alertes ou pour détruire des alertes déjà présentes).
366
    De même, ce filtrage n'impacte que la production d'alertes, il ne concerne
367
    pas l'état des hôtes/services (donc l'élément peut être ``CRITICAL`` dans
368
    VigiMap mais ne pas avoir d'alarme correspondante dans VigiBoard).
369

  
370

  
371

  
337 372
Annexes
338 373
=======
339 374

  
test.ini
36 36
[app:unlimited_maps]
37 37
use = main_without_authn
38 38
max_maps = -2
39

  
40
[app:pagination]
41
use = main
42
vigiboard_items_per_page = 1
vigiboard/controllers/root.py
58 58

  
59 59
from vigiboard.controllers.vigiboardrequest import VigiboardRequest
60 60
from vigiboard.controllers.feeds import FeedsController
61
from vigiboard.controllers.silence import SilenceController
61 62

  
62 63
from vigiboard.lib import export_csv, dateformat
63 64
from vigiboard.widgets.edit_event import edit_event_status_options, \
......
87 88
        not_anonymous(l_('You need to be authenticated')))
88 89
    api = ApiRootController()
89 90
    feeds = FeedsController()
91
    silence = SilenceController()
90 92
    custom = CustomController()
91 93

  
92 94
    # Prédicat pour la restriction de l'accès aux interfaces.
vigiboard/controllers/silence.py
1
# -*- coding: utf-8 -*-
2
# vim:set expandtab tabstop=4 shiftwidth=4:
3
###############################################################################
4
#
5
# Copyright (C) 2007-2013 CS-SI
6
#
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License version 2 as
9
# published by the Free Software Foundation.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
###############################################################################
20

  
21
"""Gère la planification des mises en silence."""
22

  
23
#import time
24
from datetime import datetime
25

  
26
from tg import expose, validate, require, flash, tmpl_context, \
27
    request, config, redirect
28
from pylons.i18n import lazy_ugettext as l_, ugettext as _
29
#from tg.i18n import get_lang
30

  
31
#from tw.forms import CalendarDateTimePicker
32
from webhelpers import paginate
33
from tw.forms import validators
34

  
35
from vigilo.turbogears.helpers import get_current_user
36
from repoze.what.predicates import Any, All, in_group, \
37
                                    has_permission, not_anonymous
38
from formencode import schema
39
from formencode.compound import All as All_
40
from formencode.foreach import ForEach
41

  
42
from sqlalchemy.exc import InvalidRequestError, IntegrityError
43
from sqlalchemy.sql.expression import asc, desc
44

  
45
from vigilo.turbogears.controllers import BaseController
46
from vigilo.models.session import DBSession
47

  
48
from vigilo.models.tables import SupItem, Host, LowLevelService, \
49
                            HighLevelService, StateName, Silence, UserSupItem
50
from vigilo.models.tables.secondary_tables import SILENCE_STATE_TABLE
51

  
52
from vigilo.models.utils import group_concat
53

  
54
import logging
55

  
56
LOGGER = logging.getLogger(__name__)
57

  
58
__all__ = ['SilenceController']
59

  
60
# pylint: disable-msg=R0201
61
class SilenceController(BaseController):
62
    """
63
    Contrôleur gérant la planification des mises en silence.
64
    """
65

  
66
    # Prédicat pour la restriction de l'accès aux interfaces.
67
    # L'utilisateur doit avoir la permission "vigiboard-silence"
68
    # ou appartenir au groupe "managers" pour accéder à VigiBoard.
69
    access_restriction = All(
70
        not_anonymous(msg=l_("You need to be authenticated")),
71
        Any(in_group('managers'),
72
            has_permission('vigiboard-silence'),
73
            msg=l_("Insufficient privileges for this action"))
74
    )
75

  
76
    def handle_error_message(self, message, redirection_url='./'):
77
        """
78
        Affiche le message dans l'IHM, l'enregistre dans les logs
79
        et renvoie le navigateur vers l'URL de redirection.
80

  
81
        @param message: message d'erreur à afficher
82
        @type  message: C{str}
83
        @param redirection_url: (optionnel) URL de redirection
84
        @type  redirection_url: C{str}
85
        """
86
        LOGGER.error(message)
87
        flash(message, 'error')
88
        redirect(redirection_url)
89

  
90
    def process_form_errors(self, *argv, **kwargv):
91
        """
92
        Gestion des erreurs de validation : on affiche les erreurs
93
        puis on redirige vers la dernière page accédée.
94
        """
95
        for k in tmpl_context.form_errors:
96
            flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error')
97
        redirect(request.environ.get('HTTP_REFERER', '/'))
98

  
99
    def query_silences(self):
100
        """
101
        Retourne une requête SQLAlchemy interrogeant
102
        la table des mises en silence
103
        """
104

  
105
        # Si l'utilisateur fait partie du groupe 'managers', on récupère la
106
        # liste de tous les supitems de la base de données
107
        if in_group('managers').is_met(request.environ):
108
            lls_query = DBSession.query(
109
                    LowLevelService.idservice.label('idsupitem'),
110
                    LowLevelService.servicename.label("servicename"),
111
                    Host.name.label('hostname')
112
                ).join((Host, Host.idhost == LowLevelService.idhost))
113

  
114
            host_query = DBSession.query(
115
                    Host.idhost.label('idsupitem'),
116
                    "NULL",
117
                    Host.name.label('hostname')
118
                )
119

  
120
            supitems = lls_query.union(host_query).subquery()
121

  
122
        # Sinon on ne récupère que les supitems auxquels l'utilisateurs a accès
123
        else:
124
            user_name = request.identity['repoze.who.userid']
125
            supitems = DBSession.query(
126
                UserSupItem.idsupitem.label('idsupitem'),
127
                UserSupItem.servicename.label("servicename"),
128
                UserSupItem.hostname.label('hostname')
129
            ).filter(
130
                UserSupItem.username == user_name
131
            ).distinct().subquery()
132

  
133
        # On interroge la base pour avoir la liste des règles de mise en silence
134
        # correspondant à ces supitems.
135
        states = DBSession.query(
136
                SILENCE_STATE_TABLE.c.idsilence,
137
                StateName.statename
138
            ).join((StateName,
139
                StateName.idstatename == SILENCE_STATE_TABLE.c.idstate)
140
            ).order_by(StateName.statename
141
            ).subquery()
142
        states = DBSession.query(
143
                states.c.idsilence,
144
                group_concat(states.c.statename, ', ').label('states'),
145
            ).group_by(states.c.idsilence
146
            ).subquery()
147
        silences = DBSession.query(
148
                Silence,
149
                supitems.c.hostname,
150
                supitems.c.servicename,
151
                states.c.states
152
            ).join((supitems, supitems.c.idsupitem == Silence.idsupitem)
153
            ).join((states, states.c.idsilence == Silence.idsilence))
154

  
155
        return silences
156

  
157
    def check_silence_rule_existence(self, idsupitem):
158
        """
159
        S'assure qu'aucune règle de mise en silence n'existe dans la base de
160
        données pour le supitem considéré, et affiche un message d'erreur dans
161
        le cas contraire.
162

  
163
        @param idsupitem: Identifiant du supitem.
164
        @type  idsupitem: C{int}
165
        """
166
        silence = DBSession.query(Silence
167
            ).filter(Silence.idsupitem == idsupitem
168
            ).first()
169
        if not silence:
170
            return
171
        if isinstance(silence.supitem, LowLevelService):
172
            msg = _("Another rule already exists for service '%s' " \
173
                    "on host '%s'.") % (silence.supitem.servicename,
174
                        silence.supitem.host.name)
175
        else:
176
            msg = _("Another rule already exists for host '%s'.") % (
177
                silence.supitem.name)
178
        self.handle_error_message(msg)
179

  
180
    class IndexSchema(schema.Schema):
181
        """Schéma de validation de la méthode index."""
182
        # Si on ne passe pas le paramètre "page" ou qu'on passe une valeur
183
        # invalide ou pas de valeur du tout, alors on affiche la 1ère page.
184
        page = validators.Int(min=1, if_missing=1,
185
            if_invalid=1, not_empty=True)
186
        sort = validators.OneOf(
187
            ['hostname', 'servicename', 'lastmodification',
188
                'author', 'comment', 'states'],
189
            if_missing='lastmodification', if_invalid='lastmodification')
190
        order = validators.OneOf(['desc', 'asc'],
191
            if_missing='desc', if_invalid='desc')
192

  
193
    @validate(
194
        validators=IndexSchema(),
195
        error_handler = process_form_errors)
196
    @expose('silence.html')
197
    @require(access_restriction)
198
    def index(self, page=1, sort=None, order=None):
199
        """
200
        Affiche la liste des règles de mise en silence enregistrées dans
201
        la BDD, que l'utilisateur pourra ensuite éditer ou supprimer.
202

  
203
        @param sort: (optionnel) Critère de tri de la liste des
204
                     règles de mise en silence enregistrées.
205
        @type  sort: C{str}
206
        @param order: (optionnel) Ordre de tri.
207
        @type  order: C{str}
208
        """
209

  
210
#        # On récupère la langue de l'utilisateur
211
#        lang = get_lang()
212
#        if not lang:
213
#            lang = ['fr']
214
#        lang = lang[0]
215

  
216
        # On récupère tous les enregistrements de la table
217
        # silence, qu'ils concernent des hôtes, des services
218
        # de bas niveau, ou bien des services de haut niveau.
219
        silences = self.query_silences()
220

  
221
        # On trie ces enregistrements selon le critère choisi
222
        # par l'utilisateur (par défaut, la date d'ajout).
223
        sort_keys = {
224
            'hostname': 'hostname',
225
            'servicename': 'servicename',
226
            'lastmodification': Silence.lastmodification,
227
            'author': Silence.author,
228
            'comment': Silence.comment,
229
#            'start': Silence.start,
230
#            'end': Silence.end,
231
            'states': 'states',
232
        }
233
        if sort in sort_keys.keys():
234
            # Tri dans l'ordre croissant
235
            if order != 'desc':
236
                silences = silences.order_by(asc(sort_keys[sort]))
237
            # Tri dans l'ordre décroissant
238
            else:
239
                silences = silences.order_by(desc(sort_keys[sort]))
240

  
241
        # On calcule la pagination
242
        page = paginate.Page(silences, page=page,
243
            items_per_page=int(config['vigiboard_items_per_page']))
244

  
245
#        # On initialise les widgets des calendriers
246
#        # utilisés dans le formulaire de mise en silence.
247
#        start_calendar = CalendarDateTimePicker('start',
248
#                                            button_text = l_("Choose a date"),
249
#                                            date_format = '%Y-%m-%d %H:%M',
250
#                                            calendar_lang = lang)
251
#        end_calendar = CalendarDateTimePicker('end',
252
#                                            button_text = l_("Choose a date"),
253
#                                            date_format = '%Y-%m-%d %H:%M',
254
#                                            calendar_lang = lang)
255

  
256
        # Traduction du nom des colonnes
257
        columns = [
258
            ('hostname', l_('Host')),
259
            ('servicename', l_('Service')),
260
            ('states', l_('States')),
261
            ('lastmodification', l_('Last modification')),
262
            ('author', l_('Author')),
263
            ('comment', l_('Comment'))
264
        ]
265

  
266
        return dict(
267
            page=page,
268
            sort=sort,
269
            order=order,
270
#            start_calendar=start_calendar,
271
#            end_calendar=end_calendar,
272
            columns=columns
273
        )
274

  
275
    @expose('silence_form.html')
276
    @require(access_restriction)
277
    def add(self):
278
        """
279
        Affiche un formulaire d'ajout d'une règle de mise en silence.
280
        """
281
        return dict(
282
            id=None,
283
            hostname=None,
284
            servicename=None,
285
            states=None,
286
            comment=None,
287
#            start_calendar=start_calendar,
288
#            end_calendar=end_calendar,
289
        )
290

  
291
    class UpdateSchema(schema.Schema):
292
        """Schéma de validation de la méthode update."""
293
        id = validators.Int(min=1, not_empty=True)
294

  
295
    @validate(
296
        validators=UpdateSchema(),
297
        error_handler = process_form_errors)
298
    @expose('silence_form.html')
299
    @require(access_restriction)
300
    def update(self, id):
301
        """
302
        Affiche un formulaire de mise à jour d'une règle de mise en silence.
303

  
304
        @param id: Identifiant de la règle.
305
        @type  id: C{int}
306
        """
307

  
308
        # On s'assure que la règle existe bien dans la base
309
        try:
310
            silence = DBSession.query(Silence
311
                ).filter(Silence.idsilence == id).one()
312
        except InvalidRequestError, e:
313
            msg = _('An exception has been raised while ' \
314
                    'querying the database: %s') % str(e)
315
            self.handle_error_message(msg)
316
        if not silence:
317
            msg = _("Silence rule #%s does not exist.") % id
318
            self.handle_error_message(msg)
319

  
320
        # On s'assure que l'utilisateur dispose bien des permissions sur le
321
        # supitem considéré
322
        user = get_current_user()
323
        if not silence.supitem.is_allowed_for(user):
324
            msg = _("Silence rule #%s does not exist.") % id
325
            self.handle_error_message(msg)
326

  
327
        if hasattr(silence.supitem, 'servicename'):
328
            hostname = silence.supitem.host.name
329
            servicename = silence.supitem.servicename
330
        else:
331
            hostname = silence.supitem.name
332
            servicename = None
333

  
334
        return dict(
335
            id=id,
336
            hostname=hostname,
337
            servicename=servicename,
338
            states=[s.statename for s in silence.states],
339
            comment=silence.comment,
340
#            start_calendar=start_calendar,
341
#            end_calendar=end_calendar,
342
        )
343

  
344
    class CreateOrModifySchema(schema.Schema):
345
        """Schéma de validation de la méthode create_or_modify."""
346
        states = All_(
347
            validators.Set(use_set=True),
348
            validators.OneOf(["WARNING", "CRITICAL", "DOWN", "UNKNOWN"],
349
                testValueList=True, hideList=True, not_empty=True)
350
        )
351
        host = validators.String(not_empty=True)
352
        service = validators.String()
353
        comment = validators.String()
354
        idsilence = validators.Int(min=1, if_missing=None,
355
            if_invalid=None, not_empty=False)
356

  
357
    @validate(
358
        validators=CreateOrModifySchema(),
359
        error_handler = process_form_errors)
360
    @expose()
361
    @require(access_restriction)
362
    def create_or_modify(
363
            self,
364
            states,
365
            host,
366
            service=None,
367
#            start=time.time(),
368
#            end=time.time(),
369
            comment=None,
370
            idsilence=None):
371
        """
372
        Ajoute une règle de mise en silence d'un hôte/service,
373
        ou en modifie une déjà existante.
374

  
375
        @param states: (optionnel) Liste des états concernés par la règle.
376
        @type  states: C{list} of C{unicode}
377
        @param host: Nom de l'hôte sur lequel porte la règle.
378
        @type  host: C{unicode}
379
        @param service: (optionnel) Nom du service sur lequel
380
            porte la règle.
381
        @type  service: C{unicode}
382
#        @param start: Début de la mise en silence planifiée.
383
#        @type  start: C{str}
384
#        @param end: Fin de la mise en silence planifiée.
385
#        @type  end: C{str}
386
        @param comment: (optionnel) Commentaire accompagnant la règle.
387
        @type  comment: C{unicode}
388
        @param idsilence: (optionnel) Identifiant de la règle dans le cas d'une
389
            mise à jour.
390
        @type  idsilence: C{int}
391
        """
392

  
393
        # TODO: Faire ce traitement dans le schéma de validation
394
        if not states:
395
            msg = _('No state specified for the silence rule.')
396
            self.handle_error_message(msg)
397
        states = list(states)
398

  
399
        # On récupère le nom et l'IP de l'utilisateur.
400
        user = get_current_user()
401
        user_name = user.user_name
402
        user_ip = request.remote_addr
403

  
404
        # On récupère l'identifiant de l'item (hôte
405
        # ou service) concerné par la mise en silence.
406
        idsupitem = SupItem.get_supitem(host, service)
407
        if idsupitem:
408
            try:
409
                supitem = DBSession.query(SupItem
410
                    ).filter(SupItem.idsupitem == idsupitem).one()
411
            except InvalidRequestError, e:
412
                msg = _('An exception has been raised while ' \
413
                        'querying the database: %s') % str(e)
414
                self.handle_error_message(msg)
415
        if not idsupitem or not supitem.is_allowed_for(user):
416
            if not service:
417
                msg = _("Host '%s' does not exist.") % host
418
                self.handle_error_message(msg)
419
            else:
420
                msg = _("Service '%s' does not exist for host '%s'."
421
                    ) % (service, host)
422
                self.handle_error_message(msg)
423

  
424
        # On distingue mise à jour et création :
425

  
426
        # 1. Dans le cas d'une mise à jour :
427
        if idsilence:
428

  
429
            # - On s'assure que la règle existe bien dans la base
430
            try:
431
                silence = DBSession.query(Silence
432
                    ).filter(Silence.idsilence == idsilence).one()
433
            except InvalidRequestError, e:
434
                msg = _('An exception has been raised while ' \
435
                        'querying the database: %s') % str(e)
436
                self.handle_error_message(msg)
437
            if not silence:
438
                msg = _("Silence rule #%s does not exist.") % idsilence
439
                self.handle_error_message(msg)
440

  
441
            # - Si le supitem a été modifié, on vérifie qu'aucune
442
            #   autre règle n'existe pour le nouveau supitem
443
            if silence.idsupitem != idsupitem:
444
                self.check_silence_rule_existence(idsupitem)
445

  
446
            # On supprime les états existants
447
            silence.states = []
448

  
449
        # 2. Dans le cas d'une création :
450
        else:
451

  
452
            # - On s'assure qu'aucune autre règle n'existe pour le supitem
453
            self.check_silence_rule_existence(idsupitem)
454

  
455
            # - Et on crée l'objet représentant la règle
456
            silence = Silence()
457

  
458
        # Dans les 2 cas, on met à jour l'objet avec
459
        # les informations passées en paramètre
460
        silence.idsupitem = idsupitem
461
        silence.comment = comment
462
        silence.lastmodification = datetime.now().replace(microsecond=0)
463
        silence.author = user_name
464
        try:
465
            DBSession.add(silence)
466
            for state in states:
467
                s = DBSession.query(StateName
468
                    ).filter(StateName.statename == state).one()
469
                silence.states.append(s)
470
            DBSession.flush()
471
        except (IntegrityError, InvalidRequestError), e:
472
            msg = _('An exception has been raised while ' \
473
                    'updating the database: %s') % str(e)
474
            self.handle_error_message(msg)
475

  
476
        # On notifie l'opération dans les logs, on affiche un message de
477
        # succès, et on redirige le navigateur vers la liste des règles de
478
        # mise en silence.
479
        if idsilence:
480
            # Mise à jour d'une règle portant sur un service
481
            if hasattr(silence.supitem, 'servicename'):
482
                LOGGER.info(_(
483
                    'User %(user)s (IP: %(ip)s) updated silence rule ' \
484
                    '#%(id)s for service %(service)s on host %(host)s.'
485
                ) % {
486
                    'user': user_name,
487
                    'ip': user_ip,
488
                    'id': idsilence,
489
                    'host': host,
490
                    'service': service
491
                })
492
                flash(_(
493
                    'Silence rule #%(id)s (host: %(host)s, service: ' \
494
                    '%(service)s) has been successfully updated.') % {
495
                        'id': idsilence,
496
                        'host': host,
497
                        'service': service
498
                })
499
            # Mise à jour d'une règle portant sur un hôte
500
            else:
501
                LOGGER.info(_(
502
                    'User %(user)s (IP: %(ip)s) updated silence rule ' \
503
                    '#%(id)s for host %(host)s.') % {
504
                        'user': user_name,
505
                        'ip': user_ip,
506
                        'id': idsilence,
507
                        'host': host
508
                })
509
                flash(_(
510
                    'Silence rule #%(id)s (host: %(host)s) ' \
511
                    'has been successfully updated.') % {
512
                        'id': idsilence,
513
                        'host': host
514
                })
515
        else:
516
            # Ajout d'une règle portant sur un service
517
            if service:
518
                LOGGER.info(_(
519
                    'User %(user)s (IP: %(ip)s) added a silence rule (#' \
520
                    '%(id)s) for service %(service)s on host %(host)s.'
521
                ) % {
522
                    'user': user_name,
523
                    'ip': user_ip,
524
                    'id': idsilence,
525
                    'host': host,
526
                    'service': service
527
                })
528
                flash(_('A new silence rule (#%(id)s) has been added for '
529
                    'service "%(service)s" on host "%(host)s".') % {
530
                        'id': silence.idsilence,
531
                        'service': service,
532
                        'host': host
533
                    })
534
            # Ajout d'une règle portant sur un hôte
535
            else:
536
                LOGGER.info(_(
537
                    'User %(user)s (IP: %(ip)s) added a silence rule ' \
538
                    '(#%(id)s) for host %(host)s.') % {
539
                        'user': user_name,
540
                        'ip': user_ip,
541
                        'id': idsilence,
542
                        'host': host
543
                })
544
                flash(_('A new silence rule (#%(id)s) has been added for the '
545
                    'host "%(host)s".') % {
546
                        'id': silence.idsilence,
547
                        'host': host
548
                    })
549
        redirect('./')
550

  
551

  
552
    class DeleteSchema(schema.Schema):
553
        """Schéma de validation de la méthode delete."""
554
        id = All_(
555
            validators.Set(use_set=True),
556
            ForEach(validators.Int(min=1)),
557
        )
558

  
559
    @validate(
560
        validators=DeleteSchema(),
561
        error_handler = process_form_errors)
562
    @expose()
563
    @require(access_restriction)
564
    def delete(self, id):
565
        """
566
        Suppression d'une règle ou d'une liste de règles de mise en silence.
567

  
568
        @param id: Liste des identifiants des règles à supprimer.
569
        @type  id: C{list} of C{int}
570
        """
571

  
572
        # TODO: Faire ce traitement dans le schéma de validation
573
        if not id:
574
            msg = _('No silence rule id specified.')
575
            self.handle_error_message(msg)
576
        id = list(id)
577

  
578
        # On recherche les règles dans la BDD.
579
        try:
580
            silences = DBSession.query(Silence
581
                ).filter(Silence.idsilence.in_(id)).all()
582
        except InvalidRequestError, e:
583
            msg = _('An exception has been raised while ' \
584
                    'querying the database: %s') % str(e)
585
            self.handle_error_message(msg)
586

  
587
        # On s'assure que toutes les règles ont bien été trouvées dans la
588
        # base, faute de quoi on lève une erreur et on arrête le traitement
589
        if len(silences) != len(id):
590
            missing_ids = [
591
                i for i in id if i not in [s.idsilence for s in silences]]
592
            if len(missing_ids) > 1:
593
                msg = _('Error: the following silence rules do not exist:' \
594
                    ' %s.') % ", ".join('#' + str(i) for i in missing_ids)
595
            else:
596
                msg = _('Error: silence rule #%s does not exist.'
597
                    ) % ", ".join(str(i) for i in missing_ids)
598
            self.handle_error_message(msg)
599

  
600
        # On s'assure que l'utilisateur dispose bien des permissions nécessaires
601
        # pour supprimer chacune des règles
602
        user = get_current_user()
603
        for s in silences:
604
            if not s.supitem.is_allowed_for(user):
605
                msg = _("Silence rule #%s does not exist.") % s.idsilence
606
                self.handle_error_message(msg)
607

  
608
        # On supprime les règles dans la BDD.
609
        try:
610
            for silence in silences:
611
                DBSession.delete(silence)
612
            DBSession.flush()
613
        except InvalidRequestError, e:
614
            msg = _('An exception has been raised while ' \
615
                    'deleting the silence rules: %s') % str(e)
616
            self.handle_error_message(msg)
617

  
618
        # On notifie l'opération dans les logs
619
        user_name = user.user_name
620
        user_ip = request.remote_addr
621
        for s in silences:
622
            # Règle concernant un service de bas niveau
623
            if hasattr(s.supitem, 'servicename'):
624
                LOGGER.info(_(
625
                    'User %(user)s (IP: %(ip)s) deleted silence rule ' \
626
                    '#%(id)s for service %(service)s on host ' \
627
                    '%(host)s') % {
628
                        'user': user_name,
629
                        'ip': user_ip,
630
                        'id': s.idsilence,
631
                        'host': s.supitem.host.name,
632
                        'service': s.supitem.servicename
633
                })
634
            # Règle concernant un hôte
635
            else:
636
                LOGGER.info(_(
637
                    'User %(user)s (IP: %(ip)s) deleted silence rule ' \
638
                    '#%(id)s for host %(host)s') % {
639
                        'user': user_name,
640
                        'ip': user_ip,
641
                        'id': s.idsilence,
642
                        'host': s.supitem.name,
643
                })
644

  
645
        # On affiche un message de succès
646
        if len(id) > 1:
647
            flash(_('The following silence rules have been successfully ' \
648
                'deleted: %s.') % ", ".join(str(i) for i in id))
649
        else:
650
            flash(_('Silence rule #%s has been successfully ' \
651
                'deleted.') % id[0])
652

  
653
        # On redirige le navigateur vers la page d'index
654
        redirect('./', )
655

  
vigiboard/i18n/de/LC_MESSAGES/vigiboard.po
8 8
"Project-Id-Version: vigiboard 2.0.0\n"
9 9
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10 10
"POT-Creation-Date: 2010-11-19 10:22+0100\n"
11
"PO-Revision-Date: 2013-11-19 12:46+0100\n"
11
"PO-Revision-Date: 2014-02-03 10:52+0100\n"
12 12
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13
"Language-Team: de_DE <LL@li.org>\n"
14 14
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
......
22 22
msgid "Vigilo has detected a breakdown on the following collector(s): %(list)s"
23 23
msgstr ""
24 24

  
25
#: vigiboard/controllers/root.py:88 vigiboard/controllers/root.py:97
26
#: vigiboard/controllers/root.py:578
25
#: vigiboard/controllers/root.py:89 vigiboard/controllers/root.py:99
26
#: vigiboard/controllers/root.py:582 vigiboard/controllers/silence.py:70
27 27
msgid "You need to be authenticated"
28 28
msgstr "Sie müssen sich authentifizieren"
29 29

  
30
#: vigiboard/controllers/root.py:100
30
#: vigiboard/controllers/root.py:102
31 31
msgid "You don't have access to VigiBoard"
32 32
msgstr "Sie haben keinen Zugang zu VigiBoard"
33 33

  
34
#: vigiboard/controllers/root.py:248 vigiboard/controllers/root.py:544
34
#: vigiboard/controllers/root.py:252 vigiboard/controllers/root.py:548
35 35
#: vigiboard/controllers/vigiboardrequest.py:474
36 36
msgid "Apply"
37 37
msgstr "Anwenden"
38 38

  
39
#: vigiboard/controllers/root.py:384
39
#: vigiboard/controllers/root.py:388
40 40
msgid "No masked event or access denied"
41 41
msgstr "Kein maskiertes Ereignis oder Zugriff verweigert"
42 42

  
43
#: vigiboard/controllers/root.py:442
43
#: vigiboard/controllers/root.py:446
44 44
msgid "No such event or access denied"
45 45
msgstr "Ereignis nicht vorhanden oder Zugriff verweigert"
46 46

  
47
#: vigiboard/controllers/root.py:511
47
#: vigiboard/controllers/root.py:515
48 48
msgid "No such host/service"
49 49
msgstr "Host/Service nicht vorhanden"
50 50

  
51
#: vigiboard/controllers/root.py:534
51
#: vigiboard/controllers/root.py:538
52 52
msgid "No access to this host/service or no event yet"
53 53
msgstr "Kein Zugang zu diesem Host/Service oder Ereignis noch nicht vorhanden"
54 54

  
55
#: vigiboard/controllers/root.py:581
55
#: vigiboard/controllers/root.py:585
56 56
msgid "You don't have write access to VigiBoard"
57 57
msgstr "Sie haben keinen Schreibzugriff auf VigiBoard"
58 58

  
59
#: vigiboard/controllers/root.py:604
59
#: vigiboard/controllers/root.py:608
60 60
msgid "No event has been selected"
61 61
msgstr "Es wurde kein Ereignis ausgewählt"
62 62

  
63
#: vigiboard/controllers/root.py:632
63
#: vigiboard/controllers/root.py:636
64 64
msgid ""
65 65
"Changes have occurred since the page was last displayed, your changes "
66 66
"HAVE NOT been saved."
......
68 68
"Die seit der letzten Anzeige der Seite von Ihnen vorgenommenen Änderungen"
69 69
" WURDEN NICHT gespeichert."
70 70

  
71
#: vigiboard/controllers/root.py:638
71
#: vigiboard/controllers/root.py:642
72 72
msgid "No access to this event"
73 73
msgstr "Kein Zugang zu diesem Ereignis "
74 74

  
75
#: vigiboard/controllers/root.py:645
75
#: vigiboard/controllers/root.py:649
76 76
msgid "You don't have administrative access to VigiBoard"
77 77
msgstr "Sie haben keine administrativen Zugriff auf VigiBoard"
78 78

  
79
#: vigiboard/controllers/root.py:672
79
#: vigiboard/controllers/root.py:676
80 80
msgid "None"
81 81
msgstr ""
82 82

  
83
#: vigiboard/controllers/root.py:673
83
#: vigiboard/controllers/root.py:677
84 84
#, fuzzy
85 85
msgid "Acknowledged"
86 86
msgstr "Bestätigen"
87 87

  
88
#: vigiboard/controllers/root.py:674
88
#: vigiboard/controllers/root.py:678
89 89
msgid "Acknowledged and closed"
90 90
msgstr ""
91 91

  
92
#: vigiboard/controllers/root.py:695
92
#: vigiboard/controllers/root.py:699
93 93
#, python-format
94 94
msgid ""
95 95
"User \"%(user)s\" (%(address)s) changed the trouble ticket from "
96 96
"\"%(previous)s\" to \"%(new)s\" on event #%(idevent)d"
97 97
msgstr ""
98 98

  
99
#: vigiboard/controllers/root.py:740
99
#: vigiboard/controllers/root.py:744
100 100
#, python-format
101 101
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d"
102 102
msgstr ""
103 103

  
104
#: vigiboard/controllers/root.py:773
104
#: vigiboard/controllers/root.py:777
105 105
#, python-format
106 106
msgid ""
107 107
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" "
108 108
"to \"%(new)s\" on event #%(idevent)d"
109 109
msgstr ""
110 110

  
111
#: vigiboard/controllers/root.py:785
111
#: vigiboard/controllers/root.py:789
112 112
msgid "Updated successfully"
113 113
msgstr "Erfolgreich aktualisiert"
114 114

  
115
#: vigiboard/controllers/root.py:810
115
#: vigiboard/controllers/root.py:814
116 116
#, fuzzy, python-format
117 117
msgid "No such plugin '%s'"
118 118
msgstr "Plug-In \"%s\" nicht vorhanden"
119 119

  
120
#: vigiboard/controllers/root.py:852
120
#: vigiboard/controllers/root.py:856
121 121
msgid "No such incident or insufficient permissions"
122 122
msgstr "Ereignis nicht vorhanden oder unzureichende Berechtigungen"
123 123

  
124
#: vigiboard/controllers/root.py:964
124
#: vigiboard/controllers/root.py:968
125 125
#, python-format
126 126
msgid "Next %(limit)s"
127 127
msgstr ""
128 128

  
129
#. TRANSLATORS: Format de date et heure Python/JavaScript.
130
#. TRANSLATORS:
131
#. http://www.dynarch.com/static/jscalendar-1.0/doc/html/reference.html#node_sec_5.3.5
132
#. TRANSLATORS: http://docs.python.org/release/2.5/lib/module-time.html
133
#: vigiboard/controllers/plugins/date.py:57 vigiboard/lib/dateformat.py:34
134
#: vigiboard/lib/dateformat.py:46
129
#: vigiboard/controllers/silence.py:73
130
msgid "Insufficient privileges for this action"
131
msgstr ""
132

  
133
#: vigiboard/controllers/silence.py:172
135 134
#, python-format
136
msgid "%Y-%m-%d %I:%M:%S %p"
137
msgstr "%Y-%m-%d %I:%M:%S %p"
135
msgid "Another rule already exists for service '%s' on host '%s'."
136
msgstr ""
137

  
138
#: vigiboard/controllers/silence.py:176
139
#, python-format
140
msgid "Another rule already exists for host '%s'."
141
msgstr ""
142

  
143
#: vigiboard/controllers/silence.py:258
144
#: vigiboard/controllers/plugins/hostname.py:38
145
msgid "Host"
146
msgstr "Host"
147

  
148
#: vigiboard/controllers/silence.py:259
149
#: vigiboard/controllers/plugins/servicename.py:41
150
msgid "Service"
151
msgstr "Service"
152

  
153
#: vigiboard/controllers/silence.py:260
154
msgid "States"
155
msgstr ""
156

  
157
#: vigiboard/controllers/silence.py:261
158
msgid "Last modification"
159
msgstr ""
160

  
161
#: vigiboard/controllers/silence.py:262
162
msgid "Author"
163
msgstr ""
164

  
165
#: vigiboard/controllers/silence.py:263
166
msgid "Comment"
167
msgstr ""
168

  
169
#: vigiboard/controllers/silence.py:313 vigiboard/controllers/silence.py:412
170
#: vigiboard/controllers/silence.py:434 vigiboard/controllers/silence.py:583
171
#, python-format
172
msgid "An exception has been raised while querying the database: %s"
173
msgstr ""
174

  
175
#: vigiboard/controllers/silence.py:317 vigiboard/controllers/silence.py:324
176
#: vigiboard/controllers/silence.py:438 vigiboard/controllers/silence.py:605
177
#, python-format
178
msgid "Silence rule #%s does not exist."
179
msgstr ""
180

  
181
#: vigiboard/controllers/silence.py:395
182
msgid "No state specified for the silence rule."
183
msgstr ""
184

  
185
#: vigiboard/controllers/silence.py:417
186
#, python-format
187
msgid "Host '%s' does not exist."
188
msgstr ""
189

  
190
#: vigiboard/controllers/silence.py:420
191
#, python-format
192
msgid "Service '%s' does not exist for host '%s'."
193
msgstr ""
194

  
195
#: vigiboard/controllers/silence.py:472
196
#, python-format
197
msgid "An exception has been raised while updating the database: %s"
198
msgstr ""
199

  
200
#: vigiboard/controllers/silence.py:482
201
#, python-format
202
msgid ""
203
"User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for service "
204
"%(service)s on host %(host)s."
205
msgstr ""
206

  
207
#: vigiboard/controllers/silence.py:492
208
#, python-format
209
msgid ""
210
"Silence rule #%(id)s (host: %(host)s, service: %(service)s) has been "
211
"successfully updated."
212
msgstr ""
213

  
214
#: vigiboard/controllers/silence.py:501
215
#, python-format
216
msgid "User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for host %(host)s."
217
msgstr ""
218

  
219
#: vigiboard/controllers/silence.py:509
220
#, python-format
221
msgid "Silence rule #%(id)s (host: %(host)s) has been successfully updated."
222
msgstr ""
223

  
224
#: vigiboard/controllers/silence.py:518
225
#, python-format
226
msgid ""
227
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for service "
228
"%(service)s on host %(host)s."
229
msgstr ""
230

  
231
#: vigiboard/controllers/silence.py:528
232
#, python-format
233
msgid ""
234
"A new silence rule (#%(id)s) has been added for service \"%(service)s\" "
235
"on host \"%(host)s\"."
236
msgstr ""
237

  
238
#: vigiboard/controllers/silence.py:536
239
#, python-format
240
msgid ""
241
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for host "
242
"%(host)s."
243
msgstr ""
244

  
245
#: vigiboard/controllers/silence.py:544
246
#, python-format
247
msgid "A new silence rule (#%(id)s) has been added for the host \"%(host)s\"."
248
msgstr ""
249

  
250
#: vigiboard/controllers/silence.py:574
251
msgid "No silence rule id specified."
252
msgstr ""
253

  
254
#: vigiboard/controllers/silence.py:593
255
#, python-format
256
msgid "Error: the following silence rules do not exist: %s."
257
msgstr ""
258

  
259
#: vigiboard/controllers/silence.py:596
260
#, python-format
261
msgid "Error: silence rule #%s does not exist."
262
msgstr ""
263

  
264
#: vigiboard/controllers/silence.py:614
265
#, python-format
266
msgid "An exception has been raised while deleting the silence rules: %s"
267
msgstr ""
268

  
269
#: vigiboard/controllers/silence.py:624
270
#, python-format
271
msgid ""
272
"User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for service "
273
"%(service)s on host %(host)s"
274
msgstr ""
275

  
276
#: vigiboard/controllers/silence.py:636
277
#, python-format
278
msgid "User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for host %(host)s"
279
msgstr ""
280

  
281
#: vigiboard/controllers/silence.py:647
282
#, python-format
283
msgid "The following silence rules have been successfully deleted: %s."
284
msgstr ""
285

  
286
#: vigiboard/controllers/silence.py:650
287
#, python-format
288
msgid "Silence rule #%s has been successfully deleted."
289
msgstr ""
138 290

  
139
#: vigiboard/controllers/plugins/date.py:63
291
#: vigiboard/controllers/plugins/date.py:38
140 292
msgid "Last occurrence"
141 293
msgstr ""
142 294

  
143
#: vigiboard/controllers/plugins/date.py:66
295
#: vigiboard/controllers/plugins/date.py:41
144 296
msgid "Between"
145 297
msgstr ""
146 298

  
147
#: vigiboard/controllers/plugins/date.py:67
148
#: vigiboard/controllers/plugins/date.py:76
299
#: vigiboard/controllers/plugins/date.py:42
300
#: vigiboard/controllers/plugins/date.py:51
149 301
#: vigiboard/controllers/plugins/groups.py:41
150 302
msgid "Choose"
151 303
msgstr "Auswählen"
152 304

  
153
#: vigiboard/controllers/plugins/date.py:75
305
#: vigiboard/controllers/plugins/date.py:50
154 306
msgid "And"
155 307
msgstr ""
156 308

  
......
166 318
msgid "High-Level Service"
167 319
msgstr ""
168 320

  
169
#: vigiboard/controllers/plugins/hostname.py:38
170
msgid "Host"
171
msgstr "Host"
172

  
173 321
#: vigiboard/controllers/plugins/output.py:38
174 322
msgid "Output"
175 323
msgstr "Ausgabe"
......
178 326
msgid "Priority"
179 327
msgstr "Priorität"
180 328

  
181
#: vigiboard/controllers/plugins/servicename.py:41
182
msgid "Service"
183
msgstr "Service"
184

  
185 329
#: vigiboard/controllers/plugins/status.py:53
186 330
msgid "All alerts"
187 331
msgstr ""
......
208 352
msgid "Acknowledgement Status"
209 353
msgstr "Bestätigungsstatus"
210 354

  
355
#. TRANSLATORS: Format de date et heure Python/JavaScript.
356
#. TRANSLATORS:
357
#. http://www.dynarch.com/static/jscalendar-1.0/doc/html/reference.html#node_sec_5.3.5
358
#. TRANSLATORS: http://docs.python.org/release/2.5/lib/module-time.html
359
#: vigiboard/lib/dateformat.py:35 vigiboard/lib/dateformat.py:58
360
#: vigiboard/lib/dateformat.py:70
361
#, python-format
362
msgid "%Y-%m-%d %I:%M:%S %p"
363
msgstr "%Y-%m-%d %I:%M:%S %p"
364

  
211 365
#: vigiboard/public/js/main.js:39
212 366
msgid "Search Event"
213 367
msgstr ""
......
221 375
msgid "Unable to save preferences"
222 376
msgstr ""
223 377

  
378
#: vigiboard/public/js/silence.js:63
379
msgid "Are you sure you want to delete this rule?"
380
msgstr ""
381

  
382
#: vigiboard/public/js/silence.js:64
383
msgid "Silence rule #{id}"
384
msgstr ""
385

  
386
#: vigiboard/public/js/silence.js:65
387
msgid "Delete this rule"
388
msgstr ""
389

  
390
#: vigiboard/public/js/silence.js:79
391
msgid "No"
392
msgstr ""
393

  
224 394
#: vigiboard/widgets/edit_event.py:34
225 395
msgid "No change"
226 396
msgstr "Keine Änderung"
......
281 451
msgid "Search"
282 452
msgstr "Suchen"
283 453

  
284
#~ msgid "From"
285
#~ msgstr "Von"
286

  
287
#~ msgid "To"
288
#~ msgstr "Bis"
289

  
vigiboard/i18n/en/LC_MESSAGES/vigiboard.po
1 1
# English translations for vigilo-vigiboard.
2
# Copyright (C) 2013 ORGANIZATION
2
# Copyright (C) 2014 ORGANIZATION
3 3
# This file is distributed under the same license as the vigilo-vigiboard
4 4
# project.
5
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
5
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
6 6
#
7 7
msgid ""
8 8
msgstr ""
9 9
"Project-Id-Version: vigilo-vigiboard 3.3\n"
10 10
"Report-Msgid-Bugs-To: contact@projet-vigilo.org\n"
11
"POT-Creation-Date: 2013-11-19 12:46+0100\n"
12
"PO-Revision-Date: 2013-11-19 12:46+0100\n"
11
"POT-Creation-Date: 2014-02-03 10:52+0100\n"
12
"PO-Revision-Date: 2014-02-03 10:52+0100\n"
13 13
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14
"Language-Team: en <LL@li.org>\n"
15 15
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
......
23 23
msgid "Vigilo has detected a breakdown on the following collector(s): %(list)s"
24 24
msgstr "Vigilo has detected a breakdown on the following collector(s): %(list)s"
25 25

  
26
#: vigiboard/controllers/root.py:88 vigiboard/controllers/root.py:97
27
#: vigiboard/controllers/root.py:578
26
#: vigiboard/controllers/root.py:89 vigiboard/controllers/root.py:99
27
#: vigiboard/controllers/root.py:582 vigiboard/controllers/silence.py:70
28 28
msgid "You need to be authenticated"
29 29
msgstr "You need to be authenticated"
30 30

  
31
#: vigiboard/controllers/root.py:100
31
#: vigiboard/controllers/root.py:102
32 32
msgid "You don't have access to VigiBoard"
33 33
msgstr "You don't have access to VigiBoard"
34 34

  
35
#: vigiboard/controllers/root.py:248 vigiboard/controllers/root.py:544
35
#: vigiboard/controllers/root.py:252 vigiboard/controllers/root.py:548
36 36
#: vigiboard/controllers/vigiboardrequest.py:474
37 37
msgid "Apply"
38 38
msgstr "Apply"
39 39

  
40
#: vigiboard/controllers/root.py:384
40
#: vigiboard/controllers/root.py:388
41 41
msgid "No masked event or access denied"
42 42
msgstr "No masked event or access denied"
43 43

  
44
#: vigiboard/controllers/root.py:442
44
#: vigiboard/controllers/root.py:446
45 45
msgid "No such event or access denied"
46 46
msgstr "No such event or access denied"
47 47

  
48
#: vigiboard/controllers/root.py:511
48
#: vigiboard/controllers/root.py:515
49 49
msgid "No such host/service"
50 50
msgstr "No such host/service"
51 51

  
52
#: vigiboard/controllers/root.py:534
52
#: vigiboard/controllers/root.py:538
53 53
msgid "No access to this host/service or no event yet"
54 54
msgstr "No access to this host/service or no event yet"
55 55

  
56
#: vigiboard/controllers/root.py:581
56
#: vigiboard/controllers/root.py:585
57 57
msgid "You don't have write access to VigiBoard"
58 58
msgstr "You don't have write access to VigiBoard"
59 59

  
60
#: vigiboard/controllers/root.py:604
60
#: vigiboard/controllers/root.py:608
61 61
msgid "No event has been selected"
62 62
msgstr "No event has been selected"
63 63

  
64
#: vigiboard/controllers/root.py:632
64
#: vigiboard/controllers/root.py:636
65 65
msgid ""
66 66
"Changes have occurred since the page was last displayed, your changes "
67 67
"HAVE NOT been saved."
......
69 69
"Changes have occurred since the page was last displayed, your changes "
70 70
"HAVE NOT been saved."
71 71

  
72
#: vigiboard/controllers/root.py:638
72
#: vigiboard/controllers/root.py:642
73 73
msgid "No access to this event"
74 74
msgstr "No access to this event"
75 75

  
76
#: vigiboard/controllers/root.py:645
76
#: vigiboard/controllers/root.py:649
77 77
msgid "You don't have administrative access to VigiBoard"
78 78
msgstr "You don't have administrative access to VigiBoard"
79 79

  
80
#: vigiboard/controllers/root.py:672
80
#: vigiboard/controllers/root.py:676
81 81
msgid "None"
82 82
msgstr "None"
83 83

  
84
#: vigiboard/controllers/root.py:673
84
#: vigiboard/controllers/root.py:677
85 85
msgid "Acknowledged"
86 86
msgstr "Acknowledged"
87 87

  
88
#: vigiboard/controllers/root.py:674
88
#: vigiboard/controllers/root.py:678
89 89
msgid "Acknowledged and closed"
90 90
msgstr "Acknowledged and closed"
91 91

  
92
#: vigiboard/controllers/root.py:695
92
#: vigiboard/controllers/root.py:699
93 93
#, python-format
94 94
msgid ""
95 95
"User \"%(user)s\" (%(address)s) changed the trouble ticket from "
......
98 98
"User \"%(user)s\" (%(address)s) changed the trouble ticket from "
99 99
"\"%(previous)s\" to \"%(new)s\" on event #%(idevent)d"
100 100

  
101
#: vigiboard/controllers/root.py:740
101
#: vigiboard/controllers/root.py:744
102 102
#, python-format
103 103
msgid "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d"
104 104
msgstr "User \"%(user)s\" (%(address)s) forcefully closed event #%(idevent)d"
105 105

  
106
#: vigiboard/controllers/root.py:773
106
#: vigiboard/controllers/root.py:777
107 107
#, python-format
108 108
msgid ""
109 109
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" "
......
112 112
"User \"%(user)s\" (%(address)s) changed the state from \"%(previous)s\" "
113 113
"to \"%(new)s\" on event #%(idevent)d"
114 114

  
115
#: vigiboard/controllers/root.py:785
115
#: vigiboard/controllers/root.py:789
116 116
msgid "Updated successfully"
117 117
msgstr "Updated successfully"
118 118

  
119
#: vigiboard/controllers/root.py:810
119
#: vigiboard/controllers/root.py:814
120 120
#, python-format
121 121
msgid "No such plugin '%s'"
122 122
msgstr "No such plugin '%s'"
123 123

  
124
#: vigiboard/controllers/root.py:852
124
#: vigiboard/controllers/root.py:856
125 125
msgid "No such incident or insufficient permissions"
126 126
msgstr "No such incident or insufficient permissions"
127 127

  
128
#: vigiboard/controllers/root.py:964
128
#: vigiboard/controllers/root.py:968
129 129
#, python-format
130 130
msgid "Next %(limit)s"
131 131
msgstr "Next %(limit)s"
132 132

  
133
#. TRANSLATORS: Format de date et heure Python/JavaScript.
134
#. TRANSLATORS:
135
#. http://www.dynarch.com/static/jscalendar-1.0/doc/html/reference.html#node_sec_5.3.5
136
#. TRANSLATORS: http://docs.python.org/release/2.5/lib/module-time.html
137
#: vigiboard/controllers/plugins/date.py:57 vigiboard/lib/dateformat.py:34
138
#: vigiboard/lib/dateformat.py:46
133
#: vigiboard/controllers/silence.py:73
134
msgid "Insufficient privileges for this action"
135
msgstr "Insufficient privileges for this action"
136

  
137
#: vigiboard/controllers/silence.py:172
139 138
#, python-format
140
msgid "%Y-%m-%d %I:%M:%S %p"
141
msgstr "%Y-%m-%d %I:%M:%S %p"
139
msgid "Another rule already exists for service '%s' on host '%s'."
140
msgstr "Another rule already exists for service '%s' on host '%s'."
141

  
142
#: vigiboard/controllers/silence.py:176
143
#, python-format
144
msgid "Another rule already exists for host '%s'."
145
msgstr "Another rule already exists for host '%s'."
146

  
147
#: vigiboard/controllers/silence.py:258
148
#: vigiboard/controllers/plugins/hostname.py:38
149
msgid "Host"
150
msgstr "Host"
151

  
152
#: vigiboard/controllers/silence.py:259
153
#: vigiboard/controllers/plugins/servicename.py:41
154
msgid "Service"
155
msgstr "Service"
156

  
157
#: vigiboard/controllers/silence.py:260
158
msgid "States"
159
msgstr "States"
160

  
161
#: vigiboard/controllers/silence.py:261
162
msgid "Last modification"
163
msgstr "Last modification"
164

  
165
#: vigiboard/controllers/silence.py:262
166
msgid "Author"
167
msgstr "Author"
168

  
169
#: vigiboard/controllers/silence.py:263
170
msgid "Comment"
171
msgstr "Comment"
172

  
173
#: vigiboard/controllers/silence.py:313 vigiboard/controllers/silence.py:412
174
#: vigiboard/controllers/silence.py:434 vigiboard/controllers/silence.py:583
175
#, python-format
176
msgid "An exception has been raised while querying the database: %s"
177
msgstr "An exception has been raised while querying the database: %s"
178

  
179
#: vigiboard/controllers/silence.py:317 vigiboard/controllers/silence.py:324
180
#: vigiboard/controllers/silence.py:438 vigiboard/controllers/silence.py:605
181
#, python-format
182
msgid "Silence rule #%s does not exist."
183
msgstr "Silence rule #%s does not exist."
184

  
185
#: vigiboard/controllers/silence.py:395
186
msgid "No state specified for the silence rule."
187
msgstr "No state specified for the silence rule."
188

  
189
#: vigiboard/controllers/silence.py:417
190
#, python-format
191
msgid "Host '%s' does not exist."
192
msgstr "Host '%s' does not exist."
193

  
194
#: vigiboard/controllers/silence.py:420
195
#, python-format
196
msgid "Service '%s' does not exist for host '%s'."
197
msgstr "Service '%s' does not exist for host '%s'."
198

  
199
#: vigiboard/controllers/silence.py:472
200
#, python-format
201
msgid "An exception has been raised while updating the database: %s"
202
msgstr "An exception has been raised while updating the database: %s"
203

  
204
#: vigiboard/controllers/silence.py:482
205
#, python-format
206
msgid ""
207
"User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for service "
208
"%(service)s on host %(host)s."
209
msgstr ""
210
"User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for service "
211
"%(service)s on host %(host)s."
212

  
213
#: vigiboard/controllers/silence.py:492
214
#, python-format
215
msgid ""
216
"Silence rule #%(id)s (host: %(host)s, service: %(service)s) has been "
217
"successfully updated."
218
msgstr ""
219
"Silence rule #%(id)s (host: %(host)s, service: %(service)s) has been "
220
"successfully updated."
221

  
222
#: vigiboard/controllers/silence.py:501
223
#, python-format
224
msgid "User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for host %(host)s."
225
msgstr "User %(user)s (IP: %(ip)s) updated silence rule #%(id)s for host %(host)s."
226

  
227
#: vigiboard/controllers/silence.py:509
228
#, python-format
229
msgid "Silence rule #%(id)s (host: %(host)s) has been successfully updated."
230
msgstr "Silence rule #%(id)s (host: %(host)s) has been successfully updated."
231

  
232
#: vigiboard/controllers/silence.py:518
233
#, python-format
234
msgid ""
235
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for service "
236
"%(service)s on host %(host)s."
237
msgstr ""
238
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for service "
239
"%(service)s on host %(host)s."
142 240

  
143
#: vigiboard/controllers/plugins/date.py:63
241
#: vigiboard/controllers/silence.py:528
242
#, python-format
243
msgid ""
244
"A new silence rule (#%(id)s) has been added for service \"%(service)s\" "
245
"on host \"%(host)s\"."
246
msgstr ""
247
"A new silence rule (#%(id)s) has been added for service \"%(service)s\" "
248
"on host \"%(host)s\"."
249

  
250
#: vigiboard/controllers/silence.py:536
251
#, python-format
252
msgid ""
253
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for host "
254
"%(host)s."
255
msgstr ""
256
"User %(user)s (IP: %(ip)s) added a silence rule (#%(id)s) for host "
257
"%(host)s."
258

  
259
#: vigiboard/controllers/silence.py:544
260
#, python-format
261
msgid "A new silence rule (#%(id)s) has been added for the host \"%(host)s\"."
262
msgstr "A new silence rule (#%(id)s) has been added for the host \"%(host)s\"."
263

  
264
#: vigiboard/controllers/silence.py:574
265
msgid "No silence rule id specified."
266
msgstr "No silence rule id specified."
267

  
268
#: vigiboard/controllers/silence.py:593
269
#, python-format
270
msgid "Error: the following silence rules do not exist: %s."
271
msgstr "Error: the following silence rules do not exist: %s."
272

  
273
#: vigiboard/controllers/silence.py:596
274
#, python-format
275
msgid "Error: silence rule #%s does not exist."
276
msgstr "Error: silence rule #%s does not exist."
277

  
278
#: vigiboard/controllers/silence.py:614
279
#, python-format
280
msgid "An exception has been raised while deleting the silence rules: %s"
281
msgstr "An exception has been raised while deleting the silence rules: %s"
282

  
283
#: vigiboard/controllers/silence.py:624
284
#, python-format
285
msgid ""
286
"User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for service "
287
"%(service)s on host %(host)s"
288
msgstr ""
289
"User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for service "
290
"%(service)s on host %(host)s"
291

  
292
#: vigiboard/controllers/silence.py:636
293
#, python-format
294
msgid "User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for host %(host)s"
295
msgstr "User %(user)s (IP: %(ip)s) deleted silence rule #%(id)s for host %(host)s"
296

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

Also available in: Unified diff