def populate_DB(): """ Peuple la base de données. """ # On ajoute un groupe d'hôtes et un groupe de services. supitemmanagers = functions.add_supitemgroup(u'managersgroup') usergroup = UserGroup.by_group_name(u'users_with_access') DBSession.add(DataPermission( group=supitemmanagers, usergroup=usergroup, access=u'w', )) DBSession.flush() # On crée un 2 hôtes, et on les ajoute au groupe d'hôtes. host1 = functions.add_host(u'host1') host2 = functions.add_host(u'host2') supitemmanagers.supitems.append(host1) supitemmanagers.supitems.append(host2) DBSession.flush() # On crée 2 services de bas niveau, et on les ajoute au groupe de services. service1 = functions.add_lowlevelservice(host1, u'service1') service2 = functions.add_lowlevelservice(host2, u'service2') supitemmanagers.supitems.append(service1) supitemmanagers.supitems.append(service2) DBSession.flush() return ([host1, host2], [service1, service2])
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)
def populate_db(bind): from vigilo.models.session import DBSession from vigilo.models import tables permissions = { 'vigiboard-access': 'Gives access to VigiBoard', 'vigiboard-update': 'Allows users to update events', 'vigiboard-admin': 'Allows users to forcefully close open events', 'vigiboard-silence': 'Allows users to view and edit silence rules', } for (permission_name, description) in permissions.iteritems(): if not tables.Permission.by_permission_name(unicode(permission_name)): DBSession.add(tables.Permission( permission_name=unicode(permission_name), description=unicode(description), )) DBSession.flush()
def test_status_no_change(self): """RevMan: statut sans changement""" DBSession.add(tables.Version(name=RevisionManager.version_key, version=1)) DBSession.flush() status = self.rev_mgr.status() expected = {"added": [], "removed": [], "modified": []} self.assertEqual(status, expected)
def test_get_root_group_when_not_allowed(self): """Récupération des groupes racines de l'arbre sans les droits""" # Récupération du groupe utilisé lors de ce test. SupItemGroup.by_group_name(u'root') # Création d'un nouvel utilisateur et d'un nouveau groupe usergroup = UserGroup(group_name=u'new_users') vigiboard_perm = Permission.by_permission_name(u'vigiboard-access') usergroup.permissions.append(vigiboard_perm) user = User( user_name=u'new_user', fullname=u'', email=u'user.has.no@access', ) user.usergroups.append(usergroup) DBSession.add(user) DBSession.flush() transaction.commit() # L'utilisateur est authentifié mais n'a aucun accès. Il # cherche à obtenir la liste des groupes racines de l'arbre. response = self.app.get('/get_groups', extra_environ={'REMOTE_USER': '******'}) json = response.json # On s'assure que la liste retournée est bien vide. self.assertEqual( json, { 'items': [], 'groups': [] } )
def test_search_service_when_allowed_by_service(self): """ Teste la recherche par service avec des droits explicites (droits accordés car l'utilisateur a explicitement les droits sur ce service). """ # On crée un service avec une alerte. # Le service est rattaché à un groupe de services # pour lesquel l'utilisateur a les permissions. servicegroup = insert_deps()[1] usergroup = UserGroup.by_group_name(u'users') DBSession.add(DataPermission( group=servicegroup, usergroup=usergroup, access=u'r', )) DBSession.flush() transaction.commit() # On envoie une requête avec recherche sur le service créé, # on s'attend à recevoir 1 résultat. response = self.app.get('/?service=baz', extra_environ={'REMOTE_USER': '******'}) # Il doit y avoir 1 seule ligne de résultats. rows = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr') print "There are %d rows in the result set" % len(rows) assert_equal(len(rows), 1) # Il doit y avoir plusieurs colonnes dans la ligne de résultats. cols = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr/td') print "There are %d columns in the result set" % len(cols) assert_true(len(cols) > 1)
def populate_DB(): """ Peuple la base de données. """ # On ajoute un groupe d'hôtes et un groupe de services. supitemmanagers = SupItemGroup(name=u'managersgroup', parent=None) DBSession.add(supitemmanagers) DBSession.flush() usergroup = UserGroup.by_group_name(u'users_with_access') DBSession.add(DataPermission( group=supitemmanagers, usergroup=usergroup, access=u'r', )) DBSession.flush() # On crée un hôte de test, et on l'ajoute au groupe d'hôtes. managerhost = functions.add_host(u'managerhost') supitemmanagers.supitems.append(managerhost) DBSession.flush() # On crée un services de bas niveau, et on l'ajoute au groupe de services. managerservice = functions.add_lowlevelservice( managerhost, u'managerservice') supitemmanagers.supitems.append(managerservice) DBSession.flush() return (managerhost, managerservice)
def test_get_supitemgroups(self): """Récupération des groupes d'éléments supervisés accessibles.""" user = User(user_name=u'manager', email=u'', fullname=u'') DBSession.flush() usergroup = UserGroup(group_name=u'managers') usergroup.users.append(user) DBSession.flush() root = SupItemGroup(name=u'root', parent=None) DBSession.add(root) sub1 = SupItemGroup(name=u'sub1', parent=root) DBSession.add(sub1) sub2 = SupItemGroup(name=u'sub2', parent=root) DBSession.add(sub2) sub21 = SupItemGroup(name=u'sub21', parent=sub2) DBSession.add(sub21) DBSession.flush() dataperm = DataPermission( usergroup=usergroup, group=sub2, access=u'r', ) DBSession.add(dataperm) DBSession.flush() eq_([ (root.idgroup, False), (sub2.idgroup, True), (sub21.idgroup, True), ], user.supitemgroups())
def test_cache(self): """Teste le cache des noms d'états.""" row = DBSession.query(StateName).first() oldname = self.klass.value_to_statename(row.idstatename) row.statename = row.statename + u'_' DBSession.add(row) DBSession.flush() # On s'assure que le cache est bien utilisé : # ie. il renvoie l'ancien nom de l'état. currname = self.klass.value_to_statename(row.idstatename) assert_equals(oldname, currname) # De la même manière, le mapping inverse # fonctionne toujours avec l'ancien nom. assert_equals( row.idstatename, self.klass.statename_to_value(oldname) ) # On provoque un rafraîchissement du cache. assert_equals( row.idstatename, self.klass.statename_to_value(row.statename) ) try: self.klass.statename_to_value(oldname) except KeyError: # On s'attend à avoir une KeyError car l'ancien nom # n'existe plus (ni dans la base, ni dans le cache). pass except Exception, e: self.fail("Got an unexpected exception: %s (%s)" % (type(e), e))
def insert_hls_history(info_dictionary): """ Insère le nouvel état du service de haut niveau dans HLSHistory afin de conserver une trace. @param info_dictionary: Dictionnaire contenant les informations extraites du message d'alerte reçu par le rule dispatcher. @type info_dictionary: C{dict} """ if not info_dictionary['idsupitem']: LOGGER.error(_('Got a reference to a non configured high-level ' 'service (%(service)r)'), { "service": info_dictionary["service"], }) return None history = HLSHistory() history.idhls = info_dictionary['idsupitem'] # On enregistre l'heure à laquelle le message a # été traité plutôt que le timestamp du message. history.timestamp = datetime.now() history.idstatename = StateName.statename_to_value( info_dictionary['state']) DBSession.add(history)
def add_dependency(group, depended, distance=None): """ Ajoute une dépendance à un groupe de dépendances. @param group: Groupe de dépendance (identifiant ou instance). @type group: C{int} or L{tables.DependencyGroup} @param depended: Élément à ajouter au groupe de dépendance, sous la forme d'un tuple (hôte, service) décrivant l'élément à ajouter. @type depended: C{tuple} """ if isinstance(group, int): idgroup = group else: idgroup = group.idgroup if isinstance(depended, tables.SupItem): dependency = depended else: host, service = depended if host is None: # HLS dependency = tables.HighLevelService.by_service_name(unicode(service)) elif service is None: # Host dependency = tables.Host.by_host_name(unicode(host)) else: # LLS dependency = tables.LowLevelService.by_host_service_name( unicode(host), unicode(service)) DBSession.add(tables.Dependency( idgroup=idgroup, supitem=dependency, distance=distance, )) DBSession.flush()
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)
def db_commit(self): version_obj = Version.by_object_name(self.version_key) if version_obj is None: version_obj = Version(name=self.version_key) version_obj.version = self.deploy_revision DBSession.add(version_obj) DBSession.flush()
def _add_permission(self, group, perm): print "group = %r, perm = %r" % (unicode(group).encode('utf-8'), perm) DBSession.add(tables.DataPermission( idgroup=group.idgroup, idusergroup=self._usergroup.idgroup, access=unicode(perm), )) DBSession.flush()
def add_graphgroup(name, parent=None): name = unicode(name) g = tables.GraphGroup.by_parent_and_name(parent, name) if not g: g = tables.GraphGroup(name=name, parent=parent) DBSession.add(g) DBSession.flush() return g
def populate_DB(): """ Peuple la base de données en vue des tests. """ # On crée quatre hôtes de test. host1 = functions.add_host(u"host1") host2 = functions.add_host(u"host2") host3 = functions.add_host(u"host3") host4 = functions.add_host(u"host4") DBSession.flush() # On ajoute un service sur chaque hôte. service1 = functions.add_lowlevelservice(host2, u"service1") service2 = functions.add_lowlevelservice(host1, u"service2") service3 = functions.add_lowlevelservice(host3, u"service3") functions.add_lowlevelservice(host4, u"service4") DBSession.flush() # On crée un groupe de supitems et on y ajoute 'host1' et 'host4' en vue des # tests portant sur les permissions group1 = functions.add_supitemgroup(u"group1") DBSession.add(group1) functions.add_host2group(u"host1", u"group1") functions.add_host2group(u"host4", u"group1") DBSession.flush() # On ajoute 2 utilisateurs. functions.add_user(u"no_rights", u"*****@*****.**", u"no_rights", u"no_rights", u"no_rights") functions.add_user(u"limited_rights", u"*****@*****.**", u"limited_rights", u"limited_rights", u"limited_rights") functions.add_usergroup_permission(u"limited_rights", u"vigiboard-silence") functions.add_supitemgrouppermission(u"group1", u"limited_rights") DBSession.flush() # On ajoute 4 règles de mise en silence. functions.add_silence( states=[u"UNKNOWN"], host=host1, service=None, user=u"manager", comment=u"foo", date=u"2000-01-01 00:00:00" ) functions.add_silence( states=[u"DOWN"], host=host1, service=service2, user=u"unrestricted", comment=u"bar", date=u"2000-01-02 00:00:00", ) functions.add_silence( states=[u"WARNING", "CRITICAL"], host=host2, service=service1, user=u"unrestricted", comment=u"baz", date=u"2000-01-03 00:00:00", ) functions.add_silence( states=[u"DOWN"], host=host3, service=None, user=u"manager", comment=u"qux", date=u"2000-01-04 00:00:00" ) DBSession.flush() transaction.commit()
def do_get_dependencies(self): """Création des dépendances du test.""" ModelTest.do_get_dependencies(self) hls = functions.add_highlevelservice(u'HLS') host = functions.add_host(u'myhost') path = ImpactedPath(supitem=host) DBSession.add(path) DBSession.flush() return dict(path=path, hls=hls)
def setUp(self): """Initialisation avant chaque test.""" super(TestDetailsPluginMapsHostLimited, self).setUp() # On fait manuellement ce que l'initialisation de VigiMap ferait # (car on est dans les tests de VigiBoard, pas ceux de VigiMap). root = functions.add_mapgroup(u'Root') DBSession.add(Permission(permission_name=u'vigimap-access')) print "Creation hote, service et cartes" host = functions.add_host(u'localhost éçà') functions.add_lowlevelservice(host, u'lls éçà') sig = functions.add_supitemgroup(u'supitemgroup éçà') functions.add_host2group(host, sig) mg = functions.add_mapgroup(u'éçà', root) m1 = functions.add_map(u'M1', root) # La seconde carte appartient à "/Root/éçà" # et permet de tester les accès indirects. m2 = functions.add_map(u'M2', mg) m3 = functions.add_map(u'M3', root) # On ajoute l'hôte 2 fois sur M1 pour vérifier # l'absense de doublons dans les liens. print "Preparation cartes" functions.add_node_host(host, 'h1', m1) functions.add_node_host(host, 'h2', m1) functions.add_node_host(host, 'h', m2) functions.add_node_host(host, 'h', m3) # Création de quelques utilisateurs. print "Creation des comptes utilisateurs et reglages permissions" functions.add_user(u'restricted', u'*****@*****.**', u'restricted', u'restricted', u'restricted') functions.add_user(u'unrestricted', u'*****@*****.**', u'unrestricted', u'unrestricted', u'unrestricted') functions.add_user(u'no_rights', u'*****@*****.**', u'no_rights', u'no_rights', u'no_rights') # Les 3 utilisateurs ont accès à VigiBoard. functions.add_usergroup_permission(u'no_rights', u'vigiboard-access') functions.add_usergroup_permission(u'restricted', u'vigiboard-access') functions.add_usergroup_permission(u'unrestricted', u'vigiboard-access') # Mais seuls "restricted" et "unrestricted" ont accès à VigiMap. functions.add_usergroup_permission(u'restricted', u'vigimap-access') functions.add_usergroup_permission(u'unrestricted', u'vigimap-access') # Ils voient tous les trois les événements dans VigiBoard... functions.add_supitemgrouppermission(sig, 'no_rights') functions.add_supitemgrouppermission(sig, 'restricted') functions.add_supitemgrouppermission(sig, 'unrestricted') # ... mais "restricted" ne peut voir que "M2" ... functions.add_MapGroupPermission(mg, 'restricted') # ... tandis que "unrestricted" voit les 3 cartes (par héritage). functions.add_MapGroupPermission(root, 'unrestricted') DBSession.flush() transaction.commit()
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)
def _insert(): LOGGER.debug(_('Adding event #%(event)d (supitem #%(supitem)d) ' 'to aggregate #%(aggregate)d'), { 'event': idevent, 'supitem': idsupitem, 'aggregate': idcorrevent, }) DBSession.add(EventsAggregate(idevent=idevent, idcorrevent=idcorrevent)) DBSession.flush()
def populate_db(bind): from vigilo.models.session import DBSession from vigilo.models import tables permissions = {"vigigraph-access": "Gives access to VigiGraph"} for (permission_name, description) in permissions.iteritems(): if not tables.Permission.by_permission_name(unicode(permission_name)): DBSession.add(tables.Permission(permission_name=unicode(permission_name), description=unicode(description))) DBSession.flush()
def test_status_dir_added(self): """RevMan: statut après ajout d'un dossier""" testdir = os.path.join(self.confdir, "testdir") os.mkdir(testdir) self._run_svn(["add", testdir]) self._run_svn(["commit", "-m", "test", self.confdir]) DBSession.add(tables.Version(name=RevisionManager.version_key, version=1)) DBSession.flush() status = self.rev_mgr.status() expected = {"added": [testdir], "removed": [], "modified": []} self.assertEqual(status, expected)
def close_green(logger, options): """ Cette fonction ferme les événements qui apparaissent en vert dans VigiBoard (c'est-à-dire ceux dans l'état "OK" ou "UP"). @param logger: Logger à utiliser pour afficher des messages. @type logger: C{logging.Logger} @param options: Liste d'options demandées par l'utilisateur du script. @type options: C{optparse.Values} @return: Nombre d'événements qui ont été fermés automatiquement. @rtype: C{int} """ from vigilo.models.session import DBSession from vigilo.models.tables import Event, CorrEvent, StateName, EventHistory sought_states = [] if options.state_up: sought_states.append(StateName.statename_to_value(u'UP')) if options.state_ok: sought_states.append(StateName.statename_to_value(u'OK')) query = DBSession.query( CorrEvent ).join( (Event, Event.idevent == CorrEvent.idcause), ).filter(Event.current_state.in_(sought_states) ).filter(CorrEvent.ack != CorrEvent.ACK_CLOSED) if options.days is not None and options.days > 0: # Génère une date qui se trouve options.days jours dans le passé. old_date = datetime.fromtimestamp(time.time() - options.days * 86400) query = query.filter(CorrEvent.timestamp_active <= old_date) events = query.all() username = unicode(pwd.getpwuid(os.getuid())[0]) for event in events: logger.info(_('closing event on %s') % event.cause.supitem) # On ajoute un message dans l'historique pour la traçabilité. history = EventHistory( type_action=u"Acknowledgement change state", idevent=event.idcause, value=u"", text=u"Automatically marked the event as closed", username=username, timestamp=datetime.now(), ) DBSession.add(history) # On referme l'événement. event.ack = CorrEvent.ACK_CLOSED DBSession.flush() return len(events)
def populate_db(bind): """ Initialisation de la base de données pour VigiConf. """ scm_version = tables.Version.by_object_name(RevisionManager.version_key) if scm_version is None: scm_version = tables.Version( name=RevisionManager.version_key, version=0 ) DBSession.add(scm_version) DBSession.flush()
def add_dependency_group(host, service, role, operator='&'): """ Ajoute un groupe de dépendances. @param host: Hôte sur lequel porte le groupe de dépendances ou None si le groupe porte sur un service de haut niveau. @type host: C{basestring} ou None @param service: Service de l'hôte sur lequel porte le groupe de dépendances ou None s'il porte sur l'hôte lui-même. @type service: C{basestring} ou None @param role: Rôle de ce groupe de dépendances. Peut valoir "hls" pour indiquer qu'il s'agit des dépendances d'un service de haut niveau, ou "topology" pour indiquer qu'il s'agit de dépendances topologiques. @type role: C{str} @param operator: Type d'opérateur de dépendance. Peut valoir "+" (type PLUS), "&" (type ET) ou "|" (type OU). @note: Le type d'opérateur de dépendance n'a de sens que lorsque L{role} vaut "hls". """ if role != 'hls' and role != 'topology': raise ValueError('Valid roles: "hls" or "topology"') if isinstance(host, tables.Host): host = host.name service = None if isinstance(service, tables.LowLevelService): host = service.host.name service = service.servicename if isinstance(service, tables.HighLevelService): host = None service = service.servicename if host is None: # HLS dependent = tables.HighLevelService.by_service_name(unicode(service)) elif service is None: # Host dependent = tables.Host.by_host_name(unicode(host)) else: # LLS dependent = tables.LowLevelService.by_host_service_name( unicode(host), unicode(service)) dg = DBSession.query(tables.DependencyGroup).filter( tables.DependencyGroup.dependent == dependent).first() if dg: return dg group = tables.DependencyGroup( operator=unicode(operator), role=unicode(role), dependent=dependent, ) DBSession.add(group) DBSession.flush() return group.idgroup
def test_status_file_added(self): """RevMan: statut après ajout d'un fichier""" testdir = os.path.join(self.confdir, "hosts") testfile = os.path.join(testdir, "dummy.xml") open(testfile, "w").close() self._run_svn(["add", testfile]) self._run_svn(["commit", "-m", "test", self.confdir]) DBSession.add(tables.Version(name=RevisionManager.version_key, version=1)) DBSession.flush() status = self.rev_mgr.status() expected = {"added": [testfile], "removed": [], "modified": []} self.assertEqual(status, expected)
def test_get_children_limit(self): """L'option limit de get_children doit limiter le nombre retourné""" for i in range(10): child = self.klass(name=u"achild%d" % i) DBSession.add(child) DBSession.add(GroupHierarchy( parent=self.obj, child=child, hops=1, )) DBSession.flush() assert_equal( 5, len(self.obj.get_children(limit=5)) )
def __init__(self, **kwargs): """ Initialise l'instance avec les informations du groupe. @param kwargs: Un dictionnaire avec les informations sur le groupe. @type kwargs: C{dict} """ # Ajoute une boucle dans la hiérarchie des groupes pour ce groupe, # ce qui faciliter les tests sur l'héritage et la construction de # la hiérarchie elle-même. DBSession.add(GroupHierarchy(parent=self, child=self, hops=0)) super(Group, self).__init__(**kwargs)
def make_dependencies(self): """Création de quelques dépendances dans la BDD.""" host = Host( name=u"server.example.com", hosttpl=u"", address=u"127.0.0.1", snmpcommunity=u"public", snmpport=42, weight=42, ) DBSession.add(host) DBSession.flush()
def test_get_children(self): """Récupération des groupes fils.""" child = self.klass(name=u"achild") DBSession.add(child) DBSession.add(GroupHierarchy( parent=self.obj, child=child, hops=1, )) DBSession.flush() assert_equal( [child, ], self.obj.get_children() )