Exemplo n.º 1
0
    def add_dependencies(self):
        """
        Ajout de quelques dépendances entre services de bas
        niveau dans la BDD, préalable à certains des test.
        """
        dep_group1 = functions.add_dependency_group(None, self.service1, u'topology', u'|')
        dep_group2 = functions.add_dependency_group(None, self.service2, u'topology', u'|')
        dep_group3 = functions.add_dependency_group(None, self.service3, u'topology', u'|')
        dep_group4 = functions.add_dependency_group(None, self.service4, u'topology', u'|')

        self.dependency1 = functions.add_dependency(dep_group1, self.service2, 1)
        self.dependency2 = functions.add_dependency(dep_group1, self.service3, 1)
        self.dependency3 = functions.add_dependency(dep_group2, self.service4, 1)
        self.dependency4 = functions.add_dependency(dep_group3, self.service4, 1)
        self.dependency5 = functions.add_dependency(dep_group4, self.service5, 1)
Exemplo n.º 2
0
    def do_get_dependencies(self):
        """Generate some data for the test"""
        ModelTest.do_get_dependencies(self)
        host = functions.add_host(u'myhost')
        service = functions.add_lowlevelservice(host, u'myservice')
        depgroup = functions.add_dependency_group(
                        host, service, u'topology', u'+')

        return dict(
            idgroup=depgroup,
            supitem=service,
        )
Exemplo n.º 3
0
    def test_aggregate_3_levels(self):
        """
        Agrégation sur 3 niveaux.
        """
        # Ajout des dépendances topologiques :
        # - Host 2 dépend de Host 1
        # - Host 3 dépend de Host 2
        dep_group = functions.add_dependency_group(
                        self.hosts[2], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)
        dep_group = functions.add_dependency_group(
                        self.hosts[3], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[2], 1)
        functions.add_dependency(dep_group, self.hosts[1], 2)

        # Simule la chute de "Host 3" puis "Host 1", puis "Host 2".
        res, idcorrevent3 = yield self.handle_alert(self.hosts[3], 'UNREACHABLE')
        self.assertNotEquals(res, None)
        res, idcorrevent1 = yield self.handle_alert(self.hosts[1], 'DOWN')
        self.assertNotEquals(res, None)
        res, idcorrevent2 = yield self.handle_alert(
            self.hosts[2],
            'UNREACHABLE',
            preds=[idcorrevent1],
            succs=[idcorrevent3],
        )
        self.assertEquals(res, None) # Pas de nouvel agrégat créé.

        # On s'attend à trouver 3 événements bruts et 1 agrégat.
        self.assertEquals(3, DBSession.query(tables.Event).count())
        self.assertEquals(1, DBSession.query(tables.CorrEvent).count())

        events = DBSession.query(tables.Event).all()
        events.sort(key=lambda x: x.supitem.name)
        self.assertEquals(u'Host 1', events[0].supitem.name)
        self.assertEquals(u'Host 2', events[1].supitem.name)
        self.assertEquals(u'Host 3', events[2].supitem.name)
Exemplo n.º 4
0
 def test_parents_directive(self):
     """Nagios: parents"""
     # On ajoute un 2ème hôte et on génère une dépendance topologique
     # de "testserver1" sur "testserver2".
     Host(conf.hostsConf, "host/localhost.xml", u"testserver2",
                  "192.168.1.2", "Servers")
     add_host("testserver2", ConfFile.get_or_create("dummy.xml"))
     dep_group = add_dependency_group('testserver1', None, 'topology')
     add_dependency(dep_group, ("testserver2", None))
     # "testserver2" doit apparaître comme parent de "testserver1"
     # dans le fichier de configuration généré pour Nagios.
     self._generate()
     nagiosconffile = os.path.join(self.basedir, "localhost",
                                   "nagios", "nagios.cfg")
     self.assert_(os.path.exists(nagiosconffile),
                  "Nagios conf file was not generated")
     nagiosconf = open(nagiosconffile).read()
     print nagiosconf
     self.assertTrue(re.search("^\s*parents\s+testserver2\s*$",
                     nagiosconf, re.M))
