def cb(_result):
     self.assertEqual(DBSession.query(tables.Event).count(), 0,
         "L'événement ne doit pas avoir été inséré")
     self.assertEqual(DBSession.query(tables.EventHistory).count(), 0,
         "L'événement ne doit pas avoir d'historique")
     self.assertEqual(self.rd._do_correl.call_count, 0,
         "La correlation ne doit pas avoir été lancée")
Example #2
0
    def by_host_and_source_name(cls, host, sourcename):
        """
        Renvoie une source de données concernant un service donné
        en fonction de son nom.

        @param cls: Classe à utiliser pour la récupération de la source.
        @type cls: C{type}
        @param host: Instance de L{Host} ou identifiant
            de l'hôte sur lequel porte la source de données.
        @type host: C{int} ou L{Host}
        @param sourcename: Nom de la source de données à récupérer.
        @type sourcename: C{unicode}
        @return: La source de données de performances dont le nom est
            C{sourcename} et qui porte sur le service C{service}.
        @rtype: L{PerfDataSource}
        """
        if isinstance(host, (int, long)):
            return DBSession.query(cls
                ).filter(cls.idhost == host
                ).filter(cls.name == sourcename
                ).first()

        return DBSession.query(cls
            ).filter(cls.idhost == host.idhost
            ).filter(cls.name == sourcename
            ).first()
Example #3
0
    def test_purge_zero_days(self):
        """Purge des événements sans limite d'âge."""
        # On veut fermer les événements corrélés qui sont dans l'état OK,
        # quelque soit la date à laquelle ils ont été créés.
        options = Options(days=0, size=None)
        clean_vigiboard(LOGGER, options, None)

        # Les 2 entrées d'historique pour un HLS
        # doivent avoir été supprimées.
        self.assertEquals(0, DBSession.query(tables.HLSHistory).count())

        # On s'assure que le CorrEvent et l'événement sur localhost2
        # âgés de 2j ont bien été supprimés.
        supitem = tables.Host.by_host_name(u'localhost2')
        event = DBSession.query(tables.Event).filter(
            tables.Event.idsupitem == supitem.idsupitem).first()
        self.assertEquals(None, event) # sans Event, pas de CorrEvent possible.

        # Les autres doivent toujours être dans l'état "fermé".
        others = DBSession.query(tables.CorrEvent).all()

        self.assertNotEquals(0, len(others))
        for other in others:
            # Contourne le problème du support incomplet des contraintes
            # référentielles de type ON DELETE CASCADE dans SQLite.
            if other.cause is None:
                continue

            self.assertEquals(
                other.ack,
                tables.CorrEvent.ACK_NONE,
                "L'événement corrélé sur %s devrait être 'nouveau'" %
                    other.cause.supitem
            )
Example #4
0
    def impacted_hls(self, *args):
        """
        Renvoie une requête portant sur les services de haut niveau impactés.

        @param args: Liste d'éléments à récupérer dans la requête.
        @type args: Une C{DeclarativeBase} ou une liste de C{Column}s.
        @return: Une C{Query} portant sur les éléments demandés.
        @rtype: C{sqlalchemy.orm.query.Query}
        """
        from vigilo.models.tables import HighLevelService, \
                                            ImpactedHLS, ImpactedPath

        if not args:
            args = [HighLevelService]

        imp_hls1 = aliased(ImpactedHLS)
        imp_hls2 = aliased(ImpactedHLS)

        subquery = DBSession.query(
            functions.max(imp_hls1.distance).label('distance'),
            imp_hls1.idpath
        ).join(
            (ImpactedPath, ImpactedPath.idpath == imp_hls1.idpath)
        ).filter(ImpactedPath.idsupitem == self.idsupitem
        ).group_by(imp_hls1.idpath).subquery()

        services_query = DBSession.query(*args).distinct(
        ).join(
            (imp_hls2, HighLevelService.idservice == imp_hls2.idhls),
            (subquery, subquery.c.idpath == imp_hls2.idpath),
        ).filter(imp_hls2.distance == subquery.c.distance)

        return services_query
