[switchs.py] utf-8 + début de ménage
This commit is contained in:
parent
f7abf46550
commit
adebfe1ea0
1 changed files with 49 additions and 104 deletions
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" met à jour les propriétés des prises des switchs du bat :
|
||||
mac autorisée(s), état (activé ou non) et nom de la prise
|
||||
""" met à jour les propriétés des prises des switchs du bat :
|
||||
mac autorisée(s), état (activé ou non) et nom de la prise
|
||||
argument : nom du switch
|
||||
|
||||
procédure de configuration initiale :
|
||||
procédure de configuration initiale :
|
||||
* mot de passe admin (password manager user-name <username>)
|
||||
* activation du ssh (crypto key generate ssh)
|
||||
* copie fichier de conf
|
||||
|
@ -23,9 +23,10 @@ from ldap_crans import crans_ldap, BorneWifi
|
|||
from annuaires_pg import uplink_prises, reverse, bat_manuels, all_switchs, bat_switchs
|
||||
from random import shuffle
|
||||
from gen_confs import *
|
||||
from time import localtime
|
||||
import datetime
|
||||
import config
|
||||
import re
|
||||
from crans.deprecated import deprecated
|
||||
|
||||
capture_model = re.compile(r'\((.*)\)')
|
||||
headers_by_model = {
|
||||
|
@ -38,27 +39,20 @@ headers_by_model = {
|
|||
|
||||
gigabit_models = ['J9021A', 'J9145A']
|
||||
|
||||
try:
|
||||
any
|
||||
except NameError:
|
||||
def any(iterable):
|
||||
for item in iterable:
|
||||
if item:
|
||||
return True
|
||||
return False
|
||||
|
||||
class switch(gen_config) :
|
||||
# Répertoire ou écire les fichiers de conf
|
||||
CONF_REP='/tmp/' # avec un / derrière
|
||||
"""Classe de configuration d'un switch"""
|
||||
# Répertoire ou écire les fichiers de conf
|
||||
CONF_REP='/tmp/' # avec un / derrière
|
||||
|
||||
config = """%(switch_config_header)s
|
||||
|
||||
hostname "%(switch)s"
|
||||
; Generated %(date_gen)s by switchs.py
|
||||
%(module-type)s
|
||||
;-------------------------------------------------------- Snmp
|
||||
snmp-server contact "root@crans.org"
|
||||
snmp-server location "Batiment %(bat)s"
|
||||
;A faire à la main
|
||||
;A faire à la main
|
||||
snmpv3 enable
|
||||
snmpv3 restricted-access
|
||||
;snmpv3 user "initial"
|
||||
|
@ -121,7 +115,7 @@ vlan %(vlan_appts)s
|
|||
exit
|
||||
;-------------------------------------------------------- Logs
|
||||
%(INTERFACES_CONF)s
|
||||
;------------------------------------------------------- Accès d'administration
|
||||
;------------------------------------------------------- Accès d'administration
|
||||
no telnet-server
|
||||
no web-management
|
||||
aaa authentication ssh login public-key none
|
||||
|
@ -144,7 +138,7 @@ no cdp run
|
|||
no stack
|
||||
"""
|
||||
|
||||
# Serveur DHCP des différent vlans
|
||||
# Serveur DHCP des différent vlans
|
||||
dhcp_servers = {
|
||||
'1':'138.231.136.34',
|
||||
'3':'138.231.148.34',
|
||||
|
@ -187,7 +181,7 @@ exit
|
|||
* un _tulpe_ de noms de switch => reconfig de ces swiths"""
|
||||
self.db = crans_ldap() # connexion LDAP
|
||||
if type(truc) == list :
|
||||
# On enlève les chambres "CRA", "????" et EXT qui n'ont pas besion de config
|
||||
# On enlève les chambres "CRA", "????" et EXT qui n'ont pas besion de config
|
||||
self.chbres = [ch for ch in truc if (ch not in [ "CRA", "????", "EXT" ]) ]
|
||||
self.switch = None
|
||||
else :
|
||||
|
@ -199,10 +193,10 @@ exit
|
|||
|
||||
def restart(self) :
|
||||
if self.chbre :
|
||||
# Tout est déja fait
|
||||
# Tout est déja fait
|
||||
return
|
||||
####### Vu qu'il n'y a pas de serveur tftp ici
|
||||
# on excécute pas le truc en dessous
|
||||
# on excécute pas le truc en dessous
|
||||
#for switch in self.switch :
|
||||
# self.aff = anim('\treboot de %s' % switch)
|
||||
# sw = hptools.switch(switch)
|
||||
|
@ -217,61 +211,11 @@ exit
|
|||
for switch in self.switch :
|
||||
self.configure_switch(switch)
|
||||
|
||||
@deprecated
|
||||
def configure_chbre(self,chbre) :
|
||||
""" Recontigure la chambre fournie chambre """
|
||||
try :
|
||||
bat = chbre[0].lower()
|
||||
if bat in bat_switchs :
|
||||
prise = sw_chbre(chbre)
|
||||
prise.reconfigure() # Vitesse et nom (juste au cas ou ca aurait changé)
|
||||
elif bat in bat_manuels :
|
||||
class prise_non_manageable :
|
||||
def __init__(self,chbre) :
|
||||
self.chbre = chbre
|
||||
|
||||
def __mail(self,sujet) :
|
||||
To = "clef%s@crans.org" % self.chbre[0].lower()
|
||||
From = To
|
||||
conn=smtplib.SMTP('localhost')
|
||||
txt_mail = "From: Crans scripts <%(From)s>\n"
|
||||
txt_mail+= "To: %(To)s\n"
|
||||
txt_mail+= "Subject: (CRANS) %s\n\nMerci." % sujet
|
||||
conn.sendmail(From, To , txt_mail % { 'From' : From, 'To' : To })
|
||||
conn.quit()
|
||||
|
||||
def disable(self) :
|
||||
self.__mail("Chambre %s à débrancher." % self.chbre)
|
||||
def enable(self) :
|
||||
self.__mail("Chambre %s à brancher." % self.chbre)
|
||||
|
||||
prise=prise_non_manageable(chbre)
|
||||
|
||||
else :
|
||||
# Rien a faire
|
||||
print OK
|
||||
return True
|
||||
|
||||
|
||||
a = self.db.search('chbre=%s&paiement=ok' % chbre)
|
||||
a = a['adherent'] + a['club']
|
||||
if a and 'bloq' not in a[0].blacklist_actif() :
|
||||
# Il faut activer la prise
|
||||
anim('\tactivation chbre %s' % chbre)
|
||||
prise.enable()
|
||||
else :
|
||||
# Il faut désactiver la prise
|
||||
anim('\tdésactivation chbre %s' % chbre)
|
||||
prise.disable()
|
||||
|
||||
print OK
|
||||
except :
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
return True
|
||||
""" Recontigure la chambre fournie chambre.
|
||||
Déprécié. Tous les switchs possèdent une authentification radius."""
|
||||
return False
|
||||
|
||||
def configure_switch(self,switch) :
|
||||
self.aff = anim('\tconfiguration de %s' % switch)
|
||||
|
@ -291,9 +235,9 @@ exit
|
|||
return 1
|
||||
|
||||
def __configure_switch(self,switch) :
|
||||
""" Génère le fichier de conf du switch donné """
|
||||
### Récupération données du switch
|
||||
# Batiment et numéro du switch
|
||||
""" Génère le fichier de conf du switch donné """
|
||||
### Récupération données du switch
|
||||
# Batiment et numéro du switch
|
||||
bat = switch[3].lower()
|
||||
sw_num = int(switch[5])
|
||||
dhcp_servers = self.dhcp_servers
|
||||
|
@ -303,12 +247,13 @@ exit
|
|||
|
||||
self.aff.cycle()
|
||||
|
||||
## On veut par défaut tout confier au serveur radius principal
|
||||
## On veut par défaut tout confier au serveur radius principal
|
||||
#shuffle(self.rad_servs)
|
||||
rad = self.rad_template * len(self.rad_servs)
|
||||
|
||||
|
||||
params = { 'switch' : switch, 'bat' : bat.upper() ,
|
||||
'date_gen': str(datetime.datetime.now()),
|
||||
'radius_key' : radius_key ,
|
||||
'radius-serveurs' : rad[:-1] % tuple(self.rad_servs),
|
||||
}
|
||||
|
@ -328,7 +273,7 @@ exit
|
|||
res, msg = commands.getstatusoutput("scp bat%s-%i:cfg/startup-config %s" % (bat, sw_num, old_config.name))
|
||||
|
||||
if res != 0:
|
||||
raise RuntimeError(u"Erreur : impossible de récupérer l'ancienne configuration du switch")
|
||||
raise RuntimeError(u"Erreur : impossible de récupérer l'ancienne configuration du switch")
|
||||
|
||||
params['switch_config_header'] = old_config.readline()
|
||||
old_config.close()
|
||||
|
@ -346,7 +291,7 @@ exit
|
|||
sys.stderr.write(model)
|
||||
params['switch_config_header']=headers_by_model[model]
|
||||
except:
|
||||
sys.stderr.write('Impossible de déterminer le header à utiliser (switch %s)' % switch)
|
||||
sys.stderr.write('Impossible de déterminer le header à utiliser (switch %s)' % switch)
|
||||
params['switch_config_header']= '; J4899A Configuration Editor; Created on release #H.10.50'
|
||||
|
||||
model = params['switch_config_header'].split(' ', 2)[1]
|
||||
|
@ -357,10 +302,10 @@ exit
|
|||
|
||||
self.aff.cycle()
|
||||
|
||||
# Nombre de prises et modèle
|
||||
# Nombre de prises et modèle
|
||||
nb_prises = machine.nombrePrises()
|
||||
if nb_prises < 0 :
|
||||
raise RuntimeError("Erreur : impossible de déterminer les caractéristiques du switch.")
|
||||
raise RuntimeError("Erreur : impossible de déterminer les caractéristiques du switch.")
|
||||
|
||||
has_dhcp_snooping = "2810" not in " ".join(machine.info())
|
||||
|
||||
|
@ -370,7 +315,7 @@ exit
|
|||
# Dictionnaire prise -> chambre
|
||||
prise_chbres = reverse(bat)
|
||||
|
||||
# Prises occupées par des machines du Cr@ns
|
||||
# Prises occupées par des machines du Cr@ns
|
||||
crans_prises={}
|
||||
for m in self.db.search('prise=%s%i*' % (bat.upper(), sw_num))['machine'] :
|
||||
try: crans_prises[m.prise()].append(m)
|
||||
|
@ -378,7 +323,7 @@ exit
|
|||
|
||||
self.aff.iter = nb_prises+1
|
||||
|
||||
# Paramètres à affecter
|
||||
# Paramètres à affecter
|
||||
for key in ( 'uplinks', 'non_uplinks' ) :
|
||||
params[key] = []
|
||||
|
||||
|
@ -387,21 +332,21 @@ exit
|
|||
'adm_tagged' : [] , 'adm_untagged' : [] ,
|
||||
'appts_tagged' : [], 'appts_untagged' : [],
|
||||
|
||||
# VLans pour le reste: le vlan des adhérents, des
|
||||
# VLans pour le reste: le vlan des adhérents, des
|
||||
# inconnus et de ceux qui ne paie pas
|
||||
'default' : [] }
|
||||
|
||||
personnels_loges = self.db.search('etudes=Personnel ENS')['adherent']
|
||||
prises_appartements= [ p.chbre() for p in personnels_loges ]
|
||||
|
||||
# Génération de la conf de chaque prise
|
||||
# Génération de la conf de chaque prise
|
||||
for prise in range(1,nb_prises+1):
|
||||
self.aff.cycle()
|
||||
|
||||
# Conf par défaut : activée, autonégociation
|
||||
# Conf par défaut : activée, autonégociation
|
||||
prise_params = { 'prise' : prise , 'speed' : '',
|
||||
'etat' : '', 'no_flowcontrol': '' }
|
||||
annu_prise = '%i%02i' % (sw_num, prise) # prise telle que notée dans l'annuaire
|
||||
annu_prise = '%i%02i' % (sw_num, prise) # prise telle que notée dans l'annuaire
|
||||
|
||||
if uplink_prises[bat].has_key(int(annu_prise)) :
|
||||
### Prise d'uplink
|
||||
|
@ -419,7 +364,7 @@ exit
|
|||
params['non_uplinks'].append(prise)
|
||||
|
||||
if crans_prises.has_key("%s%s" % (bat.upper(), annu_prise)) :
|
||||
### Prise réservée à l'association
|
||||
### Prise réservée à l'association
|
||||
wifi=0
|
||||
adm=0
|
||||
autres=0
|
||||
|
@ -466,7 +411,7 @@ exit
|
|||
# chambres.
|
||||
chbres = prise_chbres.get(annu_prise, [])
|
||||
|
||||
# Pour les switchs gigabit, on bloque le gigabit par défaut, sauf
|
||||
# Pour les switchs gigabit, on bloque le gigabit par défaut, sauf
|
||||
# pour les membres actifs et les clubs (cf plus bas)
|
||||
if model in gigabit_models:
|
||||
prise_params['speed'] = 'speed-duplex auto-10-100'
|
||||
|
@ -478,7 +423,7 @@ exit
|
|||
# On selectionne les eventuels adherents y residant
|
||||
residents = self.db.search("chbre=%s%s" % (bat, chb))
|
||||
for adherent in residents['adherent']:
|
||||
if adherent.droits(): #Seuls les membres actifs ont le droit à plus
|
||||
if adherent.droits(): #Seuls les membres actifs ont le droit à plus
|
||||
prise_params['speed'] = ''
|
||||
# On selectionne les machines fixes de l'adherent, et on ajoute le nombre au quota
|
||||
nombre_de_machines += len(adherent.machines_fixes())
|
||||
|
@ -487,9 +432,9 @@ exit
|
|||
|
||||
# Authentification RADIUS, pas pour les clubs...
|
||||
if not any("cl" in chbre.lower() for chbre in chbres):
|
||||
# "unauth-vid" est le vlan sur lequel sont envoyés les machines
|
||||
# quand l'authentification RADIUS échoue. On met le VLAN 1 pour
|
||||
# éviter les problèmes quand LDAP se ch@#! dessus.
|
||||
# "unauth-vid" est le vlan sur lequel sont envoyés les machines
|
||||
# quand l'authentification RADIUS échoue. On met le VLAN 1 pour
|
||||
# éviter les problèmes quand LDAP se ch@#! dessus.
|
||||
params['INTERFACES_CONF'] += """aaa port-access mac-based %(prise)s
|
||||
aaa port-access mac-based %(prise)s addr-limit %(nbmac)s
|
||||
aaa port-access mac-based %(prise)s logoff-period 3600
|
||||
|
@ -497,11 +442,11 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
""" % { 'nbmac': 2 + nombre_de_machines, 'prise': prise }
|
||||
# On regle le nombre de machines connectables a la prise au nombre de machines
|
||||
# sur cette prise dans l'annuaire plus 2
|
||||
else: # ... et pour les clubs, vlans par défaut
|
||||
else: # ... et pour les clubs, vlans par défaut
|
||||
vlans['default'].append(prise)
|
||||
|
||||
# On donne à la prise un nom qui dépend des chambres
|
||||
# connectés dessus
|
||||
# On donne à la prise un nom qui dépend des chambres
|
||||
# connectés dessus
|
||||
if chbres :
|
||||
prise_params['nom'] = 'Chambre'
|
||||
if len(chbres) > 1 : prise_params['nom'] += 's'
|
||||
|
@ -522,7 +467,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
|
||||
# Petite verif
|
||||
if not params['uplinks'] or not params['non_uplinks'] :
|
||||
raise RuntimeError('Switch sans uplink ou sans prise adhérent.')
|
||||
raise RuntimeError('Switch sans uplink ou sans prise adhérent.')
|
||||
|
||||
def mk_list(liste_prise) :
|
||||
"""
|
||||
|
@ -544,12 +489,12 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
if nouveau == groupe[1] + 1 :
|
||||
groupe[1] += 1
|
||||
else :
|
||||
# Ajout du groupe au résultat
|
||||
# Ajout du groupe au résultat
|
||||
if groupe[0] == groupe[1] :
|
||||
result.append(str(groupe[0]))
|
||||
else :
|
||||
result.append('-'.join(map(str,groupe)))
|
||||
# Réinit de groupe
|
||||
# Réinit de groupe
|
||||
groupe = [ nouveau, nouveau ]
|
||||
|
||||
return ','.join(result)
|
||||
|
@ -563,7 +508,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
for key, prises in vlans.items() :
|
||||
vlans[key]=mk_list(prises)
|
||||
|
||||
# Config des vlans spéciaux (adm, wifi et appartements)
|
||||
# Config des vlans spéciaux (adm, wifi et appartements)
|
||||
for v in ('adm', 'wifi', 'hotspot', 'appts') :
|
||||
params['prises_%s' % v] = ''
|
||||
for t in ('tagged' , 'untagged') :
|
||||
|
@ -590,7 +535,7 @@ if __name__ == '__main__' :
|
|||
opts, args = getopt.getopt(sys.argv[1:], 'hga', ['get-conf', 'help', 'all', 'header=' ])
|
||||
if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) == 1 :
|
||||
print "%s [-g|--get-conf] <switch>" % sys.argv[0].split('/')[-1].split('.')[0]
|
||||
print "Génération du fichier de configuration des switchs donnés."
|
||||
print "Génération du fichier de configuration des switchs donnés."
|
||||
sys.exit(255)
|
||||
|
||||
if args[0] == 'all' or 'a' in opts or '--all' in opts :
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue