Beispiel #1
0
    def supitemgroup(self, supitemgroup, partial, noCache):
        """
        Auto-compléteur pour les noms des groupes d'éléments supervisés.

        @param supitemgroup: Motif qui doit apparaître dans le nom
            du groupe d'éléments supervisés.
        @type supitemgroup: C{unicode}
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms de groupes d'élements supervisés correspondant
            au motif donné et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        supitemgroup = sql_escape_like(supitemgroup)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            supitemgroup += "%"

        supitemgroups = DBSession.query(SupItemGroup.name).distinct().filter(SupItemGroup.name.ilike(supitemgroup))

        if not config.is_manager.is_met(request.environ):
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
            supitemgroups = supitemgroups.filter(SupItemGroup.idgroup.in_(user_groups))

        supitemgroups = supitemgroups.all()
        return dict(results=[s.name for s in supitemgroups])
Beispiel #2
0
def get_service(idservice, service_type, idhost=None):
    """
    Retourne un service à partir de son ID ou de son nom. Si le service est un
    service de bas niveau (C{tables.LowLevelService}), il faut aussi fournir un
    identifiant d'hôte (ID ou nom).

    @param idservice: l'identifiant du service à récupérer, ou son nom
    @type  idservice: C{int} ou C{str}
    @param service_type: le type de service à récupérer
    @type  service_type: C{str}: C{lls} ou C{hls}
    @param idhost: l'identifiant de l'hôte associé au service, ou son nom
    @type  idhost: C{int} ou C{str}
    """
    try:
        idservice = int(idservice)
    except ValueError:
        # on a reçu un nom de service
        if service_type == "lls":
            if idhost is None:
                raise HTTPNotFound("Can't find the host, you must use " "the numeric service ID")
            host = get_host(idhost)
            service = tables.LowLevelService.by_host_service_name(host.name, idservice)
        elif service_type == "hls":
            service = tables.HighLevelService.by_service_name(idservice)
    else:
        service = DBSession.query(tables.Service).get(idservice)
    if service is None:
        raise HTTPNotFound("Can't find the service: %s" % idservice)
    # ACLs
    user = get_current_user()
    if not user:
        raise HTTPForbidden("You must be logged in")
    if not service.is_allowed_for(user):
        raise HTTPForbidden("Access to this service is forbidden")
    return service
Beispiel #3
0
    def plugin_json(self, idcorrevent, plugin_name, *arg, **krgv):
        """
        Permet de récupérer la valeur d'un plugin associée à un CorrEvent
        donné via JSON.
        """

        # Vérification de l'existence du plugin
        plugins = dict(config['columns_plugins'])
        if plugin_name not in plugins:
            raise HTTPNotFound(_("No such plugin '%s'") % plugin_name)

        # Récupération de la liste des évènements corrélés
        events = DBSession.query(CorrEvent.idcorrevent)

        # Filtrage des évènements en fonction des permissions de
        # l'utilisateur (s'il n'appartient pas au groupe 'managers')
        if not config.is_manager.is_met(request.environ):
            user = get_current_user()

            events = events.join(
                (Event, Event.idevent == CorrEvent.idcause),
            ).outerjoin(
                (LowLevelService, LowLevelService.idservice == Event.idsupitem),
            ).join(
                (SUPITEM_GROUP_TABLE,
                    or_(
                        SUPITEM_GROUP_TABLE.c.idsupitem == \
                            LowLevelService.idhost,
                        SUPITEM_GROUP_TABLE.c.idsupitem == \
                            Event.idsupitem,
                    )
                ),
            ).join(
                (GroupHierarchy,
                    GroupHierarchy.idchild == SUPITEM_GROUP_TABLE.c.idgroup),
            ).join(
                (DataPermission,
                    DataPermission.idgroup == GroupHierarchy.idparent),
            ).join(
                (USER_GROUP_TABLE,
                    USER_GROUP_TABLE.c.idgroup == DataPermission.idusergroup),
            ).filter(USER_GROUP_TABLE.c.username == user.user_name)

        # Filtrage des évènements en fonction
        # de l'identifiant passé en paramètre
        events = events.filter(CorrEvent.idcorrevent == idcorrevent).count()

        # Pas d'événement ou permission refusée. On ne distingue pas
        # les 2 cas afin d'éviter la divulgation d'informations.
        if events == 0:
            raise HTTPNotFound(_('No such incident or insufficient '
                                'permissions'))

        # L'évènement existe bien, et l'utilisateur dispose
        # des permissions appropriées. On fait alors appel au
        # plugin pour récupérer les informations à retourner.
        return plugins[plugin_name].get_json_data(idcorrevent, *arg, **krgv)
Beispiel #4
0
    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 = {},
        )
Beispiel #5
0
    def create_or_modify(
            self,
            states,
            host,
            service=None,
#            start=time.time(),
#            end=time.time(),
            comment=None,
            idsilence=None):
        """
        Ajoute une règle de mise en silence d'un hôte/service,
        ou en modifie une déjà existante.

        @param states: (optionnel) Liste des états concernés par la règle.
        @type  states: C{list} of C{unicode}
        @param host: Nom de l'hôte sur lequel porte la règle.
        @type  host: C{unicode}
        @param service: (optionnel) Nom du service sur lequel
            porte la règle.
        @type  service: C{unicode}