Example #5
0
    def test_migration(self):
        """Teste la migration (partielle/totale) du modèle."""

        # Recherche des scripts de migration dans le dossier des tests.
        module = u'vigilo.models.test.testdata'
        scripts = get_migration_scripts(module)

        expected_scripts = {
            1: '001_Initial_version',
            2: '002_Dummy',
            3: '003_Dummy',
        }
        self.assertEquals(scripts, expected_scripts)

        # On simule l'installation d'un nouveau modèle.
        DBSession.add(tables.Version(
            name=module,
            version=1,
        ))
        DBSession.flush()

        # On vérifie qu'une migration jusqu'à un point fixe fonctionne.
        migrate_model(DBSession.bind, module, scripts, 2)
        version = DBSession.query(tables.Version).filter(
            tables.Version.name == module).one()
        self.assertEquals(version.version, 2)

        # On annule la migration et on teste cette fois une migration
        # jusqu'à la dernière version disponible.
        version.version = 1
        DBSession.flush()
        migrate_model(DBSession.bind, module, scripts)
        version = DBSession.query(tables.Version).filter(
            tables.Version.name == module).one()
        self.assertEquals(version.version, 3)
Example #6
0
    def test_select_graph_without_a_host(self):
        """
        Résultats de la recherche sur un graphe sans préciser d'hôte
        """

        # Récupération de l'hôte 'host1' dans la base de données
        host1 = DBSession.query(Host).filter(
            Host.name == u'host1 éà').first()

        # Récupération du graphe 'graph1' dans la base de données
        graph1 = DBSession.query(Graph).filter(
            Graph.name == u'graph1 éà').first()

        # Récupération des résultats obtenus après une recherche sur
        # un graphe sans préciser d'hôte par l'utilisateur 'manager'.
        response = self.app.post(
            '/rpc/searchHostAndGraph?search_form_graph=%s' %
                urllib2.quote(graph1.name.encode('utf-8'), ''),
            {},
            extra_environ={'REMOTE_USER': '******'}
        )
        json = response.json

        # On s'assure que la liste retournée est conforme à celle attendue
        self.assertEqual(
            json, {
                'labels': [[host1.name, graph1.name]],
                'ids': [[host1.idhost, graph1.idgraph]],
                'more': False,
            }
        )
