def event(self, idevent, page): """ Affichage de l'historique d'un événement brut. Pour accéder à cette page, l'utilisateur doit être authentifié. @param idevent: identifiant de l'événement brut souhaité. @type idevent: C{int} @param page: numéro de la page à afficher. @type page: C{int} Cette méthode permet de satisfaire l'exigence VIGILO_EXIG_VIGILO_BAC_0080. """ # Auto-supervision self.get_failures() user = get_current_user() events = VigiboardRequest(user, False) events.add_table( Event, events.items.c.hostname.label('hostname'), events.items.c.servicename.label('servicename'), ) events.add_join((EVENTSAGGREGATE_TABLE, \ EVENTSAGGREGATE_TABLE.c.idevent == Event.idevent)) events.add_join((CorrEvent, CorrEvent.idcorrevent == \ EVENTSAGGREGATE_TABLE.c.idcorrevent)) events.add_join((events.items, Event.idsupitem == events.items.c.idsupitem)) events.add_filter(Event.idevent == idevent) if events.num_rows() != 1: flash(_('No such event or access denied'), 'error') redirect('/') events.format_events(0, 1) events.generate_tmpl_context() history = events.format_history() # Pagination des résultats items_per_page = int(session.get('items_per_page', config['vigiboard_items_per_page'])) page = paginate.Page(history, page=page, items_per_page=items_per_page) event = events.req[0] return dict( idevent = idevent, hostname = event.hostname, servicename = event.servicename, plugins_data = {}, page = page, search_form = create_search_form, search = {}, fixed_search = {}, )
def update(self, id, last_modification, trouble_ticket, ack): """ Mise à jour d'un événement suivant les arguments passés. Cela peut être un changement de ticket ou un changement de statut. @param id: Le ou les identifiants des événements à traiter @param last_modification: La date de la dernière modification dont l'utilisateur est au courant. @param trouble_ticket: Nouveau numéro du ticket associé. @param ack: Nouvel état d'acquittement des événements sélectionnés. Cette méthode permet de satisfaire les exigences suivantes : - VIGILO_EXIG_VIGILO_BAC_0020, - VIGILO_EXIG_VIGILO_BAC_0060, - VIGILO_EXIG_VIGILO_BAC_0110. """ # On vérifie que des identifiants ont bien été transmis via # le formulaire, et on informe l'utilisateur le cas échéant. if id is None: flash(_('No event has been selected'), 'warning') raise redirect(request.environ.get('HTTP_REFERER', '/')) # On récupère la liste de tous les identifiants des événements # à mettre à jour. ids = [ int(i) for i in id.strip(',').split(',') ] user = get_current_user() events = VigiboardRequest(user) events.add_table( CorrEvent, Event, events.items.c.hostname, events.items.c.servicename, ) events.add_join((Event, CorrEvent.idcause == Event.idevent)) events.add_join((events.items, Event.idsupitem == events.items.c.idsupitem)) events.add_filter(CorrEvent.idcorrevent.in_(ids)) events.generate_request() idevents = [event[0].idcause for event in events.req] # Si des changements sont survenus depuis que la # page est affichée, on en informe l'utilisateur. last_modification = datetime.fromtimestamp(last_modification) cur_last_modification = get_last_modification_timestamp(idevents, None) if cur_last_modification and last_modification < cur_last_modification: flash(_('Changes have occurred since the page was last displayed, ' 'your changes HAVE NOT been saved.'), 'warning') raise redirect(request.environ.get('HTTP_REFERER', '/')) # Vérification que au moins un des identifiants existe et est éditable if not events.num_rows(): flash(_('No access to this event'), 'error') redirect('/') if ack == u'Forced': condition = Any( config.is_manager, has_permission('vigiboard-admin'), msg=l_("You don't have administrative access " "to VigiBoard")) try: condition.check_authorization(request.environ) except NotAuthorizedError, e: reason = unicode(e) flash(reason, 'error') raise redirect(request.environ.get('HTTP_REFERER', '/'))
def item(self, page, host, service, sort=None, order=None): """ Affichage de l'historique de l'ensemble des événements corrélés jamais ouverts sur l'hôte / service demandé. Pour accéder à cette page, l'utilisateur doit être authentifié. @param page: Numéro de la page à afficher. @type: C{int} @param host: Nom de l'hôte souhaité. @type: C{str} @param service: Nom du service souhaité @type: C{str} @param sort: Colonne de tri @type: C{str} or C{None} @param order: Ordre du tri (asc ou desc) @type: C{str} or C{None} Cette méthode permet de satisfaire l'exigence VIGILO_EXIG_VIGILO_BAC_0080. """ # Auto-supervision self.get_failures() idsupitem = SupItem.get_supitem(host, service) if not idsupitem: flash(_('No such host/service'), 'error') redirect('/') user = get_current_user() aggregates = VigiboardRequest(user, False, sort=sort, order=order) aggregates.add_table( CorrEvent, aggregates.items.c.hostname, aggregates.items.c.servicename, ) aggregates.add_join((Event, CorrEvent.idcause == Event.idevent)) aggregates.add_join((aggregates.items, Event.idsupitem == aggregates.items.c.idsupitem)) aggregates.add_filter(aggregates.items.c.idsupitem == idsupitem) # Pagination des résultats aggregates.generate_request() items_per_page = int(session.get('items_per_page', config['vigiboard_items_per_page'])) page = paginate.Page(aggregates.req, page=page, items_per_page=items_per_page) # Vérification qu'il y a au moins 1 événement qui correspond if not page.item_count: flash(_('No access to this host/service or no event yet'), 'error') redirect('/') # Ajout des formulaires et préparation # des données pour ces formulaires. ids_events = [event[0].idcause for event in page.items] tmpl_context.last_modification = \ mktime(get_last_modification_timestamp(ids_events).timetuple()) tmpl_context.edit_event_form = EditEventForm("edit_event_form", submit_text=_('Apply'), action=url('/update')) plugins_data = {} for plugin in dict(config['columns_plugins']): plugins_data[plugin] = {} return dict( hostname = host, servicename = service, plugins_data = plugins_data, page = page, sort = sort, order = order, event_edit_status_options = edit_event_status_options, search_form = create_search_form, search = {}, fixed_search = {}, )
def masked_events(self, idcorrevent, page): """ Affichage de la liste des événements bruts masqués d'un événement corrélé (événements agrégés dans l'événement corrélé). @param page: numéro de la page à afficher. @type page: C{int} @param idcorrevent: identifiant de l'événement corrélé souhaité. @type idcorrevent: C{int} """ # Auto-supervision self.get_failures() user = get_current_user() # Récupère la liste des événements masqués de l'événement # corrélé donné par idcorrevent. events = VigiboardRequest(user, False) events.add_table( Event, events.items.c.hostname, events.items.c.servicename, ) events.add_join((EVENTSAGGREGATE_TABLE, \ EVENTSAGGREGATE_TABLE.c.idevent == Event.idevent)) events.add_join((CorrEvent, CorrEvent.idcorrevent == \ EVENTSAGGREGATE_TABLE.c.idcorrevent)) events.add_join((events.items, Event.idsupitem == events.items.c.idsupitem)) events.add_filter(Event.idevent != CorrEvent.idcause) events.add_filter(CorrEvent.idcorrevent == idcorrevent) # Récupère l'instance de SupItem associé à la cause de # l'événement corrélé. Cette instance est utilisé pour # obtenir le nom d'hôte/service auquel la cause est # rattachée (afin de fournir un contexte à l'utilisateur). hostname = None servicename = None cause_supitem = DBSession.query( SupItem, ).join( (Event, Event.idsupitem == SupItem.idsupitem), (CorrEvent, Event.idevent == CorrEvent.idcause), ).filter(CorrEvent.idcorrevent == idcorrevent ).one() if isinstance(cause_supitem, LowLevelService): hostname = cause_supitem.host.name servicename = cause_supitem.servicename elif isinstance(cause_supitem, Host): hostname = cause_supitem.name # Pagination des résultats events.generate_request() items_per_page = int(session.get('items_per_page', config['vigiboard_items_per_page'])) page = paginate.Page(events.req, page=page, items_per_page=items_per_page) # Vérification que l'événement existe if not page.item_count: flash(_('No masked event or access denied'), 'error') redirect('/') return dict( idcorrevent = idcorrevent, hostname = hostname, servicename = servicename, plugins_data = {}, page = page, search_form = create_search_form, search = {}, fixed_search = {}, )
def index(self, page, sort=None, order=None, **search): """ Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée (page 1 par defaut), la liste des événements, rangés par ordre de prise en compte, puis de sévérité. Pour accéder à cette page, l'utilisateur doit être authentifié. @param page: Numéro de la page souhaitée, commence à 1 @type page: C{int} @param sort: Colonne de tri @type sort: C{str} or C{None} @param order: Ordre du tri (asc ou desc) @type order: C{str} or C{None} @param search: Dictionnaire contenant les critères de recherche. @type search: C{dict} Cette méthode permet de satisfaire les exigences suivantes : - VIGILO_EXIG_VIGILO_BAC_0040, - VIGILO_EXIG_VIGILO_BAC_0070, - VIGILO_EXIG_VIGILO_BAC_0100, """ # Auto-supervision self.get_failures() user = get_current_user() aggregates = VigiboardRequest(user, search=search, sort=sort, order=order) aggregates.add_table( CorrEvent, aggregates.items.c.hostname, aggregates.items.c.servicename ) aggregates.add_join((Event, CorrEvent.idcause == Event.idevent)) aggregates.add_contains_eager(CorrEvent.cause) aggregates.add_group_by(Event) aggregates.add_join((aggregates.items, Event.idsupitem == aggregates.items.c.idsupitem)) aggregates.add_order_by(asc(aggregates.items.c.hostname)) # Certains arguments sont réservés dans routes.util.url_for(). # On effectue les substitutions adéquates. # Par exemple: "host" devient "host_". reserved = ('host', 'anchor', 'protocol', 'qualified') for column in search.copy(): if column in reserved: search[column + '_'] = search[column] del search[column] # On ne garde que les champs effectivement renseignés. for column in search.copy(): if not search[column]: del search[column] # On sérialise les champs de type dict. def serialize_dict(dct, key): if isinstance(dct[key], dict): for subkey in dct[key]: serialize_dict(dct[key], subkey) dct['%s.%s' % (key, subkey)] = dct[key][subkey] del dct[key] elif isinstance(dct[key], datetime): dct[key] = dct[key].strftime(dateformat.get_date_format()) fixed_search = search.copy() for column in fixed_search.copy(): serialize_dict(fixed_search, column) # Pagination des résultats aggregates.generate_request() items_per_page = int(session.get('items_per_page', config['vigiboard_items_per_page'])) page = paginate.Page(aggregates.req, page=page, items_per_page=items_per_page) # Récupération des données des plugins plugins_data = {} plugins = dict(config['columns_plugins']) ids_events = [event[0].idcause for event in page.items] ids_correvents = [event[0].idcorrevent for event in page.items] for plugin in plugins: plugin_data = plugins[plugin].get_bulk_data(ids_correvents) if plugin_data: plugins_data[plugin] = plugin_data else: plugins_data[plugin] = {} # Ajout des formulaires et préparation # des données pour ces formulaires. tmpl_context.last_modification = \ mktime(get_last_modification_timestamp(ids_events).timetuple()) tmpl_context.edit_event_form = EditEventForm("edit_event_form", submit_text=_('Apply'), action=url('/update')) if request.response_type == 'text/csv': # Sans les 2 en-têtes suivants qui désactivent la mise en cache, # Internet Explorer refuse de télécharger le fichier CSV (cf. #961). response.headers['Pragma'] = 'public' # Nécessaire pour IE. response.headers['Cache-Control'] = 'max-age=0' # Nécessaire pour IE. response.headers["Content-Type"] = "text/csv" response.headers['Content-Disposition'] = \ 'attachment;filename="alerts.csv"' return export_csv.export(page, plugins_data) return dict( hostname = None, servicename = None, plugins_data = plugins_data, page = page, sort = sort, order = order, event_edit_status_options = edit_event_status_options, search_form = create_search_form, search = search, fixed_search = fixed_search, )