#        @param start: Début de la mise en silence planifiée.
#        @type  start: C{str}
#        @param end: Fin de la mise en silence planifiée.
#        @type  end: C{str}
        @param comment: (optionnel) Commentaire accompagnant la règle.
        @type  comment: C{unicode}
        @param idsilence: (optionnel) Identifiant de la règle dans le cas d'une
            mise à jour.
        @type  idsilence: C{int}
        """

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

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

        # On récupère l'identifiant de l'item (hôte
        # ou service) concerné par la mise en silence.
        idsupitem = SupItem.get_supitem(host, service)
        if idsupitem:
            try:
                supitem = DBSession.query(SupItem
                    ).filter(SupItem.idsupitem == idsupitem).one()
            except InvalidRequestError, e:
                msg = _('An exception has been raised while ' \
                        'querying the database: %s') % str(e)
                self.handle_error_message(msg)
Beispiel #6
0
    def service(self, service, host, partial, noCache):
        """
        Auto-compléteur pour les noms des services d'un hôte.

        @param host: Nom d'hôte (optionnel) sur lequel s'applique
            l'autocomplétion.
        @type  host: C{unicode}
        @param service: Motif qui doit apparaître dans le nom de service.
        @type  service: C{unicode}
        @note: Les caractères '?' et '*' peuvent être utilisés dans
            le paramètre L{service} pour remplacer un caractère quelconque
            ou une chaîne de caractères, respectivement.
            Ex: 'ho?t*' permet de récupérer 'host', 'honte' et 'hostile',
            mais pas 'hote' ou 'hopital'.
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms de services configurés sur L{host} (ou sur n'importe
            quel hôte si L{host} vaut None), correspondant au motif donné
            et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        service = sql_escape_like(service)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            service += "%"

        hostgroup = SUPITEM_GROUP_TABLE.alias()
        servicegroup = SUPITEM_GROUP_TABLE.alias()
        services = (
            DBSession.query(LowLevelService.servicename)
            .distinct()
            .outerjoin(
                (Host, Host.idhost == LowLevelService.idhost),
                (hostgroup, hostgroup.c.idsupitem == Host.idhost),
                (servicegroup, servicegroup.c.idsupitem == LowLevelService.idservice),
            )
            .filter(LowLevelService.servicename.ilike(service))
            .order_by(LowLevelService.servicename)
        )

        if not config.is_manager.is_met(request.environ):
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
            services = services.filter(
                or_(hostgroup.c.idgroup.in_(user_groups), servicegroup.c.idgroup.in_(user_groups))
            )

        if host:
            services = services.filter(Host.name == host)

        services = services.all()
        return dict(results=[s.servicename for s in services])
Beispiel #7
0
 def _get_allowed_groups(self):
     """
     @return: liste des ID des groupes autorisés pour l'utilisateur courant
     @rtype:  liste de C{int}
     """
     user = get_current_user()
     #user = tables.User.by_user_name(u"editor") # debug
     if not user:
         raise HTTPForbidden("You must be logged in")
     allowed_groups = None
     if self.type == "map":
         allowed_groups = user.mapgroups(only_id=True)
     elif self.type == "supitem":
         allowed_groups = [ g[0] for g in user.supitemgroups() ]
     return allowed_groups
Beispiel #8
0
    def get_root_groups(self):
        """
        Retourne tous les groupes racines (c'est à dire n'ayant
        aucun parent) d'hôtes auquel l'utilisateur a accès.

        @return: Un dictionnaire contenant la liste de ces groupes.
        @rtype : C{dict} of C{list} of C{dict} of C{mixed}
        """

        # On récupère tous les groupes qui ont un parent.
        children = DBSession.query(
            SupItemGroup,
        ).distinct(
        ).join(
            (GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup)
        ).filter(GroupHierarchy.hops > 0)

        # Ensuite on les exclut de la liste des groupes,
        # pour ne garder que ceux qui sont au sommet de
        # l'arbre et qui constituent nos "root groups".
        root_groups = DBSession.query(
            SupItemGroup,
        ).except_(children
        ).order_by(SupItemGroup.name)

        # On filtre ces groupes racines afin de ne
        # retourner que ceux auquels l'utilisateur a accès
        user = get_current_user()
        if not config.is_manager.is_met(request.environ):
            root_groups = root_groups.join(
                (GroupHierarchy,
                    GroupHierarchy.idparent == SupItemGroup.idgroup),
                (DataPermission,
                    DataPermission.idgroup == GroupHierarchy.idchild),
                (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
                    DataPermission.idusergroup),
            ).filter(USER_GROUP_TABLE.c.username == user.user_name)

        groups = []
        for group in root_groups.all():
            groups.append({
                'id'   : group.idgroup,
                'name' : group.name,
                'type' : "group",
            })

        return dict(groups=groups, items=[])
Beispiel #9
0
def check_map_access(m):
    """
    Vérifie que l'utilisateur courant a bien accès à la carte donnée en
    argument

    @param m: carte à tester
    @type  m: C{tables.Map}
    """
    user = get_current_user()
    # user = tables.User.by_user_name(u"editor") # debug
    if not user:
        raise HTTPForbidden("You must be logged in")
    allowed_mapgroups = user.mapgroups(only_id=True, only_direct=True)
    for mapgroup in m.groups:
        if mapgroup.idgroup in allowed_mapgroups:
            return True
    raise HTTPForbidden("Access denied to map %s" % m.idmap)
Beispiel #10
0
    def host(self, host, partial, noCache):
        """
        Auto-compléteur pour les noms d'hôtes.

        @param host: Motif qui doit apparaître dans le nom de l'hôte.
        @type  host: C{unicode}
        @note: Les caractères '?' et '*' peuvent être utilisés dans
            le paramètre L{host} pour remplacer un caractère quelconque
            ou une chaîne de caractères, respectivement.
            Ex: 'ho?t*' permet de récupérer 'host', 'honte' et 'hostile',
            mais pas 'hote' ou 'hopital'.
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms d'hôtes correspondant au motif donné en entrée
            et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        host = sql_escape_like(host)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            host += "%"

        hostgroup = SUPITEM_GROUP_TABLE.alias()
        servicegroup = SUPITEM_GROUP_TABLE.alias()
        hostnames = (
            DBSession.query(Host.name)
            .distinct()
            .outerjoin(
                (hostgroup, hostgroup.c.idsupitem == Host.idhost),
                (LowLevelService, LowLevelService.idhost == Host.idhost),
                (servicegroup, servicegroup.c.idsupitem == LowLevelService.idservice),
            )
            .filter(Host.name.ilike(host))
            .order_by(Host.name)
        )

        if not config.is_manager.is_met(request.environ):
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
            hostnames = hostnames.filter(
                or_(hostgroup.c.idgroup.in_(user_groups), servicegroup.c.idgroup.in_(user_groups))
            )

        hostnames = hostnames.all()
        return dict(results=[h.name for h in hostnames])
Beispiel #11
0
 def get_all(self):
     # pylint:disable-msg=C0111,R0201
     user = get_current_user()
     #user = tables.User.by_user_name(u"editor") # debug
     if not user:
         raise HTTPForbidden("You must be logged in")
     mapgroups = user.mapgroups(only_id=False, only_direct=True)
     result = []
     for mapgroup in mapgroups:
         for m in mapgroup.maps:
             if m.idmap in [mr["id"] for mr in result]:
                 continue # Déjà ajouté
             result.append({
                 "id": m.idmap,
                 "href": tg.url("/api/v%s/maps/%s" % (self.apiver, m.idmap)),
                 "title": m.title,
                 })
     return dict(maps=result)
Beispiel #12
0
    def graph(self, graphname, host, partial, noCache):
        """
        Auto-compléteur pour les noms des graphes.

        @param graphname: Motif qui doit apparaître dans le nom du graphe.
        @type graphname: C{unicode}
        @param host: Nom de l'hôte auquel le graphe doit être rattaché.
        @type host: C{unicode}
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms des graphes portant sur L{host}, correspondant
            au motif donné et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        graphname = sql_escape_like(graphname)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            graphname += "%"

        graphs = (
            DBSession.query(Graph.name)
            .distinct()
            .join(
                (GRAPH_PERFDATASOURCE_TABLE, GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
                (PerfDataSource, PerfDataSource.idperfdatasource == GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
                (Host, Host.idhost == PerfDataSource.idhost),
            )
            .filter(Graph.name.ilike(graphname))
            .filter(Host.name == host)
            .order_by(Graph.name)
        )

        if not config.is_manager.is_met(request.environ):
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
            graphs = graphs.join((SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost)).filter(
                SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups)
            )

        graphs = graphs.all()
        return dict(results=[g.name for g in graphs])
Beispiel #13
0
 def get_one(self, idgraph):
     # pylint:disable-msg=C0111,R0201
     graph = DBSession.query(Graph).get(idgraph)
     if not graph:
         raise HTTPNotFound("Can't find graph %s" % idgraph)
     # ACLs
     user = get_current_user()
     # user = tables.User.by_user_name(u"editor") # debug
     for pds in graph.perfdatasources:
         if not pds.host.is_allowed_for(user):
             raise HTTPForbidden("Access denied to graphs on host %s" % pds.host.name)
     result = {
         "id": graph.idgraph,
         "href": tg.url("/api/v%s/graphs/%s" % (self.apiver, graph.idgraph)),
         "name": graph.name,
         "template": graph.template,
         "vlabel": graph.vlabel,
     }
     groups = []
     for group in graph.groups:
         groups.append(
             {
                 "id": group.idgroup,
                 "name": group.name,
                 "href": tg.url("/api/v%s/graphgroups/%s" % (self.apiver, group.idgroup)),
             }
         )
     result["groups"] = groups
     datasources = []
     for pds in graph.perfdatasources:
         datasources.append(
             {
                 "id": pds.idperfdatasource,
                 "name": pds.name,
                 "href": tg.url(
                     "/api/v%s/host/%s/perfdatasources/%s" % (self.apiver, pds.idhost, pds.idperfdatasource)
                 ),
             }
         )
     result["perfdatasources"] = datasources
     return dict(graph=result)
Beispiel #14
0
    def searchHost(self, query):
        """
        Affiche les résultats de la recherche par nom d'hôte.
        La requête de recherche (C{query}) correspond à un préfixe
        qui sera recherché dans le nom d'hôte. Ce préfixe peut
        contenir les caractères '*' et '?' qui agissent comme des
        "jokers".

        @keyword query: Prefixe de recherche sur les noms d'hôtes
        @type    query: C{unicode}
        """
        if not query:
            redirect("searchHostForm")
            return

        query = sql_escape_like(query.strip())
        user = get_current_user()
        if user is None:
            return dict(items=[])

        # Récupère les hôtes auxquels l'utilisateur a réellement accès.
        hosts = DBSession.query(
                Host.name,
            ).distinct(
            ).join(
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
                    Host.idhost),
            ).filter(Host.name.like(query + u'%')
            ).order_by(Host.name.asc(),)

        # Les managers ont accès à tout.
        # Les autres ont un accès restreint.
        if not config.is_manager.is_met(request.environ):
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
            hosts = hosts.join(
                    (GroupHierarchy, GroupHierarchy.idchild == \
                        SUPITEM_GROUP_TABLE.c.idgroup)
                ).filter(GroupHierarchy.idparent.in_(supitemgroups))

        return dict(hosts=[h.name for h in hosts])