Example #7
0
    def test_close_limited_up(self):
        """Fermeture événements état UP avec limite de durée."""
        # On veut fermer les événements corrélés qui sont dans l'état UP,
        # ayant au moins 1j d'âge.
        options = Options(state_up=True, state_ok=False, days=1)
        res = close_green(LOGGER, options)
        self.assertTrue(res) # pas d'erreur.

        # On s'assure que le CorrEvent associé à l'état UP
        # âgé de 2j a bien été clos.
        supitem = tables.Host.by_host_name(u'localhost2')
        event = DBSession.query(tables.Event).filter(
            tables.Event.idsupitem == supitem.idsupitem).one()
        correvent = DBSession.query(tables.CorrEvent).filter(
            tables.CorrEvent.idcause == event.idevent).one()
        self.assertEquals(correvent.ack, tables.CorrEvent.ACK_CLOSED)

        # Les autres doivent toujours être dans l'état "nouveau".
        others = DBSession.query(tables.CorrEvent).filter(
            tables.CorrEvent.idcorrevent != correvent.idcorrevent).all()
        self.assertNotEquals(0, len(others))
        for other in others:
            self.assertEquals(other.ack, tables.CorrEvent.ACK_NONE,
                "L'événement corrélé sur %s devrait être 'nouveau'" %
                other.cause.supitem
            )
    def test_add_multiple_batch(self):
        """Ajout permission sur plusieurs groupes en mode batch."""
        for (incode, outcode) in commands._permissions.iteritems():
            print "Test permission %s" % incode
            options = NamespaceStub(
                permission=incode,
                object_type=self._type,
                usergroup=self._usergroup.group_name.encode('utf-8'),
                object_group=self._group1.name.encode('utf-8'),
                batch=True,
                update=False,
                commit=False,   # la base de test est en mémoire,
                                # en la committant, on perdrait tout.
            )
            res = commands.cmd_add(options)
            self.assertEquals(res, 0)

            # 2 permissions doivent avoir été ajoutées.
            dataperms = DBSession.query(tables.DataPermission).all()
            self.assertEquals(2, len(dataperms))

            idgroups = [self._group1.idgroup, self._group2.idgroup]
            for dataperm in dataperms:
                self.assertTrue(dataperm.idgroup in idgroups)
                idgroups.remove(dataperm.idgroup)
                self.assertEquals(dataperm.idusergroup, self._usergroup.idgroup)
                self.assertEquals(dataperm.access, outcode)

            # Suppression des permissions pour le test
            # du type de permission suivant.
            for dataperm in dataperms:
                DBSession.delete(dataperm)
                DBSession.flush()
            dataperm = DBSession.query(tables.DataPermission).first()
            self.assertEquals(dataperm, None)
    def test_get_graph_groups_when_not_allowed(self):
        """
        Récupération des groupes de graphes sans les bons droits
        """

        # Récupération de l'hôte 'host1' dans la base de données
        host1 = DBSession.query(Host).filter(
            Host.name == u'host1 éà').first()

        # Récupération de l'hôte 'host3' dans la base de données
        host3 = DBSession.query(Host).filter(
            Host.name == u'host3 éà').first()

        # Récupération des groupes de graphes de l'hôte
        # host1 accessibles à l'utilisateur 'user'
        response = self.app.post(
        '/rpc/graphtree?host_id=%s' % (host1.idhost, ), {
            }, extra_environ={'REMOTE_USER': '******'})
        json = response.json

        # On s'assure que la liste de groupes
        # de graphes retournée est vide
        self.assertEqual(
            json, {
                'graphs': [],
                'groups': []
            }
        )

        # Récupération des groupes de graphes de l'hôte
        # host3 accessibles à l'utilisateur 'user'
        response = self.app.post(
        '/rpc/graphtree?host_id=%s' % (host3.idhost, ), {
            }, extra_environ={'REMOTE_USER': '******'})
        json = response.json

        # On s'assure que la liste de groupes
        # de graphes retournée est vide
        self.assertEqual(
            json, {
                'graphs': [],
                'groups': []
            }
        )

        # Récupération des groupes de graphes de l'hôte
        # host1 accessibles à l'utilisateur 'visitor'
        response = self.app.post(
        '/rpc/graphtree?host_id=%s' % (host1.idhost, ), {
            }, extra_environ={'REMOTE_USER': '******'})
        json = response.json

        # On s'assure que la liste de groupes
        # de graphes retournée est vide
        self.assertEqual(
            json, {
                'graphs': [],
                'groups': []
            }
        )
    def test_add_single(self):
        """Ajout de permission sur un seul groupe."""
        for (incode, outcode) in commands._permissions.iteritems():
            print "Test permission %s" % incode
            options = NamespaceStub(
                permission=incode,
                object_type=self._type,
                usergroup=self._usergroup.group_name.encode('utf-8'),
                object_group=self._group1.path.encode('utf-8'),
                batch=False,
                update=False,
                commit=False,   # la base de test est en mémoire,
                                # en la committant, on perdrait tout.
            )
            res = commands.cmd_add(options)
            self.assertEquals(res, 0)

            # Une seule permission doit exister en base de données.
            # Elle doit porter sur le groupe 1 définis par le test
            # et avoir le bon type d'accès.
            dataperm = DBSession.query(tables.DataPermission).one()
            self.assertEquals(dataperm.idgroup, self._group1.idgroup)
            self.assertEquals(dataperm.idusergroup, self._usergroup.idgroup)
            self.assertEquals(dataperm.access, outcode)

            # Suppression de la permission pour le test
            # du type de permission suivant.
            DBSession.delete(dataperm)
            DBSession.flush()
            dataperm = DBSession.query(tables.DataPermission).first()
            self.assertEquals(dataperm, None)
Example #11
0
 def test_insert_old_state(self):
     """Abandon de l'insertion d'un état ancien"""
     self.make_dependencies()
     ts_old = 1239104006
     ts_recent = 1239104042
     ts_recent_dt = datetime.fromtimestamp(ts_recent)
     idsupitem = SupItem.get_supitem("server.example.com", "Load")
     # Insertion de l'état récent
     state = DBSession.query(State).get(idsupitem)
     state.timestamp = ts_recent_dt
     # Création d'un message d'événement portant sur un SBN.
     info_dictionary = {
             "type": "event",
             "timestamp": datetime.fromtimestamp(ts_old),
             "host": "server.example.com",
             "service": "Load",
             "state": "WARNING",
             "message": "WARNING: Load average is above 4 (4.5)",
             }
     info_dictionary['idsupitem'] = SupItem.get_supitem(
         info_dictionary['host'],
         info_dictionary['service']
     )
     # Insertion de l'ancien événement dans la BDD
     result = insert_state(info_dictionary)
     self.assertTrue(isinstance(result, OldStateReceived))
     supitem = DBSession.query(SupItem).get(idsupitem)
     self.assertEqual(supitem.state.timestamp, ts_recent_dt)