Exemplo n.º 5
0
    def test_desaggregate2(self):
        """Désagrégation d'une vraie alerte d'un agrégat OK/UP (#1027)."""
        # Ajout des dépendances topologiques :
        # - Host 3 dépend de Host 1.
        dep_group = functions.add_dependency_group(
                        self.hosts[3], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)

        # Host 1 est dans l'état UP (pour cela, on génère déjà une alerte
        # DOWN qu'on fait ensuite repasser UP).
        res, idcorrevent1 = yield self.handle_alert(self.hosts[1], 'DOWN')
        self.assertNotEquals(res, None)
        res, idcorrevent1 = yield self.handle_alert(self.hosts[1], 'UP')
        self.assertNotEquals(res, None)
        # Host 3 est DOWN.
        event = functions.add_event(self.hosts[3], 'DOWN', 'DOWN')
        functions.add_host_state(self.hosts[3], 'DOWN')
        # Par erreur, l'alerte sur Host 3 s'est retrouvée masquée
        # par celle sur Host 1 (#1027).
        correvent = DBSession.query(tables.CorrEvent).filter(
            tables.CorrEvent.idcorrevent == idcorrevent1).one()
        correvent.events.append(event)
        DBSession.flush()

        # On reçoit une notification sur Host 3 qui confirme le problème.
        # L'événement doit être retiré de l'agrégat d'Host 1 et placé
        # dans un nouvel agrégat.
        res, idcorrevent2 = yield self.handle_alert(self.hosts[3], 'DOWN')
        self.assertNotEquals(res, None)
        self.assertNotEquals(idcorrevent2, idcorrevent1)

        # On vérifie que les événements sont bien dans les bons agrégats.
        correvent = DBSession.query(tables.CorrEvent).filter(
            tables.CorrEvent.idcorrevent == idcorrevent1).one()
        self.assertEquals(len(correvent.events), 1)
        correvent2 = DBSession.query(tables.CorrEvent).filter(
            tables.CorrEvent.idcorrevent == idcorrevent2).one()
        self.assertEquals(
            [event.idevent],
            [e.idevent for e in correvent2.events]
        )
Exemplo n.º 6
0
    def test_reaggregate2(self):
        """Réagrégation des événements corrélés."""
        # Host 2 dépend de Host 1
        dep_group = functions.add_dependency_group(
                        self.hosts[2], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)

        # 1. Un 1er agrégat doit avoir été créé.
        LOGGER.debug('Step 1')
        res, idcorrevent1 = yield self.handle_alert(
            self.hosts[1], 'DOWN')
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)

        # 2. L'événement brut doit avoir été fusionné
        #    dans l'agrégat précédent.
        LOGGER.debug('Step 2')
        res, idcorrevent2 = yield self.handle_alert(
            self.hosts[2], 'UNREACHABLE', preds=[idcorrevent1])
        # Aucune erreur, mais correvent agrégé.
        self.assertEquals(res, None)
        self.assertEquals(idcorrevent2, None)

        # On a 2 événements bruts et 1 agrégat en base.
        LOGGER.debug("Checking events")
        self.assertEquals(2, DBSession.query(tables.Event).count())
        LOGGER.debug("Checking correvents")
        db_correvents = DBSession.query(tables.CorrEvent).all()
        self.assertEquals(1, len(db_correvents))

        # 3. L'agrégat de l'étape 2 doit avoir été désagrégé.
        LOGGER.debug('Step 3')
        res, idcorrevent3 = yield self.handle_alert(
            self.hosts[1], 'UP')
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)

        # On a 2 événements bruts et 2 agrégats en base.
        LOGGER.debug("Checking events")
        self.assertEquals(2, DBSession.query(tables.Event).count())
        LOGGER.debug("Checking correvents")
        db_correvents = DBSession.query(tables.CorrEvent).all()
        self.assertEquals(2, len(db_correvents))
        db_correvents.sort(key=lambda x: x.cause.supitem.name)
        # Le premier à l'état "UP" et porte sur "Host 1".
        self.assertEquals(self.hosts[1].idhost,
                          db_correvents[0].cause.idsupitem)
        self.assertEquals(
            u'UP',
            tables.StateName.value_to_statename(
                db_correvents[0].cause.current_state)
        )
        # Le 2nd est "UNREACHABLE" et porte sur "Host 2".
        self.assertEquals(self.hosts[2].idhost,
                          db_correvents[1].cause.idsupitem)
        self.assertEquals(
            u'UNREACHABLE',
            tables.StateName.value_to_statename(
                db_correvents[1].cause.current_state)
        )

        # 4. Les événements doivent avoir été réagrégés.
        LOGGER.debug('Step 4')
        # 2 = id du nouveau correvent après désagrégation
        res, idcorrevent4 = yield self.handle_alert(
            self.hosts[1], 'DOWN', succs=[2])
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)
        self.assertEquals(idcorrevent4, idcorrevent1)

        # On a 2 événements bruts et 1 agrégat en base.
        LOGGER.debug("Checking events")
        self.assertEquals(2, DBSession.query(tables.Event).count())
        LOGGER.debug("Checking correvents")
        db_correvents = DBSession.query(tables.CorrEvent).all()
        self.assertEquals(1, len(db_correvents))
        # Il a l'état "DOWN", porte sur "Host 1"
        # et contient les 2 événements bruts.
        self.assertEquals(self.hosts[1].idhost,
                          db_correvents[0].cause.idsupitem)
        self.assertEquals(
            u'DOWN',
            tables.StateName.value_to_statename(
                db_correvents[0].cause.current_state)
        )
        self.assertEquals(
            [u'Host 1', u'Host 2'],
            sorted([ev.supitem.name for ev in db_correvents[0].events])
        )