Beispiel #15
0
    def hls(self, service, partial, noCache):
        """
        Auto-compléteur pour les noms des services de haut niveau.

        @param service: Motif qui doit apparaître dans le nom de service.
        @type  service: C{unicode}
        @note: Les caractères '?' et '*' peuvent être utilisés dans
            le paramètre L{service} pour remplacer un caractère quelconque
            ou une chaîne de caractères, respectivement.
            Ex: 'ho?t*' permet de récupérer 'host', 'honte' et 'hostile',
            mais pas 'hote' ou 'hopital'.
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms des services de haut niveau correspondant au motif
            donné et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        service = sql_escape_like(service)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            service += "%"

        services = (
            DBSession.query(HighLevelService.servicename)
            .distinct()
            .filter(HighLevelService.servicename.ilike(service))
            .order_by(HighLevelService.servicename)
        )

        #        if not config.is_manager.is_met(request.environ):
        #            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
        #            services = services.join(
        #                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
        #                                            HighLevelService.idservice),
        #                ).filter(SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups))

        services = services.all()
        return dict(results=[s.servicename for s in services])
Beispiel #16
0
    def perfdatasource(self, ds, host, partial, noCache):
        """
        Auto-compléteur pour les noms des indicateurs de performance.

        @param ds: Motif qui doit apparaître dans le nom de l'indicateur.
        @type ds: C{unicode}
        @param host: Nom de l'hôte auquel l'indicateur doit être rattaché.
        @type host: C{unicode}
        @return: Un dictionnaire dont la clé 'results' contient la liste
            des noms des indicateurs de supervision sur L{host} correspondant
            au motif donné et auxquels l'utilisateur a accès.
        @rtype: C{dict}
        """
        ds = sql_escape_like(ds)
        user = get_current_user()
        if not user:
            return dict(results=[])

        if partial:
            ds += "%"

        perfdatasources = (
            DBSession.query(PerfDataSource.name)
            .distinct()
            .join((Host, Host.idhost == PerfDataSource.idhost))
            .filter(PerfDataSource.name.ilike(ds))
            .filter(Host.name == host)
            .order_by(PerfDataSource.name)
        )

        if not config.is_manager.is_met(request.environ):
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
            perfdatasources = perfdatasources.join(
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost)
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups))

        perfdatasources = perfdatasources.all()
        return dict(results=[ds.name for ds in perfdatasources])
Beispiel #17
0
def get_host(idhost):
    """
    Retourne un hôte (C{tables.Host}) à partir de son ID ou de son nom

    @param idhost: l'identifiant de l'hôte
    @type  idhost: C{int} ou C{str}
    """
    try:
        idhost = int(idhost)
    except ValueError:
        host = tables.Host.by_host_name(idhost)
    else:
        host = DBSession.query(tables.Host).get(idhost)
    if host is None:
        raise HTTPNotFound("Can't find the host: %s" % idhost)
    # ACLs
    user = get_current_user()
    # user = tables.User.by_user_name(u"editor") # debug
    if not user:
        raise HTTPForbidden("You must be logged in")
    if not host.is_allowed_for(user):
        raise HTTPForbidden("Access to this host is forbidden")
    return host
Beispiel #18
0
def get_all_services(model_class):
    """
    Retourne tous les services auxquels l'utilisateur à accès, suivant le type
    demandé en argument.

    @param model_class: la classe du modèle correspondante au type de service
        demandé
    @type  model_class: sous-classe de C{tables.Service}
    """
    user = get_current_user()
    # user = tables.User.by_user_name(u"editor") # debug
    if not user:
        raise HTTPForbidden("You must be logged in")
    servicegroup = tables.secondary_tables.SUPITEM_GROUP_TABLE.alias()
    services = (
        DBSession.query(model_class)
        .distinct()
        .outerjoin((servicegroup, servicegroup.c.idsupitem == model_class.idservice))
    )
    # ACLs
    if not tg.config.is_manager.is_met(tg.request.environ):
        user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
        services = services.filter(servicegroup.c.idgroup.in_(user_groups))
    return services.all()
Beispiel #19
0
def get_all_hosts():
    """
    Retourne tous les hôtes (C{tables.Host}) auxquels l'utilisateur à accès
    """
    user = get_current_user()
    # user = tables.User.by_user_name(u"editor") # debug
    if not user:
        raise HTTPForbidden("You must be logged in")
    hostgroup = tables.secondary_tables.SUPITEM_GROUP_TABLE.alias()
    servicegroup = tables.secondary_tables.SUPITEM_GROUP_TABLE.alias()
    hosts = (
        DBSession.query(tables.Host)
        .distinct()
        .outerjoin(
            (hostgroup, hostgroup.c.idsupitem == tables.Host.idhost),
            (tables.LowLevelService, tables.LowLevelService.idhost == tables.Host.idhost),
            (servicegroup, servicegroup.c.idsupitem == tables.LowLevelService.idservice),
        )
    )
    # ACLs
    if not tg.config.is_manager.is_met(tg.request.environ):
        user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
        hosts = hosts.filter(or_(hostgroup.c.idgroup.in_(user_groups), servicegroup.c.idgroup.in_(user_groups)))
    return hosts.all()
Beispiel #20
0
    def graphtree(self, host_id=None, parent_id=None, offset=0, noCache=None):
        """
        Affiche un étage de l'arbre de sélection
        des graphes et groupes de graphes.

        @param parent_id: identifiant du groupe de graphes parent
        @type  parent_id: C{int} or None
        """

        # Si l'identifiant de l'hôte n'est pas spécifié, on
        # retourne un dictionnaire contenant deux listes vides
        if host_id is None:
            return dict(groups = [], graphs=[])

        # On vérifie les permissions sur l'hôte
        # TODO: Utiliser un schéma de validation
        host_id = int(host_id)
        host = DBSession.query(Host
            ).filter(Host.idhost == host_id
            ).first()
        if host is None:
            return dict(groups = [], graphs=[])
        user = get_current_user()
        if not host.is_allowed_for(user):
            return dict(groups = [], graphs=[])

        # On récupère la liste des groupes de graphes associés à l'hôte
        host_graph_groups = DBSession.query(
            GraphGroup
        ).distinct(
        ).join(
            (GRAPH_GROUP_TABLE, \
                GRAPH_GROUP_TABLE.c.idgroup == GraphGroup.idgroup),
            (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
            (GRAPH_PERFDATASOURCE_TABLE, \
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
            (PerfDataSource, PerfDataSource.idperfdatasource == \
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
            (SUPITEM_GROUP_TABLE, \
                SUPITEM_GROUP_TABLE.c.idsupitem == PerfDataSource.idhost),
        ).filter(PerfDataSource.idhost == host_id
        ).order_by(GraphGroup.name.asc()
        ).all()

        # Si l'identifiant du groupe parent n'est pas spécifié,
        # on récupère la liste des groupes de graphes racines.
        if parent_id is None:
            graph_groups = GraphGroup.get_top_groups()

        # Sinon on récupère la liste des graphes dont le
        # groupe passé en paramètre est le parent direct
        else:
            # TODO: Utiliser un schéma de validation
            parent_id = int(parent_id)
            graph_groups = DBSession.query(
                GraphGroup
            ).join(
                (GroupHierarchy, GroupHierarchy.idchild == \
                    GraphGroup.idgroup),
            ).filter(GroupHierarchy.hops == 1
            ).filter(GroupHierarchy.idparent == parent_id
            ).order_by(GraphGroup.name.asc()
            ).all()

        # On réalise l'intersection des deux listes
        groups = []
        for gg in graph_groups:
            if gg in host_graph_groups:
                groups.append({
                    'id'   : gg.idgroup,
                    'name' : gg.name,
                    'type' : "group",
                })

        # On récupère la liste des graphes appartenant au
        # groupe dont l'identifiant est passé en paramètre
        graphs = []
        if parent_id:
            db_graphs = DBSession.query(
                Graph.idgraph,
                Graph.name,
            ).distinct(
            ).join(
                (GRAPH_GROUP_TABLE,
                    GRAPH_GROUP_TABLE.c.idgraph == Graph.idgraph),
                (GRAPH_PERFDATASOURCE_TABLE,
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
                (PerfDataSource,
                    PerfDataSource.idperfdatasource == \
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
            ).filter(GRAPH_GROUP_TABLE.c.idgroup == parent_id
            ).filter(PerfDataSource.idhost == host_id
            ).order_by(Graph.name.asc())
            for graph in db_graphs.all():
                graphs.append({
                    'id'   : graph.idgraph,
                    'name' : graph.name,
                    'type' : "item",
                })

        return dict(groups=groups, items=graphs)
Beispiel #21
0
    def hosttree(self, parent_id=None, onlytype="", offset=0, noCache=None):
        """
        Affiche un étage de l'arbre de
        sélection des hôtes et groupes d'hôtes.

        @param parent_id: identifiant du groupe d'hôte parent
        @type  parent_id: C{int} or None
        """

        # Si l'identifiant du groupe parent n'est pas
        # spécifié, on retourne la liste des groupes racines,
        # fournie par la méthode get_root_hosts_groups.
        if parent_id is None:
            return self.get_root_host_groups()

        # TODO: Utiliser un schéma de validation
        parent_id = int(parent_id)
        offset = int(offset)

        # On vérifie si le groupe parent fait partie des
        # groupes auxquel l'utilisateur a accès, et on
        # retourne une liste vide dans le cas contraire
        is_manager = config.is_manager.is_met(request.environ)
        if not is_manager:
            direct_access = False
            user = get_current_user()

            # On calcule la distance de ce groupe par rapport aux groupes
            # sur lesquels l'utilisateur a explicitement les permissions.
            #
            # La distance est définie ainsi :
            # 0 : l'utilisateur a des droits explicites sur ce groupe.
            # > 0 : l'utilisateur a accès implicitement au groupe.
            # < 0 : l'utilisateur n'a pas d'accès (il peut juste parcourir
            #       ce groupe)
            #
            # Il faut 2 étapes pour trouver la distance. La 1ère essaye
            # de trouver une distance >= 0, la 2ème une distance <= 0.

            # Distance positive.
            distance = DBSession.query(
                    functions.max(GroupHierarchy.hops)
                ).join(
                    (Group, Group.idgroup == GroupHierarchy.idparent),
                    (DataPermission,
                        DataPermission.idgroup == Group.idgroup),
                    (UserGroup,
                        UserGroup.idgroup == DataPermission.idusergroup),
                    (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
                        UserGroup.idgroup),
                ).filter(USER_GROUP_TABLE.c.username == user.user_name
                ).filter(Group.grouptype == u'supitemgroup'
                ).filter(GroupHierarchy.idchild == parent_id
                ).scalar()

            if distance is None:
                # Distance négative.
                distance = DBSession.query(
                        functions.max(GroupHierarchy.hops)
                    ).join(
                        (Group, Group.idgroup == GroupHierarchy.idchild),
                        (DataPermission,
                            DataPermission.idgroup == Group.idgroup),
                        (UserGroup,
                            UserGroup.idgroup == DataPermission.idusergroup),
                        (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
                            UserGroup.idgroup),
                    ).filter(USER_GROUP_TABLE.c.username == user.user_name
                    ).filter(Group.grouptype == u'supitemgroup'
                    ).filter(GroupHierarchy.idparent == parent_id
                    ).scalar()
                if distance is not None:
                    distance = -distance

            if distance is None:
                # Pas d'accès à ce groupe.
                return dict(groups = [], items = [])

            direct_access = distance >= 0

        limit = int(config.get("max_menu_entries", 20))
        result = {"groups": [], "items": []}

        if not onlytype or onlytype == "group":
            # On récupère la liste des groupes dont
            # l'identifiant du parent est passé en paramètre
            gh1 = aliased(GroupHierarchy, name='gh1')
            gh2 = aliased(GroupHierarchy, name='gh2')

            db_groups = DBSession.query(
                SupItemGroup
            ).options(lazyload('_path_obj')
            ).distinct(
            ).join(
                (gh1, gh1.idchild == SupItemGroup.idgroup),
            ).filter(gh1.hops == 1
            ).filter(gh1.idparent == parent_id
            ).order_by(SupItemGroup.name.asc())

            if not is_manager and not direct_access:
                # On ne doit afficher que les fils du groupe <parent_id>
                # tels que l'utilisateur a accès explicitement à l'un
                # des fils de l'un de ces groupes.
                db_groups = db_groups.join(
                        (gh2, gh2.idparent == gh1.idchild),
                        (DataPermission,
                            DataPermission.idgroup == gh2.idchild),
                        (UserGroup,
                            UserGroup.idgroup == DataPermission.idusergroup),
                        (USER_GROUP_TABLE,
                            USER_GROUP_TABLE.c.idgroup == UserGroup.idgroup),
                    ).filter(USER_GROUP_TABLE.c.username == user.user_name)

            num_children_left = db_groups.count() - offset
            if offset:
                result["continued_from"] = offset
                result["continued_type"] = "group"
            all_groups = db_groups.limit(limit).offset(offset).all()
            for group in all_groups:
                result["groups"].append({
                    'id'   : group.idgroup,
                    'name' : group.name,
                    'type' : "group",
                })
            if num_children_left > limit:
                result["groups"].append({
                    'name': _("Next %(limit)s") % {"limit": limit},
                    'offset': offset + limit,
                    'parent_id': parent_id,
                    'type': 'continued',
                    'for_type': 'group',
                })

        # On récupère la liste des hôtes appartenant au
        # groupe dont l'identifiant est passé en paramètre
        if ((not onlytype or onlytype == "item")
                and (is_manager or direct_access)):
            db_hosts = DBSession.query(
                Host.idhost,
                Host.name,
            ).join(
                (SUPITEM_GROUP_TABLE,
                    SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost
                    ),
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup == parent_id
            ).order_by(Host.name.asc())
            num_children_left = db_hosts.count() - offset
            if offset:
                result["continued_from"] = offset
                result["continued_type"] = "item"
            all_hosts = db_hosts.limit(limit).offset(offset).all()
            for host in all_hosts:
                result["items"].append({
                    'id'   : host.idhost,
                    'name' : host.name,
                    'type' : "item",
                })
            if num_children_left > limit:
                result["items"].append({
                    'name': _("Next %(limit)s") % {"limit": limit},
                    'offset': offset + limit,
                    'parent_id': parent_id,
                    'type': 'continued',
                    'for_type': 'item',
                })

        return result
Beispiel #22
0
    def fullHostPage(self, host, start=None, duration=86400):
        """
        Affichage de l'ensemble des graphes associes a un hote
        * d apres les donnees RRD
        * avec une date-heure de debut
        * pour une plage de temps

        @param host : hôte
        @type host : C{str}
        @param start : date-heure de debut des donnees
        @type start : C{str}
        @param duration : plage de temps des données. Parametre optionnel,
            initialisé a 86400 = plage de 1 jour.
        @type duration : C{str}

        @return: page avec les images des graphes et boutons de deplacement
            dans le temps
        @rtype: page html
        """
        if start is None:
            start = int(time.time()) - int(duration)
        else:
            start = int(start)
        duration = int(duration)

        user = get_current_user()
        if user is None:
            return dict(host=host, start=start, duration=duration,
                        presets=self.presets, graphs=[])

        # Vérification des permissions de l'utilisateur sur l'hôte.
        if not config.is_manager.is_met(request.environ):
            # Récupération des groupes auxquels l'utilisateur a accès.
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]

            # On vérifie que l'hôte en question existe bel et bien.
            host_obj = Host.by_host_name(host)
            if not host_obj:
                message = _('No such host "%s"') % host
                LOGGER.warning(message)
                raise http_exc.HTTPNotFound(message)

            # Récupération des groupes dont l'hôte fait partie
            hostgroups = [g.idgroup for g in host_obj.groups]
            # Si aucun des groupes de l'hôte ne fait partie des groupes
            # auxquels l'utilisateur a accès, on affiche une erreur 403.
            if len(set(hostgroups).intersection(set(supitemgroups))) < 1:
                message = _('Access denied to host "%s"') % host
                LOGGER.warning(message)
                raise http_exc.HTTPForbidden(message)

        # Récupération de la liste des noms des graphes associés à l'hôte.
        graphs = DBSession.query(
                Graph.name
            ).distinct(
            ).join(
                (GRAPH_PERFDATASOURCE_TABLE,
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
                (PerfDataSource, PerfDataSource.idperfdatasource ==
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
                (Host, Host.idhost == PerfDataSource.idhost),
            ).filter(Host.name == host)

        graphs = graphs.all()
        return dict(host=host, start=start, duration=duration,
                    presets=self.presets, graphs=graphs)
Beispiel #23
0
    def searchHostAndGraph(self, search_form_host, search_form_graph):
        """
        Determination des couples (hote-graphe) repondant aux criteres de
        recherche sur hote et/ou graphe.

        Un critere peut correspondre a un intitule complet hote ou graphe
        ou a un extrait.

        @return: couples hote-graphe
        @rtype: document json (sous forme de dict)
        """
        limit = 100
        user = get_current_user()
        ids = []
        labels = []

        if user is None:
            return dict(items=[])

        # On a un nom d'indicateur, mais pas de nom d'hôte,
        # on considère que l'utilisateur veut tous les indicateurs
        # correspondant au motif, quel que soit l'hôte.
        if search_form_graph:
            if not search_form_host:
                search_form_host = u'*'

            search_form_host = sql_escape_like(search_form_host)
            search_form_graph = sql_escape_like(search_form_graph)

            items = DBSession.query(
                    Host.idhost.label('idhost'),
                    Host.name.label('hostname'),
                    Graph.idgraph.label('idgraph'),
                    Graph.name.label('graphname'),
                ).distinct().join(
                    (PerfDataSource, PerfDataSource.idhost == Host.idhost),
                    (GRAPH_PERFDATASOURCE_TABLE, \
                        GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \
                        PerfDataSource.idperfdatasource),
                    (Graph, Graph.idgraph == \
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
                        Host.idhost),
                ).filter(Host.name.ilike(search_form_host)
                ).filter(Graph.name.ilike(search_form_graph)
                ).order_by(
                    Host.name.asc(),
                    Graph.name.asc(),
                )

        # On a ni hôte, ni indicateur. On renvoie une liste vide.
        # Si l'utilisateur voulait vraiment quelque chose,
        # il n'avait qu'à le demander.
        elif not search_form_host:
            return []

        # Sinon, on a juste un motif pour un hôte.
        # On renvoie la liste des hôtes correspondant.
        else:
            search_form_host = sql_escape_like(search_form_host)
            items = DBSession.query(
                    Host.idhost.label('idhost'),
                    Host.name.label('hostname'),
                ).distinct().join(
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
                        Host.idhost),
                ).filter(Host.name.ilike(search_form_host)
                ).order_by(Host.name.asc())

        # Les managers ont accès à tout.
        # Les autres ont un accès restreint.
        if not config.is_manager.is_met(request.environ):
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
            # pylint: disable-msg=E1103
            items = items.join(
                (GroupHierarchy, GroupHierarchy.idchild == \
                    SUPITEM_GROUP_TABLE.c.idgroup)
            ).filter(GroupHierarchy.idparent.in_(supitemgroups))

        items = items.limit(limit + 1).all() # pylint: disable-msg=E1103
        more_results = len(items) > limit

        if not search_form_graph:
            for i in xrange(min(limit, len(items))):
                ids.append((items[i].idhost, None))
                labels.append((items[i].hostname, None))
        else:
            for i in xrange(min(limit, len(items))):
                ids.append((items[i].idhost, items[i].idgraph))
                labels.append((items[i].hostname, items[i].graphname))

        return dict(labels=labels, ids=ids, more=more_results)
Beispiel #24
0
    def get_json_data(self, idcorrevent, *args, **kwargs):
        """
        Renvoie les éléments pour l'affichage de la fenêtre de dialogue
        contenant des détails sur un événement corrélé.

        @param idcorrevent: identifiant de l'événement corrélé.
        @type idcorrevent: C{int}
        """

        # Obtention de données sur l'événement et sur son historique
        host_query = DBSession.query(
            Host.idhost.label("idsupitem"),
            Host.idhost.label("idhost"),
            Host.name.label("host"),
            expr_null().label("service"),
        )
        lls_query = DBSession.query(
            LowLevelService.idservice.label("idsupitem"),
            Host.idhost.label("idhost"),
            Host.name.label("host"),
            LowLevelService.servicename.label("service"),
        ).join(
            (Host, Host.idhost == LowLevelService.idhost),
        )
        supitems = union_all(lls_query, host_query, correlate=False).alias()
        event = DBSession.query(
            CorrEvent.idcorrevent,
            CorrEvent.idcause,
            supitems.c.idhost,
            supitems.c.host,
            supitems.c.service,
            Event.message,
            Event.initial_state,
            Event.current_state,
            Event.peak_state
        ).join(
            (Event, Event.idevent == CorrEvent.idcause),
            (supitems, supitems.c.idsupitem == Event.idsupitem),
        ).filter(CorrEvent.idcorrevent == idcorrevent
        ).first()

        # On détermine les cartes auxquelles cet utilisateur a accès.
        user_maps = []
        max_maps = int(config['max_maps'])
        is_manager = config.is_manager.is_met(request.environ)
        if max_maps != 0 and (is_manager or
            has_permission('vigimap-access').is_met(request.environ)):
            items = DBSession.query(
                    Map.idmap,
                    Map.title,
                    func.lower(Map.title),
                ).distinct(
                ).join(
                    (MAP_GROUP_TABLE, MAP_GROUP_TABLE.c.idmap == Map.idmap),
                    (MapGroup, MapGroup.idgroup == MAP_GROUP_TABLE.c.idgroup),
                    (MapNodeHost, MapNodeHost.idmap == Map.idmap),
                ).order_by(func.lower(Map.title).asc()
                ).filter(MapNodeHost.idhost == event.idhost)

            if not is_manager:
                mapgroups = get_current_user().mapgroups(only_direct=True)
                # pylint: disable-msg=E1103
                items = items.filter(MapGroup.idgroup.in_(mapgroups))

            # La valeur -1 supprime la limite.
            if max_maps > 0:
                # On limite au nombre maximum de cartes demandés + 1.
                # Un message sera affiché s'il y a effectivement plus
                # de cartes que la limite configurée.
                items = items.limit(max_maps + 1)

            user_maps = [(m.idmap, m.title) for m in items.all()]

        context = {
            'idcorrevent': idcorrevent,
            'host': event.host,
            'service': event.service,
            'message': event.message,
            'maps': user_maps,
            'current_state': StateName.value_to_statename(event.current_state),
            'initial_state': StateName.value_to_statename(event.initial_state),
            'peak_state': StateName.value_to_statename(event.peak_state),
        }

        eventdetails = {}
        for edname, edlink in enumerate(config['vigiboard_links.eventdetails']):
            # Évite que les gardes ne se polluent entre elles.
            local_ctx = context.copy()

            # Les liens peuvent être conditionnés à l'aide
            # d'une expression ou d'un callable qui agira
            # comme un prédicat de test.
            if 'only_if' in edlink:
                if callable(edlink['only_if']):
                    display_link = edlink['only_if'](local_ctx)
                else:
                    display_link = edlink['only_if']
                if not display_link:
                    continue

            if callable(edlink['uri']):
                uri = edlink['uri'](local_ctx)
            else:
                uri = edlink['uri'] % local_ctx

            eventdetails[unicode(edname)] = {
                'url': url(uri),
                'target': edlink.get('target', '_blank')
            }

        return dict(
                current_state = StateName.value_to_statename(
                                    event.current_state),
                initial_state = StateName.value_to_statename(
                                    event.initial_state),
                peak_state = StateName.value_to_statename(
                                    event.peak_state),
                idcorrevent = idcorrevent,
                host = event.host,
                service = event.service,
                eventdetails = eventdetails,
                maps = user_maps,
                idcause = event.idcause,
            )
Beispiel #25
0
    def get_groups(self, parent_id=None, onlytype="", offset=0, noCache=None):
        """
        Affiche un étage de l'arbre de
        sélection des hôtes et groupes d'hôtes.

        @param parent_id: identifiant du groupe d'hôte parent
        @type  parent_id: C{int} or None
        """

        # Si l'identifiant du groupe parent n'est pas
        # spécifié, on retourne la liste des groupes
        # racines, fournie par la méthode get_root_groups.
        if parent_id is None:
            return self.get_root_groups()

        # TODO: Utiliser un schéma de validation
        parent_id = int(parent_id)
        offset = int(offset)

        # On récupère la liste des groupes de supitems dont
        # l'identifiant du parent est passé en paramètre.
        supitem_groups = DBSession.query(
                SupItemGroup.idgroup,
                SupItemGroup.name,
            ).join(
                (GroupHierarchy,
                    GroupHierarchy.idchild == SupItemGroup.idgroup),
            ).filter(GroupHierarchy.idparent == parent_id
            ).filter(GroupHierarchy.hops == 1
            ).order_by(SupItemGroup.name)

        # Si l'utilisateur n'appartient pas au groupe 'managers',
        # on filtre les résultats en fonction de ses permissions.
        if not config.is_manager.is_met(request.environ):
            user = get_current_user()
            GroupHierarchy_aliased = aliased(GroupHierarchy,
                name='GroupHierarchy_aliased')
            supitem_groups = supitem_groups.join(
                (GroupHierarchy_aliased,
                    or_(
                        GroupHierarchy_aliased.idchild == SupItemGroup.idgroup,
                        GroupHierarchy_aliased.idparent == SupItemGroup.idgroup
                    )),
                (DataPermission,
                    or_(
                        DataPermission.idgroup == \
                            GroupHierarchy_aliased.idparent,
                        DataPermission.idgroup == \
                            GroupHierarchy_aliased.idchild,
                    )),
                (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup == \
                    DataPermission.idusergroup),
            ).filter(USER_GROUP_TABLE.c.username == user.user_name)

        limit = int(config.get("max_menu_entries", 20))
        result = {"groups": [], "items": []}
        num_children_left = supitem_groups.distinct().count() - offset
        if offset:
            result["continued_from"] = offset
            result["continued_type"] = "group"
        all_grs = supitem_groups.distinct().limit(limit).offset(offset).all()
        for group in all_grs:
            result["groups"].append({
                'id'   : group.idgroup,
                'name' : group.name,
                'type' : "group",
            })
        if num_children_left > limit:
            result["groups"].append({
                'name': _("Next %(limit)s") % {"limit": limit},
                'offset': offset + limit,
                'parent_id': parent_id,
                'type': 'continued',
                'for_type': 'group',
            })

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

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

        # On supprime les règles dans la BDD.
        try:
            for silence in silences:
                DBSession.delete(silence)
            DBSession.flush()
        except InvalidRequestError, e:
            msg = _('An exception has been raised while ' \
                    'deleting the silence rules: %s') % str(e)
            self.handle_error_message(msg)
Beispiel #27
0
    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', '/'))
Beispiel #28
0
    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 = {},
        )
Beispiel #29
0
    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 = {},
        )
Beispiel #30
0
    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,
        )