Example #12
0
    def test_parent(self):
        """Affectation d'un parent à un groupe."""
        # Au début, nous n'avons pas de parent.
        assert_equal(self.obj.has_parent(), False)

        # On obtient un parent.
        parent = self.klass(name=u"aparent", parent=None)
        DBSession.add(parent)
        self.obj.parent = parent
        DBSession.query(GroupHierarchy
                        ).filter(GroupHierarchy.parent == parent
                        ).filter(GroupHierarchy.child == self.obj
                        ).filter(GroupHierarchy.hops == 1
                        ).one()
        assert_equal(self.obj.parent, parent)
        assert_equal(self.obj.has_parent(), True)

        # Notre parent est modifié.
        anotherparent = self.klass(name=u"anotherparent", parent=None)
        DBSession.add(anotherparent)
        self.obj.parent = anotherparent
        DBSession.query(GroupHierarchy
                        ).filter(GroupHierarchy.parent == anotherparent
                        ).filter(GroupHierarchy.child == self.obj
                        ).filter(GroupHierarchy.hops == 1
                        ).one()
        assert_equal(self.obj.parent, anotherparent)
        assert_equal(self.obj.has_parent(), True)

        # Suppression du parent.
        self.obj.parent = None
        assert_equal(self.obj.parent, None)
        assert_equal(self.obj.has_parent(), False)
Example #13
0
    def test_rule_creation(self):
        """ Ajout d'une règle de mise en silence """

        # 1. On essaye d'ajouter une règle de mise en silence sur 'service3'
        # avec l'utilisateur 'no_rights' et on s'assure qu'on reçoit bien une
        # erreur 403
        environ = {"REMOTE_USER": "******"}
        url = "/silence/create_or_modify?" + urllib.urlencode(
            {"states": "CRITICAL", "host": "host3", "service": "service3", "comment": "commentaire accentué"}
        )
        self.app.get(url, extra_environ=environ, status=403)

        # 2. On essaye d'ajouter une règle de mise en silence sur 'service3'
        # avec l'utilisateur 'limited_rights' et on s'assure qu'on est bien
        # redirigé sur un message d'erreur
        environ = {"REMOTE_USER": "******"}
        url = "/silence/create_or_modify?" + urllib.urlencode(
            {"states": "CRITICAL", "host": "host3", "service": "service3", "comment": "commentaire accentué"}
        )
        response = self.app.get(url, extra_environ=environ, status=302)
        response = response.follow(status=200, extra_environ=environ)
        assert_true(len(response.lxml.xpath('//div[@id="flash"]/div[@class="error"]')))

        # 3. On ajoute une règle de mise en silence sur 'service4' avec
        # l'utilisateur 'limited_rights'
        environ = {"REMOTE_USER": "******"}
        url = "/silence/create_or_modify?" + urllib.urlencode(
            {"states": "CRITICAL", "host": "host4", "service": "service4", "comment": "commentaire accentué"}
        )
        self.app.get(url, extra_environ=environ)

        # On recherche dans la base toutes les règles concernant 'service4'
        supitem_id = SupItem.get_supitem("host4", "service4")
        silences = DBSession.query(Silence).filter(Silence.idsupitem == supitem_id).all()

        # On s'assure qu'il n'y en a qu'une, et on vérifie ses propriétés
        assert_equal(len(silences), 1)
        assert_equal([s.statename for s in silences[0].states], ["CRITICAL"])
        assert_equal(silences[0].comment, u"commentaire accentué")
        assert_equal(silences[0].author, u"limited_rights")

        # 4. On ajoute une règle de mise en silence sur 'service3' avec
        # l'utilisateur 'manager'
        environ = {"REMOTE_USER": "******"}
        url = "/silence/create_or_modify?" + urllib.urlencode(
            {"states": "CRITICAL", "host": "host3", "service": "service3", "comment": "commentaire accentué"}
        )
        self.app.get(url, extra_environ=environ)

        # On recherche dans la base toutes les règles concernant 'service3'
        supitem_id = SupItem.get_supitem("host3", "service3")
        silences = DBSession.query(Silence).filter(Silence.idsupitem == supitem_id).all()

        # On s'assure qu'il n'y en a qu'une, et on vérifie ses propriétés
        assert_equal(len(silences), 1)
        assert_equal([s.statename for s in silences[0].states], ["CRITICAL"])
        assert_equal(silences[0].comment, u"commentaire accentué")
        assert_equal(silences[0].author, u"manager")