Exemplo n.º 7
0
    def test_pseudo_triangle(self):
        """
        Désagrégation avec événements en pseudo-triangle.

        Lorsque 2 hôtes tombent et qu'un 3ème hôte dépendant des 2 premiers
        au sens de la topologie devient indisponible, l'événement brut sur
        ce 3ème hôte doit être agrégé dans les agrégats des 2 premiers.

        Lorsque le 1er hôte remonte, un agrégat séparé doit être créé pour
        sa dépendance. L'agrégat n'est pas affecté lorsque le 2nd hôte
        redevient opérationnel. On finit donc avec 3 agrégats actifs.
        """
        # Ajout des dépendances topologiques :
        # - Host 3 dépend de Host 1 et Host 2 (triangle).
        dep_group = functions.add_dependency_group(
                        self.hosts[3], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)
        functions.add_dependency(dep_group, self.hosts[2], 2)

        # Simule la chute des hôtes "Host 1" et "Host 2",
        # puis l'indisponibilité de l'hôte "Host 3"
        # qui dépend des 2 autres topologiquement.
        res, idcorrevent1 = yield self.handle_alert(self.hosts[1], 'DOWN')
        self.assertNotEquals(res, None)
        res, idcorrevent2 = yield self.handle_alert(self.hosts[2], 'DOWN')
        self.assertNotEquals(res, None)
        res, idcorrevent3 = yield self.handle_alert(
            self.hosts[3],
            'UNREACHABLE',
            preds=[idcorrevent1, idcorrevent2],
        )
        self.assertEquals(res, None) # Pas de nouvel agrégat créé.
        print "Finished step 1\n"
        self.assertNotEquals(idcorrevent1, None)
        self.assertNotEquals(idcorrevent2, None)
        self.assertEquals(idcorrevent3, None)
        # On s'attend à trouver 3 événements bruts et 2 agrégats.
        self.assertEquals(3, DBSession.query(tables.Event).count())
        self.assertEquals(2, DBSession.query(tables.CorrEvent).count())
        # L'événement brut sur "Host 3" a été agrégé dans les 2 autres.
        event3 = DBSession.query(tables.Event).filter(
            tables.Event.idsupitem == self.hosts[3].idhost).one()
        # ... donc il appartient à l'agrégat de l'hôte 1.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent1)
        self.assertTrue(event3 in correvent.events)
        # ... ainsi qu'à celui de l'hôte 2.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent2)
        self.assertTrue(event3 in correvent.events)

        # Simule la remontée de "Host 1" :
        # l'événement brut concernant "Host 3" doit être retiré
        # des agrégats de l'hôte 1 et de l'hôte 2.
        # Un nouvel agrégat doit avoir été créé pour l'accueillir.
        res, _idcorrevent = yield self.handle_alert(self.hosts[1], 'UP')
        print "Finished step 2\n"
        self.assertNotEquals(res, None)
        # On s'attend à trouver 3 événements bruts et 3 agrégats.
        self.assertEquals(3, DBSession.query(tables.Event).count())
        self.assertEquals(3, DBSession.query(tables.CorrEvent).count())
        # L'événement brut sur "Host 3" n'est plus l'agrégat de l'hôte 1.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent1)
        self.assertFalse(event3 in correvent.events)
        # ... ni dans celui de l'hôte 2.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent2)
        self.assertFalse(event3 in correvent.events)
        # ... en revanche, il dispose de son propre agrégat.
        correvent = DBSession.query(
                tables.CorrEvent
            ).join(
                (tables.Event, tables.Event.idevent ==
                    tables.CorrEvent.idcause),
            ).filter(tables.Event.idsupitem == self.hosts[3].idhost
            ).one()

        # "Host 2" remonte : rien ne change.
        res, _idcorrevent = yield self.handle_alert(self.hosts[2], 'UP')
        print "Finished step 3\n"
        self.assertNotEquals(res, None)
        # On s'attend à trouver 3 événements bruts et 3 agrégats.
        self.assertEquals(3, DBSession.query(tables.Event).count())
        self.assertEquals(3, DBSession.query(tables.CorrEvent).count())
        # L'événement brut sur "Host 3" n'est plus l'agrégat de l'hôte 1.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent1)
        self.assertFalse(event3 in correvent.events)
        # ... ni dans celui de l'hôte 2.
        correvent = DBSession.query(tables.CorrEvent).get(idcorrevent2)
        self.assertFalse(event3 in correvent.events)
        # ... en revanche, il dispose de son propre agrégat.
        correvent = DBSession.query(
                tables.CorrEvent
            ).join(
                (tables.Event, tables.Event.idevent ==
                    tables.CorrEvent.idcause),
            ).filter(tables.Event.idsupitem == self.hosts[3].idhost
            ).one()
Exemplo n.º 8
0
    def test_desaggregate(self):
        """Désagrégation des événements corrélés (#467)."""
        # Ajout des dépendances topologiques :
        # - Host 2 dépend de Host 1
        # - Host 4 dépend de Host 1
        # - Host 3 dépend de Host 4
        dep_group = functions.add_dependency_group(
                        self.hosts[2], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)

        dep_group = functions.add_dependency_group(
                        self.hosts[4], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[1], 1)

        dep_group = functions.add_dependency_group(
                        self.hosts[3], None, u'topology', u'|')
        functions.add_dependency(dep_group, self.hosts[4], 1)
        functions.add_dependency(dep_group, self.hosts[1], 2)

        # 1. Un 1er agrégat doit avoir été créé.
        res, idcorrevent1 = yield self.handle_alert(
            self.hosts[2], 'UNREACHABLE')
        print "Finished step 1\n"
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)
        self.assertNotEquals(idcorrevent1, None)
        # Un agrégat a été créé sur cet hôte...
        db_correvent = DBSession.query(tables.CorrEvent).get(idcorrevent1)
        self.assertEquals(self.hosts[2].idhost, db_correvent.cause.idsupitem)
        # ... dans l'état indiqué.
        self.assertEquals(
            u'UNREACHABLE',
            tables.StateName.value_to_statename(
                db_correvent.cause.current_state)
        )
        # ... contenant uniquement un événement (cause hôte 2).
        self.assertEquals(
            [u'Host 2'],
            [ev.supitem.name for ev in db_correvent.events]
        )

        # 2. Un nouvel agrégat doit avoir été créé et l'agrégat
        #    précédent doit avoir été fusionné dans celui-ci.
        res, idcorrevent2 = yield self.handle_alert(
            self.hosts[1], 'DOWN', succs=[idcorrevent1])
        print "Finished step 2\n"
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)
        self.assertNotEquals(idcorrevent2, None)
        # Il ne doit rester qu'un seul agrégat (le 1er a été fusionné).
        db_correvent = DBSession.query(tables.CorrEvent).one()
        self.assertEquals(db_correvent.idcorrevent, idcorrevent2)
        # ... dont la cause est l'hôte 1.
        self.assertEquals(self.hosts[1].idhost, db_correvent.cause.idsupitem)
        # ... dans l'état indiqué.
        self.assertEquals(
            u'DOWN',
            tables.StateName.value_to_statename(
                db_correvent.cause.current_state)
        )
        # ... ayant 2 événements bruts rattachés (cause hôte 1 + hôte 2).
        self.assertEquals(
            [u'Host 1', u'Host 2'],
            sorted([ev.supitem.name for ev in db_correvent.events])
        )

        # 3. Pas de nouvel agrégat, mais un nouvel événement brut (hôte 4)
        #    ajouté à l'agrégat de l'étape 2.
        res, idcorrevent3 = yield self.handle_alert(
            self.hosts[4], 'UNREACHABLE', preds=[idcorrevent2])
        print "Finished step 3\n"
        # Aucune erreur n'a été levée.
        self.assertEquals(res, None)
        self.assertEquals(idcorrevent3, None) # ajouté dans l'agrégat 2.
        # Toujours un seul agrégat.
        db_correvent = DBSession.query(tables.CorrEvent).one()
        self.assertEquals(db_correvent.idcorrevent, idcorrevent2)
        # ... dont la cause est l'hôte 1.
        self.assertEquals(self.hosts[1].idhost, db_correvent.cause.idsupitem)
        # ... dans l'état indiqué.
        self.assertEquals(
            u'DOWN',
            tables.StateName.value_to_statename(
                db_correvent.cause.current_state)
        )
        # ... ayant 3 événements bruts.
        self.assertEquals(
            [u'Host 1', u'Host 2', u'Host 4'],
            sorted([ev.supitem.name for ev in db_correvent.events])
        )

        # 4. Pas de nouvel agrégat, mais un nouvel événement brut (hôte 3)
        #    ajouté à l'agrégat de l'étape 2.
        res, idcorrevent4 = yield self.handle_alert(
            self.hosts[3], 'UNREACHABLE', preds=[idcorrevent2])
        print "Finished step 4\n"
        # Aucune erreur n'a été levée.
        self.assertEquals(res, None)
        self.assertEquals(idcorrevent4, None) # ajouté dans l'agrégat 2.
        # On a 4 événements bruts en base.
        self.assertEquals(4, DBSession.query(tables.Event).count())
        # On a toujours un seul agrégat.
        db_correvent = DBSession.query(tables.CorrEvent).one()
        self.assertEquals(db_correvent.idcorrevent, idcorrevent2)
        # ... dont la cause est l'hôte 1.
        self.assertEquals(self.hosts[1].idhost, db_correvent.cause.idsupitem)
        # ... dans l'état indiqué.
        self.assertEquals(
            u'DOWN',
            tables.StateName.value_to_statename(
                db_correvent.cause.current_state)
        )
        # ... ayant 3 événements bruts.
        self.assertEquals(
            [u'Host 1', u'Host 2', u'Host 3', u'Host 4'],
            sorted([ev.supitem.name for ev in db_correvent.events])
        )

        # 5. L'agrégat de l'étape 2 doit avoir été désagrégé
        #    en 3 agrégats, l'un signalant que l'hôte 1 est UP,
        #    un autre indiquant que l'hôte 2 est UNREACHABLE,
        #    le dernier donnant les hôtes 4 et 3 UNREACHABLE.
        res, idcorrevent5 = yield self.handle_alert(self.hosts[1], 'UP')
        print "Finished step 5\n"
        # Aucune erreur n'a été levée.
        self.assertNotEquals(res, None)
        # Désagrégé à partir de l'agrégat 2.
        self.assertEquals(idcorrevent5, idcorrevent2)
        # On a 4 événements bruts et 3 agrégats en base.
        print "events"
        self.assertEquals(4, DBSession.query(tables.Event).count())
        db_correvents = DBSession.query(tables.CorrEvent).all()
        print "correvents"
        self.assertEquals(3, len(db_correvents))
        db_correvents.sort(key=lambda x: x.cause.supitem.name)
        # L'un porte sur l'hôte 1 qui doit être dans l'état "UP"
        # et ne contient qu'un seul événement brut sur host 1.
        self.assertEquals(self.hosts[1].idhost,
                          db_correvents[0].cause.idsupitem)
        self.assertEquals(
            u'UP',
            tables.StateName.value_to_statename(
                db_correvents[0].cause.current_state)
        )
        self.assertEquals(
            [u'Host 1'],
            sorted([ev.supitem.name for ev in db_correvents[0].events])
        )
        # Le second porte sur l'hôte 2, qui se trouve toujours dans
        # l'état "UNREACHABLE" et n'a qu'un seul événement brut (host 2).
        self.assertEquals(self.hosts[2].idhost,
                         db_correvents[1].cause.idsupitem)
        self.assertEquals(
            u'UNREACHABLE',
            tables.StateName.value_to_statename(
                db_correvents[1].cause.current_state)
        )
        self.assertEquals(
            [u'Host 2'],
            sorted([ev.supitem.name for ev in db_correvents[1].events])
        )
        # Le dernier des agrégats porte sur l'hôte 4
        # qui se trouve dans l'état UNREACHABLE et
        # contient 2 événements bruts (host 4 et host 3).
        self.assertEquals(self.hosts[4].idhost,
                          db_correvents[2].cause.idsupitem)
        self.assertEquals(
            u'UNREACHABLE',
            tables.StateName.value_to_statename(
                db_correvents[2].cause.current_state)
        )
        self.assertEquals(
            [u'Host 3', u'Host 4'],
            sorted([ev.supitem.name for ev in db_correvents[2].events])
        )