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_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)
def before_delete(self, mapper, connection, instance): """ On utilise before_delete() plutôt qu' after_delete() parce qu'avec after_delete() le ON DELETE CASCADE s'est déjà produit et on a plus de MapNodeService correspondant en base. """ from vigilo.models.tables.mapnode import MapNodeHls mapnodes = DBSession.query(MapNodeHls).filter( MapNodeHls.idservice == instance.idservice ).all() for mapnode in mapnodes: DBSession.delete(mapnode) return EXT_CONTINUE
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)
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)
def test_remove_permission_single(self): """Retrait de permission sur un seul groupe.""" # Permettra de tester une tentative de suppression # sur le group3, en ignorant l'accès actuel. permissions = commands._permissions.copy() permissions[None] = None for incode in commands._permissions: print "Test permission %s" % incode self._set_permissions() if incode == "ro": group = self._group1 else: group = self._group3 options = NamespaceStub( permission=incode, object_type=self._type, usergroup=self._usergroup.group_name.encode('utf-8'), object_group=group.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_remove(options) self.assertEquals(res, 0) # On doit avoir 7 permissions en base : # les 8 de départ - 1 permission supprimée. dataperms = DBSession.query(tables.DataPermission).all() self.assertEquals(7, len(dataperms)) # On vérifie que la permission qu'on voulait supprimer # a effectivement été supprimée. dataperm = DBSession.query(tables.DataPermission ).filter(tables.DataPermission.idgroup == group.idgroup ).filter(tables.DataPermission.idusergroup == self._usergroup.idgroup ).first() self.assertEquals(None, dataperm) # Suppression des permissions pour le test # du type de permission suivant. for dataperm in DBSession.query(tables.DataPermission).all(): DBSession.delete(dataperm) DBSession.flush() dataperm = DBSession.query(tables.DataPermission).first() self.assertEquals(dataperm, None)
def test_hls_mapnode(self): """Suppression des mapnodes d'un hls supprimé (#57)""" # Mettre localhost sur une carte fct.add_host(u"localhost") s = fct.add_highlevelservice("testservice") testmap = fct.add_map(u"Test map") fct.add_node_hls(s, "testservice", testmap) DBSession.flush() DBSession.delete(s) DBSession.flush() # On vérifie que la suppression du hls a bien supprimé ses # représentations cartographiques mn_count = DBSession.query(tables.MapNode).count() self.assertEquals(mn_count, 0) mns_count = DBSession.query(tables.MapNodeService).count() self.assertEquals(mns_count, 0) mnlls_count = DBSession.query(tables.MapNodeHls).count() self.assertEquals(mnlls_count, 0)
def test_conffile(self): """Suppression des mapnodes d'un hôte d'un conffile""" # Mettre localhost sur une carte conffile = tables.ConfFile.get_or_create("/tmp/test_file") h = fct.add_host(u"localhost", conffile=conffile) testmap = fct.add_map(u"Test map") fct.add_node_host(h, "localhost", testmap) DBSession.flush() DBSession.delete(conffile) DBSession.flush() # On vérifie que la suppression du fichier de configuration # de l'hôte a bien supprimé les 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)
def test_remove_multiple_batch(self): """Retrait de permissions sur plusieurs groupes en mode batch.""" # Permettra de tester une tentative de suppression # de toutes les permissions, quelle que soit le type. permissions = commands._permissions.copy() permissions[None] = None for incode in permissions: print "Test permission %s" % incode self._set_permissions() 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_remove(options) self.assertEquals(res, 0) dataperms = DBSession.query(tables.DataPermission).all() if incode is None: # Les 4 permissions de l'utilisateur # doivent avoir été supprimées. # Il reste donc 8-4 permissions en base. self.assertEquals(4, len(dataperms)) else: # 2 permissions de l'utilisateur doivent avoir été supprimées. # Il en reste donc 8-2 en base. self.assertEquals(6, len(dataperms)) # 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_update(self): """Mise à jour des permissions.""" for (incode, outcode) in commands._permissions.iteritems(): print "Test permission %s" % incode # On simule l'existence d'une permission avant le début du test. # Si le test porte sur la permission "lecture seule", alors la # permission existante est en lecture/écriture et vice-versa. existing_perm = (incode == "ro") and "w" or "r" self._add_permission(self._group1, existing_perm) 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=True, commit=False, # la base de test est en mémoire, # en la committant, on perdrait tout. ) # La demande doit être rejetée car elle rentre # en conflit avec les permissions existantes. res = commands.cmd_add(options) self.assertEquals(res, 0) # Une seule permission doit exister en base de données. dataperm = DBSession.query(tables.DataPermission).one() # Le contenu de la permission doit avoir changé. self.assertEquals(self._usergroup.idgroup, dataperm.idusergroup) self.assertEquals(self._group1.idgroup, dataperm.idgroup) self.assertEquals(outcode, dataperm.access) # Suppression de la permission pour le test # du type de permission suivant. DBSession.delete(dataperm) DBSession.flush() DBSession.expunge_all() # Nécessaire pour éviter que l'ancienne # DataPerm ne soit "vue" à l'itération # suivante. dataperm = DBSession.query(tables.DataPermission).first() self.assertEquals(dataperm, None)
def test_first_successors_aggregates(self): """Récupération des premiers agrégats dépendant d'une alerte brute""" # On ajoute quelques événements et agrégats self.add_events_and_aggregates() # On supprime un agrégat DBSession.delete(self.events_aggregate2) DBSession.flush() # On ajoute un événement et un nouvel # agrégat dont cet événement est la cause. self.event3 = functions.add_event(self.service1, u'WARNING', 'WARNING: Processes are not responding') self.events_aggregate3 = functions.add_correvent([self.event3]) # On récupère les aggrégats causés par le service 5 ctx = self.context_factory(142, defer=True) ctx._connection._must_defer = False print "First step" aggregates = yield self.topology.get_first_successors_aggregates( ctx, self.database, self.service5.idservice ) aggregates.sort() # On vérifie que le service 5 n'a causé aucun agrégat directement. self.assertEqual(aggregates, []) # On récupère les aggrégats causés par le service 4 print "Second step" aggregates = yield self.topology.get_first_successors_aggregates( ctx, self.database, self.service4.idservice ) aggregates.sort() # On vérifie que le service 4 a bien causé l'agrégat 1 # (Et uniquement l'agrégat 1). self.assertEqual(aggregates, [self.events_aggregate1.idcorrevent])
def cleanup(self): # Presque rien à faire ici : la fin du load_conf se charge déjà # de supprimer les instances de ConfFile retirées du SVN, # ce qui a pour effet de supprimer les hôtes associés. # Elle supprime aussi les hôtes qui n'ont pas de fichier # attaché (résidus laissés lors de la migration vers ConfFile). # Il reste uniquement à vérifier qu'on a pas encore en base des # fichiers qui auraient disparu du disque (modif SVN manuelle par # exemple) LOGGER.debug("Checking for leftover ConfFiles") for conffilename in self.conffiles: # self.conffiles indexe les objets par leur ID, mais aussi # pas leur nom de fichier, on ne s'intéresse qu'à ces derniers. if not isinstance(conffilename, basestring): continue filename = os.path.join(settings["vigiconf"].get("confdir"), conffilename) if not os.path.exists(filename): LOGGER.warning(_("Deleting leftover config file from " "database: %s"), conffilename) DBSession.delete(self.conffiles[conffilename]) DBSession.flush()
def test_remove_multiple_error(self): """Pas de retrait de permissions sur plusieurs groupes par défaut.""" # Permettra de tester une tentative de suppression # de toutes les permissions, quelle que soit le type. permissions = commands._permissions.copy() permissions[None] = None for incode in permissions: print "Test permission %r" % (incode, ) self._set_permissions() 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=False, update=False, commit=False, # la base de test est en mémoire, # en la committant, on perdrait tout. ) # La commande a été rejetée. res = commands.cmd_remove(options) self.assertNotEquals(res, 0) # Aucune permission n'a été retirée. dataperms = DBSession.query(tables.DataPermission).all() self.assertEquals(8, len(dataperms)) # Suppression des permissions pour le test # du type de permission suivant. for dataperm in DBSession.query(tables.DataPermission).all(): DBSession.delete(dataperm) DBSession.flush() dataperm = DBSession.query(tables.DataPermission).first() self.assertEquals(dataperm, None)
def load_conf(self): LOGGER.info(_("Loading hosts")) # On récupère d'abord la liste de tous les hôtes # précédemment définis en base et le fichier XML # auquels ils appartiennent. previous_hosts = {} for conffile in DBSession.query(ConfFile).all(): self.conffiles[conffile.idconffile] = conffile self.conffiles[conffile.name] = conffile db_hosts = DBSession.query( Host.name, Host.idconffile, ).all() for db_host in db_hosts: previous_hosts[db_host.name] = self.conffiles[db_host.idconffile] hostnames = [] # On ne s'interresse qu'à ceux sur lesquels une modification # a eu lieu (ajout ou modification). On génère en même temps # un cache des instances des fichiers de configuration. for hostname in conf.hostsConf.keys(): filename = conf.hostsConf[hostname]["filename"] relfilename = filename[len(settings["vigiconf"].get("confdir"))+1:] if self.rev_mgr.file_changed(filename, exclude_removed=True): hostnames.append(hostname) # Peuple le cache en créant les instances à la volée si # nécessaire. if relfilename not in self.conffiles: LOGGER.debug(_("Registering new configuration file " "'%(relative)s' (from %(absolute)s)"), { 'relative': relfilename, 'absolute': filename, }) conffile = ConfFile(name=unicode(relfilename)) DBSession.flush() self.conffiles[unicode(relfilename)] = conffile self.conffiles[conffile.idconffile] = conffile # Utile pendant la migration des données : # les hôtes pour lesquels on ne possédait pas d'informations # quant au fichier de définition doivent être mis à jour. for hostname, conffile in previous_hosts.iteritems(): if conffile is None: hostnames.append(hostname) del previous_hosts # Fera office de cache des instances d'hôtes # entre les deux étapes de la synchronisation. hosts = {} hostnames = sorted(list(set(hostnames))) for hostname in hostnames: hostdata = conf.hostsConf[hostname] relfilename = hostdata['filename'] \ [len(settings["vigiconf"].get("confdir"))+1:] LOGGER.debug(_("Loading host %s"), hostname) hostname = unicode(hostname) host = dict(name=hostname, hosttpl=unicode(hostdata['hostTPL']), snmpcommunity=unicode(hostdata['snmpCommunity']), address=unicode(hostdata['address']), snmpport=hostdata['snmpPort'], snmpoidsperpdu=hostdata['snmpOIDsPerPDU'], weight=hostdata['weight'], snmpversion=unicode(hostdata['snmpVersion']), conffile=self.conffiles[unicode(relfilename)], ) host = self.add(host) hosts[hostname] = host # Synchronisation des tags de l'hôte. tag_loader = TagLoader(host, hostdata.get('tags', {})) tag_loader.load() if hostnames: LOGGER.debug("Preparing group cache") groups = DBSession.query(GroupPath).join( (Group, Group.idgroup == GroupPath.idgroup) ).filter(Group.grouptype == u'supitemgroup').all() for g in groups: self.group_cache[g.idgroup] = g.path self.group_cache[g.path] = g.idgroup for part in parse_path(g.path): self.group_parts_cache.setdefault(part, []).append(g.path) # Cache de l'association entre le nom d'un groupe de graphes # et son identifiant. graphgroups = {} for graphgroup in DBSession.query(GraphGroup).all(): graphgroups[graphgroup.name] = graphgroup for hostname in hostnames: hostdata = conf.hostsConf[hostname] host = hosts[hostname] # groupes LOGGER.debug("Loading groups for host %s", hostname) self._load_groups(host, hostdata) # services LOGGER.debug("Loading services for host %s", hostname) service_loader = ServiceLoader(host) service_loader.load() # directives Nagios de l'hôte LOGGER.debug("Loading nagios conf for host %s", hostname) nagiosconf_loader = NagiosConfLoader(host, hostdata['nagiosDirectives']) nagiosconf_loader.load() # données de performance LOGGER.debug("Loading perfdatasources for host %s", hostname) pds_loader = PDSLoader(host) pds_loader.load() # graphes LOGGER.debug("Loading graphs for host %s", hostname) graph_loader = GraphLoader(host, graphgroups) graph_loader.load() # Suppression des fichiers de configuration retirés du SVN # ainsi que de leurs hôtes (par CASCADE). LOGGER.debug("Cleaning up old hosts") removed = self.rev_mgr.get_removed() for filename in removed: relfilename = filename[len(settings["vigiconf"].get("confdir"))+1:] # Si un dossier est supprimé avec rm -rf, SVN ne signale que le # dossier, pas tous ses fichiers/sous-dossiers -> on doit utiliser # un LIKE pour les attrapper DBSession.query(ConfFile).filter(or_( ConfFile.name == unicode(relfilename), ConfFile.name.like(unicode(relfilename) + u"/%") )).delete(synchronize_session='fetch') LOGGER.debug("Done cleaning up old hosts") # Ghostbusters # 1- Hosts qui n'ont plus de fichier de configuration. nb_ghosts = DBSession.query( SupItem.__table__ ).filter( SupItem.__table__.c.idsupitem.in_( DBSession.query( Host.__table__.c.idhost ).filter(Host.__table__.c.idconffile == None) ) ).delete(synchronize_session=False) LOGGER.debug("Deleted %d ghosts [Host]", nb_ghosts) # 2a- SupItems censés être des hôtes, mais qui n'ont pas d'entrée # dans la table Host. nb_ghosts = DBSession.query( SupItem.__table__ ).filter( SupItem.__table__.c.idsupitem.in_( DBSession.query( SupItem.idsupitem ).outerjoin( (Host.__table__, Host.__table__.c.idhost == SupItem.__table__.c.idsupitem) ).filter( SupItem.__table__.c.itemtype == Host.__mapper_args__['polymorphic_identity'] ).filter(Host.__table__.c.idhost == None) ) ).delete(synchronize_session=False) # 2b- SupItems censés être des LLS, mais qui n'ont pas d'entrée # dans la table LowLevelService. nb_ghosts += DBSession.query( SupItem.__table__ ).filter( SupItem.__table__.c.idsupitem.in_( DBSession.query( SupItem.idsupitem ).outerjoin( (LowLevelService.__table__, LowLevelService.__table__.c.idservice == SupItem.__table__.c.idsupitem) ).filter( SupItem.__table__.c.itemtype == LowLevelService.__mapper_args__['polymorphic_identity'] ).filter(LowLevelService.__table__.c.idservice == None) ) ).delete(synchronize_session=False) # 2c- SupItems censés être des HLS, mais qui n'ont pas d'entrée # dans la table HighLevelService. nb_ghosts += DBSession.query( SupItem.__table__ ).filter( SupItem.__table__.c.idsupitem.in_( DBSession.query( SupItem.idsupitem ).outerjoin( (HighLevelService.__table__, HighLevelService.__table__.c.idservice == SupItem.__table__.c.idsupitem) ).filter( SupItem.__table__.c.itemtype == HighLevelService.__mapper_args__['polymorphic_identity'] ).filter(HighLevelService.__table__.c.idservice == None) ) ).delete(synchronize_session=False) LOGGER.debug("Deleted %d ghosts [SupItem]", nb_ghosts) # 3a- MapLinks censés être des MapServiceLink mais qui n'ont # pas d'entrée dans la table MapServiceLink. nb_ghosts = DBSession.query( MapLink.__table__ ).filter( MapLink.__table__.c.idmaplink.in_( DBSession.query( MapLink.idmaplink ).outerjoin( (MapServiceLink.__table__, MapServiceLink.__table__.c.idmapservicelink == MapLink.__table__.c.idmaplink) ).filter( MapLink.__table__.c.type_link.in_([ MapLlsLink.__mapper_args__['polymorphic_identity'], MapHlsLink.__mapper_args__['polymorphic_identity'], ]) ).filter(MapServiceLink.__table__.c.idmapservicelink == None) ) ).delete(synchronize_session=False) # 3b- MapLinks censés être des MapSegment mais qui n'ont # pas d'entrée dans la table MapSegment. nb_ghosts += DBSession.query( MapLink.__table__ ).filter( MapLink.__table__.c.idmaplink.in_( DBSession.query( MapLink.idmaplink ).outerjoin( (MapSegment.__table__, MapSegment.__table__.c.idmapsegment == MapLink.__table__.c.idmaplink) ).filter( MapLink.__table__.c.type_link == MapSegment.__mapper_args__['polymorphic_identity'] ).filter(MapSegment.__table__.c.idmapsegment == None) ) ).delete(synchronize_session=False) LOGGER.debug("Deleted %d ghosts [MapLink]", nb_ghosts) # 4a- MapNodes qui sont censés être des MapNodeHost mais qui # n'ont pas d'entrée dans la sous-table. nb_ghosts = DBSession.query( MapNode.__table__ ).filter( MapNode.__table__.c.idmapnode.in_( DBSession.query( MapNode.idmapnode ).outerjoin( (MapNodeHost.__table__, MapNodeHost.__table__.c.idmapnode == MapNode.__table__.c.idmapnode) ).filter( MapNode.__table__.c.type_node == MapNodeHost.__mapper_args__['polymorphic_identity'] ).filter(MapNodeHost.__table__.c.idmapnode == None) ) ).delete(synchronize_session=False) # 4b- MapNodes qui sont censés être des MapNodeService mais qui # n'ont pas d'entrée dans la sous-table. nb_ghosts += DBSession.query( MapNode.__table__ ).filter( MapNode.__table__.c.idmapnode.in_( DBSession.query( MapNode.idmapnode ).outerjoin( (MapNodeService.__table__, MapNodeService.__table__.c.idmapnode == MapNode.__table__.c.idmapnode) ).filter( MapNode.__table__.c.type_node.in_([ MapNodeLls.__mapper_args__['polymorphic_identity'], MapNodeHls.__mapper_args__['polymorphic_identity'], ]) ).filter(MapNodeService.__table__.c.idmapnode == None) ) ).delete(synchronize_session=False) LOGGER.debug("Deleted %d ghosts [MapNode]", nb_ghosts) # Suppression des hôtes qui ont été supprimés dans les fichiers # modifiés. deleted_hosts = [] for conffilename in self.conffiles: if not isinstance(conffilename, basestring): continue filename = os.path.join(settings["vigiconf"].get("confdir"), conffilename) if not self.rev_mgr.file_changed(filename): continue # ce fichier n'a pas bougé for host in self.conffiles[conffilename].hosts: if host.name not in hostnames: LOGGER.debug("Deleting '%s'", host.name) deleted_hosts.append(host) DBSession.delete(host) # Nettoyage des graphes et des groupes de graphes vides LOGGER.debug("Cleaning up old graphs") empty_graphs = DBSession.query( Graph ).filter( Graph.idgraph.in_( DBSession.query( Graph.idgraph ).outerjoin( (GRAPH_PERFDATASOURCE_TABLE, GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph ), ).filter(GRAPH_PERFDATASOURCE_TABLE.c.idgraph == None ) ) ).delete(synchronize_session=False) LOGGER.debug("Removed %r obsolete graphs", empty_graphs) # Si on a changé quelque chose, on le note en BDD. if hostnames or removed or deleted_hosts or empty_graphs: Change.mark_as_modified(u"Host") Change.mark_as_modified(u"Service") Change.mark_as_modified(u"Graph") DBSession.flush() LOGGER.info(_("Done loading hosts"))
def delete(self, instance): # pylint: disable-msg=R0201 LOGGER.debug("Deleting: %s", instance) DBSession.delete(instance)
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) # On notifie l'opération dans les logs user_name = user.user_name user_ip = request.remote_addr for s in silences: # Règle concernant un service de bas niveau if hasattr(s.supitem, 'servicename'): LOGGER.info(_( 'User %(user)s (IP: %(ip)s) deleted silence rule ' \ '#%(id)s for service %(service)s on host ' \
def load_conf(self): LOGGER.info(_("Loading ventilation")) current = {} apps_location = {} for v in DBSession.query(Ventilation).all(): current[(v.idhost, v.idvigiloserver, v.idapp)] = v apps_location.setdefault(v.idapp, set()).add(v.idvigiloserver) LOGGER.debug("Current ventilation entries: %d" % len(current)) vigiloservers = {} for vigiloserver in DBSession.query(VigiloServer).all(): vigiloservers[vigiloserver.name] = vigiloserver vigiloservers[vigiloserver.idvigiloserver] = vigiloserver applications = {} for application in DBSession.query(Application).all(): applications[application.name] = application applications[application.idapp] = application new_apps_location = {} for hostname, serversbyapp in self.ventilation.iteritems(): idhost = DBSession.query(Host.idhost).filter(Host.name == unicode(hostname)).scalar() if idhost is None: # on continue sans erreur pour être cohérent avec le # comportement du chargeur d'hôtes en cas de problème dans les # groupes (l.155) # Normalement ça devrait pas arriver parce que le ventilateur # fait déjà cette vérification LOGGER.warning( _("Can't load the ventilation in database: " "the host %s is not in database yet"), hostname ) continue for app_obj, servernames in serversbyapp.iteritems(): if isinstance(servernames, basestring): servernames = [servernames] # on ne met en base que le serveur nominal servername = servernames[0] vigiloserver = vigiloservers[unicode(servername)] application = applications[unicode(app_obj.name)] key = (idhost, vigiloserver.idvigiloserver, application.idapp) if key in current: del current[key] else: v = Ventilation(idhost=idhost, idvigiloserver=vigiloserver.idvigiloserver, idapp=application.idapp) DBSession.add(v) new_apps_location.setdefault(application.idapp, set()).add(vigiloserver.idvigiloserver) # DBSession.flush() # et maintenant on supprime ce qui reste LOGGER.debug("Obsolete ventilation entries: %d" % len(current)) for v in current.values(): DBSession.delete(v) # Vérifions qu'on a pas complètement supprimé une application d'un # serveur for idapp, app_servers in apps_location.iteritems(): new_app_servers = new_apps_location.get(idapp, set()) orphan_servers = app_servers - new_app_servers if not orphan_servers: continue dbapp = applications[idapp] if dbapp.name not in [a.name for a in self.applications]: LOGGER.warning( _( "The application %s has been removed from " "the configuration, it needs to be stopped " "manually" ), dbapp.name, ) continue for app in self.applications: if app.name == dbapp.name: break for idvserver in orphan_servers: vserver = vigiloservers[idvserver] app.add_server(vserver.name, ["stop"]) LOGGER.info(_("Done loading ventilation"))