Example #14
0
    def supitemgroups(self, access=None):
        """
        Renvoie la liste des identifiants des groupes d'éléments supervisés
        auxquels l'utilisateur a accès.

        @param access: La liste des types d'accès qui autoriseront
            l'utilisateur à voir les groupes. Si elle vaut C{None},
            aucune vérification n'est faite sur le type d'accès.
        @param access: C{basestring} or C{list} of C{basestring}

        @return: Liste des identifiants des groupes d'éléments supervisés
            auxquels l'utilisateur a accès.
        @rtype: C{list} of Ctuple{} of C{int}, C{bool}
        """
        result = {}
        if hasattr(access, '__iter__'):
            access = set([ unicode(a) for a in access ])
        elif access is not None:
            access = set([unicode(access)])

        # L'accès en écriture donne implicitement un accès en lecture.
        if access is not None and u'r' in access:
            access.add(u'w')

        # Groupes d'éléments supervisés auxquels
        # l'utilisateur a directement accès.
        direct = DBSession.query(SupItemGroup.idgroup).distinct(
            ).join(
                (GroupHierarchy, GroupHierarchy.idchild ==
                    SupItemGroup.idgroup),
                (DataPermission, DataPermission.idgroup ==
                    GroupHierarchy.idparent),
                (UserGroup, UserGroup.idgroup == DataPermission.idusergroup),
                (USER_GROUP_TABLE, USER_GROUP_TABLE.c.idgroup ==
                    UserGroup.idgroup),
            ).filter(USER_GROUP_TABLE.c.username == self.user_name)
        if access is not None:
            direct = direct.filter(DataPermission.access.in_(access))
        direct = direct.all()
        direct_ids = [sig.idgroup for sig in direct]

        # Groupes d'éléments supervisés auxquels l'utilisateur a accès
        # indirectement (droit de passage, mais pas de droit de lecture).
        indirect = DBSession.query(SupItemGroup.idgroup).distinct(
            ).join(
                (GroupHierarchy, GroupHierarchy.idparent == \
                    SupItemGroup.idgroup),
            ).filter(GroupHierarchy.idchild.in_(direct_ids)
            ).filter(GroupHierarchy.hops > 0
            ).all()

        for sig in indirect:
            result[sig.idgroup] = (sig.idgroup, False)
        for sig in direct:
            result[sig.idgroup] = (sig.idgroup, True)

        return result.values()
Example #15
0
 def test_creation_loop(self):
     """
     Ajout des boucles dans la hiérarchie lors de la création d'un groupe.
     """
     DBSession.query(GroupHierarchy
                     ).filter(GroupHierarchy.idparent == self.obj.idgroup
                     ).filter(GroupHierarchy.idchild == self.obj.idgroup
                     ).filter(GroupHierarchy.hops == 0
                     ).one()
Example #16
0
    def test_update_while_data_have_changed(self):
        """Màj d'un évènement corrélé modifié entre temps."""

        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
        # et un groupe d'hôtes et de services associés à ces items.
        (_hosts, services) = populate_DB()

        # On ajoute 2 évènements corrélés causés par ces hôtes
        timestamp = datetime.now()
        correvent1_id = add_correvent_caused_by(services[0], timestamp)
        add_correvent_caused_by(services[1], timestamp)

        # Date de modification du premier évènement corrélé
        later_date = datetime.now()
        # Date du chargement de la page
        date = mktime(later_date.timetuple()) - 42

        # On ajoute une entrée dans l'historique de l'évènement brut
        # causant le premier évènement corrélé, portant pour timestamp
        # une date postérieure à celle du chargement de la page.
        correvent1 = DBSession.query(
            CorrEvent.idcause
            ).filter(CorrEvent.idcorrevent == correvent1_id).one()
        DBSession.add(EventHistory(
            type_action = u'Nagios update state',
            idevent = correvent1.idcause,
            timestamp = later_date))
        DBSession.flush()

        transaction.commit()

        # L'utilisateur utilisé pour se connecter à Vigiboard est 'access'.
        environ = {'REMOTE_USER': '******'}

        # On s'attend à ce que le statut de la requête soit 302, et
        # à ce qu'un message d'erreur avise l'utilisateur que des
        # changements sont intervenus depuis le chargement de la page.
        response = self.app.post(
            '/update', {
                "id" : str(correvent1_id),
                "last_modification" : date,
                "trouble_ticket" : "",
                "ack" : u'Acknowledged',
            }, status = 302, extra_environ = environ)

        response = response.follow(status=200, extra_environ = environ)
        assert_true(response.lxml.xpath(
            '//div[@id="flash"]/div[@class="warning"]'))

        # On s'assure que le statut de l'évènement corrélé
        # n'a pas été modifié dans la base de données.
        status = DBSession.query(
            CorrEvent.ack
            ).filter(CorrEvent.idcorrevent == correvent1_id
            ).scalar()
        assert_equal(status, CorrEvent.ACK_NONE)
