scripts/gestion/hptools2/tools.py
Pierre-Elliott Bécue 2bc93d071b Permet de spécifier une liste dans populate_all_switches
* Grâce à cela, populate_all_switches peut être restreint à une liste
 spécifique de switches pour éviter de forcément tout peupler.
2015-08-22 04:34:58 +02:00

130 lines
4.3 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
"""Fournit des outils et fonctions appelables au besoin"""
from gestion import annuaires_pg
from multiprocessing import Process, Manager
from .switch import HPSwitch
from .mac import MACFactory, format_mac
def filter_uplink(switch, stuff):
"""Filtre les prises uplink d'un retour.
stuff est une liste de la forme
[(port_id, mac), ...]"""
sortie = []
# Retourne "batg", "4.adm.crans.org", par exemple.
bat, num = switch.split('-', 1)
# On filtre ce qui n'est pas utile.
bat = bat[-1]
num = int(num[0])
# On récupère les infos utiles.
uplink = annuaires_pg.uplink_prises[bat]
gen_num_prise = 100 * num
for (port_id, mac) in stuff:
num_prise = gen_num_prise + port_id
if not num_prise in uplink:
sortie.append((port_id, mac))
return sortie
# +--------------------------------------------------------+
# | Mac Tracking Functions |
# +--------------------------------------------------------+
"""Ces fonctions servent à tracker une mac sur le réseau.
La fonction trace_mac s'occupe de ce travail. Elle utilise
la librairie multiprocessing pour spawner un process par
switch, et aller récupérer auprès de ceux-ci la liste des
MACs connectées, et les ports allant bien.
Multiprocessing ne mettant pas en place du partage de variable
par défaut, les objets retournés le sont via un Manager, dans
un dico, sans structure complexe.
Une solution dans laquelle les switches seraient renvoyés dans
leur structure python existe, mais elle est plus coûteuse,
et peu utile dans notre cas. (l'overhead engendré par la méthode
à base de dicos et régénération dans le processus parent est
epsilonesque)"""
def fetch_all_ports(switch, output):
"""Récupère l'ensemble des ports d'un switch, avec les MACS
dessus."""
sw = HPSwitch(switch)
# output est un Manager().dict()
__stuff = sw.fetch_all_ports()
__stuff = filter_uplink(switch, __stuff)
output[switch] = __stuff
def populate_all_switches(switches=None):
"""Remplit l'ensemble des switches avec les MACS qui sont
présentes sur leurs ports.
Peut également ne remplir qu'une liste spécifique si fournie
en argument."""
if switches == None:
switches = annuaires_pg.all_switchs()
hp_switches = {
switch : HPSwitch(switch)
for switch in switches
}
processes = {}
# La sortie des appels de fetch_all_ports sera écrite dans ce dico.
# On évitera la concurrence en utilisant le nom du switch comme
# séparateur
output = Manager().dict()
# Dans une première boucle, on crée les switches. Et on met
# les processes en mode actif.
for switch in switches:
hp_switches[switch].flush_ports()
processes[switch] = Process(target=fetch_all_ports, args=(switch, output), name=switch)
processes[switch].start()
# On fait la jointure des processes dans une seconde
# boucle, pour s'assurer que les processes ont bien
# tous été lancés avant de commencer à les sonder.
for switch in switches:
processes[switch].join()
for switch in switches:
if output[switch] is not None:
for (iid, val) in output[switch]:
if hp_switches[switch].ports.get(iid, None) is not None:
hp_switches[switch].ports[iid].append_mac(val)
else:
print "Output for switch %s is None." % (switch,)
def trace_mac(mac, in_all_switches=False):
"""Cherche une MAC. Si in_all_switches est à True, commence
par instancier tous les switches, et à les peupler.
Cette méthode est assez agressive, il faut l'utiliser avec
précaution."""
if in_all_switches:
populate_all_switches()
mac = format_mac(mac)
# On boucle sur les macs dans la factory
__mac = MACFactory.get_mac(mac)
if __mac is not None:
# On boucle sur les parents (des ports) à la recherche
# de ceux qui appartiennent au switch courant.
__parents = []
for parent in __mac.parents.itervalues():
__parents.append(parent)
# Si on en a trouvé, on les retourne avec la mac.
if __parents:
return (__mac, __parents)
return None