Example #17
0
 def test_change_dependencies_nothing(self):
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     before = DBSession.query(SupItemGroup).count()
     # On doit créer un 2ème loader pour forcer le rechargement
     # des instances depuis la base de données.
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     after = DBSession.query(SupItemGroup).count()
     self.assertEquals(after, before)
Example #18
0
 def do_get_dependencies(self):
     """
     On surcharge la méthode de ModelTest
     car elle insère déjà des noms d'états.
     On veut éviter toute interférence dans les tests.
     """
     # On supprime les StateName insérés par défaut.
     DBSession.query(StateName).delete()
     DBSession.flush()
     return {}
Example #19
0
    def test_insert_lls_event(self):
        """Insertion d'un évènement brut concernant un SBN"""

        self.make_dependencies()

        # Création d'un message d'événement portant sur un SBN.
        info_dictionary = {
                "type": "event",
                "timestamp": datetime.fromtimestamp(1239104006),
                "host": "server.example.com",
                "service": "Load",
                "state": u"WARNING",
                "message": u"WARNING: Load average is above 4 (4.5)",
                }
        info_dictionary['idsupitem'] = SupItem.get_supitem(
            info_dictionary['host'],
            info_dictionary['service']
        )

        # Insertion de l'événement dans la BDD
        idevent = insert_event(info_dictionary)

        assert idevent is not None
        event = DBSession.query(Event).one()

        # Vérification des informations de l'événement dans la BDD.
        self.assertEquals(LowLevelService, type(event.supitem))
        self.assertEquals(1239104006, time.mktime(event.timestamp.timetuple()))
        self.assertEquals(u'server.example.com', event.supitem.host.name)
        self.assertEquals(u'Load', event.supitem.servicename)
        self.assertEquals(u'WARNING',
            StateName.value_to_statename(event.current_state))
        self.assertEquals(u'WARNING',
            StateName.value_to_statename(event.initial_state))
        self.assertEquals(u'WARNING',
            StateName.value_to_statename(event.peak_state))
        self.assertEquals(u'WARNING: Load average is above 4 (4.5)',
                            event.message)

        # Insertion de l'état dans la BDD
        state = DBSession.query(State).get(info_dictionary['idsupitem'])
        # le timestamp par défaut est plus récent et insert_state refusera la
        # mise à jour
        state.timestamp = info_dictionary['timestamp']
        insert_state(info_dictionary)

        # Vérification des informations de l'état dans la BDD.
        self.assertEquals(LowLevelService, type(state.supitem))
        self.assertEquals(1239104006, time.mktime(state.timestamp.timetuple()))
        self.assertEquals('server.example.com', state.supitem.host.name)
        self.assertEquals('Load', state.supitem.servicename)
        self.assertEquals('WARNING',
            StateName.value_to_statename(state.state))
        self.assertEquals('WARNING: Load average is above 4 (4.5)',
                            state.message)
Example #20
0
 def test_nonexisting_predecessor(self):
     """Agrégation topologique : agrégat inexistant."""
     ctx = self.context_factory(42)
     event1 = functions.add_event(self.hosts[1], 'DOWN', u'foo')
     event2 = functions.add_event(self.hosts[2], 'UNREACHABLE', u'foo')
     ctx.set('predecessors_aggregates', [1])
     res = yield self.corrbuilder._aggregate_topologically(
                 ctx, None, event2.idevent, self.hosts[2].idhost)
     self.assertEquals(False, res)
     self.assertEquals(0, DBSession.query(tables.CorrEvent).count())
     self.assertEquals(2, DBSession.query(tables.Event).count())
Example #21
0
 def prevalidate_hosts(self):
     hosts_db = DBSession.query(tables.Host).count()
     if hosts_db != self._stats["nbHosts"]:
         self.addError("DBLoader", "hosts",
             _("The number of host entries in the database does not match "
               "the number of hosts in the configuration. "
               "Database: %(db)d, configuration: %(conf)d")
             % {"db": hosts_db, "conf": self._stats["nbHosts"]})
         hosts_db = set([h.name for h in DBSession.query(tables.Host).all()])
         hosts_conf = set([ unicode(h) for h in conf.hostsConf.keys() ])
         LOGGER.debug("Hosts: difference between conf and DB: %s",
                      " ".join(hosts_db ^ hosts_conf))
Example #22
0
 def test_change_dependencies_remove(self):
     """Gestion des changements: fichier supprimé"""
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     df.add_supitemgroup("to_be_removed")
     before = DBSession.query(SupItemGroup).count()
     # On doit créer un 2ème loader pour forcer le rechargement
     # des instances depuis la base de données.
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     grouploader.cleanup()
     after = DBSession.query(SupItemGroup).count()
     self.assertEquals(after, before - 1)
Example #23
0
 def remove_children(self):
     """
     Supprime la relation de descendance entre ce groupe
     et tous ses descendants.
     """
     children_ids = DBSession.query(
             GroupHierarchy.idchild
         ).filter(GroupHierarchy.idparent == self.idgroup
         ).filter(GroupHierarchy.hops > 0).all()
     children_ids = [c.idchild for c in children_ids]
     DBSession.query(Group).filter(Group.idgroup.in_(children_ids)).delete(
         synchronize_session='fetch')
     DBSession.flush()
Example #24
0
 def test_predecessor_and_no_aggregate(self):
     """Agrégation topologique : prédécesseur et pas d'agrégat."""
     ctx = self.context_factory(42)
     event1 = functions.add_event(self.hosts[1], 'DOWN', u'foo')
     event2 = functions.add_event(self.hosts[2], 'UNREACHABLE', u'foo')
     aggr1 = functions.add_correvent([event1])
     ctx.set('predecessors_aggregates', [aggr1.idcorrevent])
     ctx.set('successors_aggregates', [])
     res = yield self.corrbuilder._aggregate_topologically(
                 ctx, None, event2.idevent, self.hosts[2].idhost)
     self.assertEquals(True, res)
     self.assertEquals(1, DBSession.query(tables.CorrEvent).count())
     self.assertEquals(2, DBSession.query(tables.Event).count())
Example #25
0
    def test_insert_host_event(self):
        """Insertion d'un évènement brut concernant un hôte"""

        self.make_dependencies()

        # Création d'un message d'événement portant sur un hôte.
        info_dictionary = {
                "type": "event",
                "timestamp": datetime.fromtimestamp(1239104006),
                "host": "server.example.com",
                "state": u"DOWN",
                "message": u"DOWN: No ping response",
                }
        info_dictionary['idsupitem'] = SupItem.get_supitem(
            info_dictionary['host'], None,
        )

        # Insertion de l'événement dans la BDD
        idevent = insert_event(info_dictionary)

        assert idevent is not None
        event = DBSession.query(Event).one()

        # Vérification des informations de l'événement dans la BDD.
        self.assertEquals(Host, type(event.supitem))
        self.assertEquals(1239104006, time.mktime(event.timestamp.timetuple()))
        self.assertEquals(u'server.example.com', event.supitem.name)
        self.assertEquals(u'DOWN',
            StateName.value_to_statename(event.current_state))
        self.assertEquals(u'DOWN',
            StateName.value_to_statename(event.initial_state))
        self.assertEquals(u'DOWN',
            StateName.value_to_statename(event.peak_state))
        self.assertEquals(u'DOWN: No ping response',
                            event.message)

        # Insertion de l'état dans la BDD
        state = DBSession.query(State).get(info_dictionary['idsupitem'])
        # le timestamp par défaut est plus récent et insert_state refusera la
        # mise à jour
        state.timestamp = info_dictionary['timestamp']
        insert_state(info_dictionary)

        # Vérification des informations de l'état dans la BDD.
        self.assertEquals(Host, type(state.supitem))
        self.assertEquals(1239104006, time.mktime(state.timestamp.timetuple()))
        self.assertEquals('server.example.com', state.supitem.name)
        self.assertEquals('DOWN',
            StateName.value_to_statename(state.state))
        self.assertEquals('DOWN: No ping response', state.message)
 def _insert_dep(self):
     """Insertion de l'événement corrélé de test."""
     print "Insertion evenement correle"
     timestamp = datetime.now()
     supitem = DBSession.query(self.supitem_class).one()
     if isinstance(supitem, Host):
         event = functions.add_event(supitem, u'DOWN', u'', timestamp)
     else: # Sinon, il s'agit d'un LowLevelService.
         event = functions.add_event(supitem, u'CRITICAL', u'', timestamp)
     functions.add_correvent([event], timestamp=timestamp)
     DBSession.flush()
     transaction.commit()
     correvent = DBSession.query(CorrEvent.idcorrevent).one()
     return correvent.idcorrevent
Example #27
0
    def __set_parent(self, group):
        """
        Positionne un groupe en tant que parent du groupe courant.
        Cette méthode ne peut gérer qu'un unique parent, elle ne convient
        donc pas pour les L{SupItemGroup}.

        @param group: Nouveau parent du groupe courant.
        @type group: L{Group}
        @note: Si un groupe était déjà marqué comme parent du groupe courant,
            alors cette association est rompue et une nouvelle hiérarchie
            de groupe est construite pour le nouveau parent.
        """
        # On récupère tous nos enfants, petits-enfants, etc..
        children = DBSession.query(GroupHierarchy).filter(
                        GroupHierarchy.parent == self).all()

        if not children:
            loop = GroupHierarchy(parent=self, child=self, hops=0)
            DBSession.add(loop)
            DBSession.flush()
            children = [loop]

        # Supprime tous les liens de parenté du groupe courant
        # et de ses enfants (sans limite de profondeur) vers nos
        # parents (sans limite de profondeur).
        for c in children:
            DBSession.query(GroupHierarchy
                ).filter(GroupHierarchy.idchild == c.idchild
                ).filter(GroupHierarchy.hops > c.hops
                ).delete(synchronize_session='fetch')

        # Si un groupe doit devenir le nouveau parent.
        if group:
            # Récupère les parents, grands-parents, etc. de notre parent.
            parents = DBSession.query(GroupHierarchy
                ).filter(GroupHierarchy.child == group
                ).all()

            for p in parents:
                # Nos enfants [et petits ...] et nous-même héritons de
                # l'arborescence de nos parents [et grands ...] à une
                # distance augmentée de 1.
                for c in children:
                    GroupHierarchy.get_or_create(
                        idparent=p.idparent,
                        idchild=c.idchild,
                        hops=p.hops + c.hops + 1,
                    )
        DBSession.flush()
Example #28
0
 def get_one(self, idmap):
     # pylint:disable-msg=C0111,R0201
     m = DBSession.query(Map).get(idmap)
     if m is None:
         raise HTTPNotFound("Can't find map %s" % idmap)
     check_map_access(m)
     baseurl = tg.url("/api/v%s/maps/%s" % (self.apiver, m.idmap))
     result = {"id": m.idmap,
               "title": m.title,
               "mtime": m.mtime.isoformat(),
               "generated": m.generated,
               "background": {
                   "color": m.background_color,
                   "image": m.background_image,
                   "position": m.background_position,
                   "repeat": m.background_repeat,
                   },
               "href": baseurl,
               }
     # groups
     result["groups_href"] = baseurl+"/groups/"
     groups = []
     for group in m.groups:
         groups.append({
             "id": group.idgroup,
             "name": group.name,
             "href": tg.url("/api/v%s/mapgroups/%s" % (self.apiver, group.idgroup)),
             })
     result["groups"] = groups
     # nodes
     result["nodes_href"] = baseurl+"/nodes/"
     nodes = []
     for node in m.nodes:
         nodes.append({
             "id": node.idmapnode,
             "href": "%s/nodes/%s" % (baseurl, node.idmapnode)
             })
     result["nodes"] = nodes
     # links
     result["links_href"] = baseurl+"/links/"
     links = []
     for link in DBSession.query(MapLink).filter_by(
                                 idmap=idmap).all():
         links.append({
             "id": link.idmaplink,
             "href": "%s/links/%s" % (baseurl, link.idmaplink)
             })
     result["links"] = links
     return dict(map=result)
Example #29
0
 def test_change_dependencies_add(self):
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     print DBSession.query(SupItemGroup).all()
     first_group = DBSession.query(SupItemGroup).first()
     assert first_group is not None
     DBSession.delete(first_group)
     DBSession.flush()
     before = DBSession.query(SupItemGroup).count()
     # On doit créer un 2ème loader pour forcer le rechargement
     # des instances depuis la base de données.
     grouploader = GroupLoader()
     grouploader.load_dir(self.datadir)
     after = DBSession.query(SupItemGroup).count()
     self.assertEquals(after, before + 1)
Example #30
0
 def test_host_mapnode(self):
     """Suppression des mapnodes d'un host supprimé (#57)"""
     # Mettre localhost sur une carte
     h = fct.add_host(u"localhost")
     testmap = fct.add_map(u"Test map")
     fct.add_node_host(h, "localhost", testmap)
     DBSession.flush()
     DBSession.delete(h)
     DBSession.flush()
     # On vérifie que la suppression de l'hôte a bien supprimé ses
     # représentations cartographiques
     mn_count = DBSession.query(tables.MapNode).count()
     self.assertEquals(mn_count, 0)
     mnh_count = DBSession.query(tables.MapNodeHost).count()
     self.assertEquals(mnh_count, 0)