Support des switchs non adm par switch2.py (desactivation radius, mise en place de la bonne ip)

This commit is contained in:
Gabriel Detraz 2015-09-16 17:09:32 +02:00
parent e7aa590314
commit 4e10e930cd
2 changed files with 47 additions and 26 deletions

View file

@ -28,7 +28,7 @@ console inactivity-timer 30
logging {{ s }} logging {{ s }}
{%- endfor %} {%- endfor %}
;--- IP du switch --- ;--- IP du switch ---
ip default-gateway 10.231.136.4 ip default-gateway {{ gateway }}
{%- for vlan in vlans %} {%- for vlan in vlans %}
vlan {{ vlan.id }} vlan {{ vlan.id }}
name "{{ vlan.name|capitalize }}" name "{{ vlan.name|capitalize }}"
@ -54,12 +54,13 @@ no web-management
aaa authentication ssh login public-key none aaa authentication ssh login public-key none
aaa authentication ssh enable public-key none aaa authentication ssh enable public-key none
ip ssh ip ssh
ip authorized-managers 10.231.136.0 255.255.255.0 ip authorized-managers {{ network_id }} {{ subnet }}
ip ssh filetransfer ip ssh filetransfer
;--- Protection contre les boucles --- ;--- Protection contre les boucles ---
loop-protect disable-timer 30 loop-protect disable-timer 30
loop-protect transmit-interval 3 loop-protect transmit-interval 3
loop-protect {{ non_trusted }} loop-protect {{ non_trusted }}
{%- if not public %}
;--- Serveurs radius --- ;--- Serveurs radius ---
radius-server dead-time 2 radius-server dead-time 2
radius-server key {{ radius_key }} radius-server key {{ radius_key }}
@ -68,6 +69,7 @@ radius-server host {{ s }}
{%- endfor %} {%- endfor %}
;--- Filtrage mac --- ;--- Filtrage mac ---
aaa port-access mac-based addr-format multi-colon aaa port-access mac-based addr-format multi-colon
{%- endif %}
;--- Bricoles --- ;--- Bricoles ---
no cdp run no cdp run
no stack no stack
@ -86,7 +88,7 @@ no ipv6 ra-guard ports {{ trusted }}
{% endif %} {% endif %}
;--- Config des prises --- ;--- Config des prises ---
{%- for port in ports %} {%- for port in ports %}
{%- if port.radius_auth() %} {%- if port.radius_auth() and not public %}
aaa port-access mac-based {{ port|int }} aaa port-access mac-based {{ port|int }}
aaa port-access mac-based {{ port|int }} addr-limit {{ port.num_mac() }} aaa port-access mac-based {{ port|int }} addr-limit {{ port.num_mac() }}
aaa port-access mac-based {{ port|int }} logoff-period 3600 aaa port-access mac-based {{ port|int }} logoff-period 3600

View file

@ -2,14 +2,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Génération de la configuration d'un switch. Génération de la configuration d'un switch.
Attention, cette version n'a pas encore été totalement testée.
procédure de configuration initiale : procédure de configuration initiale :
* mot de passe admin (password manager user-name <username>) * mot de passe admin (password manager user-name <username>)
* activation du ssh (crypto key generate ssh) * activation du ssh (crypto key generate ssh)
* copie fichier de conf * copie fichier de conf
pour les reconfiguration copier le fichier de conf pour les reconfiguration copier le fichier de conf
dans /cfg/startup-config dans /cfg/startup-config
Dans tous les cas FAIRE LE SNMP A LA MAIN (script hptools) Dans tous les cas FAIRE LE SNMP A LA MAIN (script hptools)
@ -73,13 +71,13 @@ def net_of_vlan_name(name):
class Port(object): class Port(object):
"""Un port de switch""" """Un port de switch"""
num = None num = None
# : uplink: None ou str # : uplink: None ou str
uplink = None uplink = None
# : Liste de serveurs # : Liste de serveurs
servers = None servers = None
# : Liste de bornes # : Liste de bornes
bornes = None bornes = None
@ -100,7 +98,7 @@ class Port(object):
self.chambres = list() self.chambres = list()
self.seen_macs = list() self.seen_macs = list()
self.seen_vlans = list() self.seen_vlans = list()
def __str__(self): def __str__(self):
if self.uplink: if self.uplink:
return self.uplink return self.uplink
@ -139,7 +137,7 @@ class Port(object):
if any( adh.get('droits', None) for adh in self.adherents()): if any( adh.get('droits', None) for adh in self.adherents()):
return '' return ''
return 'speed-duplex auto-10-100' return 'speed-duplex auto-10-100'
def flowcontrol(self): def flowcontrol(self):
"""Est-ce que le flowcontrol est activé sur ce port ?""" """Est-ce que le flowcontrol est activé sur ce port ?"""
if self.uplink or self.servers: if self.uplink or self.servers:
@ -190,11 +188,11 @@ class Port(object):
# l'auth radius # l'auth radius
else: else:
return V_NO return V_NO
def radius_auth(self): def radius_auth(self):
"""Doit-on faire de l'auth radius ?""" """Doit-on faire de l'auth radius ?"""
return not self.uplink and not self.servers and not self.bornes return not self.uplink and not self.servers and not self.bornes
def adherents(self): def adherents(self):
"""Adhérents sur la prise""" """Adhérents sur la prise"""
filtre = u'(|%s)' % (''.join('(chbre=%s)' % c for c in self.chambres)) filtre = u'(|%s)' % (''.join('(chbre=%s)' % c for c in self.chambres))
@ -227,7 +225,7 @@ class PortList(list):
""" """
liste = list(int(x) for x in self) liste = list(int(x) for x in self)
liste.sort() liste.sort()
sortie = [] sortie = []
groupe = [-99999, -99999] groupe = [-99999, -99999]
for x in itertools.chain(liste, [99999]): for x in itertools.chain(liste, [99999]):
@ -270,7 +268,7 @@ def get_port_dict(switch):
port.servers.append(machine) port.servers.append(machine)
elif classe == 'borneWifi': elif classe == 'borneWifi':
port.bornes.append(machine) port.bornes.append(machine)
# On remplit les chambres # On remplit les chambres
for prise, chbres in annuaire.reverse(bat).iteritems(): for prise, chbres in annuaire.reverse(bat).iteritems():
# TODO rajouter un arg à reverse # TODO rajouter un arg à reverse
@ -349,7 +347,7 @@ def check_conf_ldap(hostname):
# La chambre est inconnue -> drop # La chambre est inconnue -> drop
continue continue
th_prises_set.add(th_prise) th_prises_set.add(th_prise)
pr_prise = bat.lower() + '%d%02d' % (sw_num, port.num) pr_prise = bat.lower() + '%d%02d' % (sw_num, port.num)
if th_prises_set and pr_prise not in th_prises_set: if th_prises_set and pr_prise not in th_prises_set:
print(" Aucune machine de chbre. Candidats: %r" % th_prises_set) print(" Aucune machine de chbre. Candidats: %r" % th_prises_set)
@ -402,7 +400,7 @@ def format_prises_group(data, first, last):
prises. Entre first et last""" prises. Entre first et last"""
first = (first-1)/2*2+1 first = (first-1)/2*2+1
last = (-last/2)*-2 last = (-last/2)*-2
def align5(txt, right=False): def align5(txt, right=False):
"""Aligne le texte en limitant à 5 char""" """Aligne le texte en limitant à 5 char"""
if len(txt) > 5: if len(txt) > 5:
@ -463,8 +461,12 @@ def conf_switch(hostname):
"""Affiche la configuration d'un switch""" """Affiche la configuration d'un switch"""
bat, sw_num = get_bat_num(hostname) bat, sw_num = get_bat_num(hostname)
switch = ldap.search(u'host=bat%s-%d.adm.crans.org' % (bat, sw_num))[0] try:
switch = ldap.search(u'host=bat%s-%d.adm.crans.org' % (bat, sw_num))[0]
except IndexError:
switch = ldap.search(u'host=bat%s-%d.crans.org' % (bat, sw_num))[0]
tpl_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__))) tpl_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
##for info: ##for info:
tpl_env.filters['vlan_id'] = vlan_id tpl_env.filters['vlan_id'] = vlan_id
@ -482,9 +484,6 @@ def conf_switch(hostname):
], ],
'radius_key': secrets.get('radius_key'), 'radius_key': secrets.get('radius_key'),
'ntp_servers': ['10.231.136.98'],
'log_servers': ['10.231.136.38'],
# dhcp et isc (secondaire) sont les deux seuls serveurs # dhcp et isc (secondaire) sont les deux seuls serveurs
'dhcp_rid_servers': [34, 160], 'dhcp_rid_servers': [34, 160],
@ -519,7 +518,25 @@ def conf_switch(hostname):
for rid in data['dhcp_rid_servers']: for rid in data['dhcp_rid_servers']:
first = netaddr.IPNetwork(net_of_vlan_name(vname)[0]).first first = netaddr.IPNetwork(net_of_vlan_name(vname)[0]).first
data['dhcp_servers'].append(str(netaddr.IPAddress(first + rid))) data['dhcp_servers'].append(str(netaddr.IPAddress(first + rid)))
# Si le switch n'est pas en .adm, il n'est pas publique (ex : batk-0)
# (désactivation de radius etc)
# On règle les logs, ntp, suivant si le switch est public ou privé (adm)
if u"adm" in unicode(switch['host']):
data['public'] = False
data['ntp_servers'] = ['10.231.136.98']
data['log_servers'] = ['10.231.136.38']
data['gateway'] = '10.231.136.4'
data['network_id'] = '10.231.136.0'
data['subnet'] = '255.255.255.0'
else:
data['public'] = True
data['ntp_servers'] = ['138.231.136.98']
data['log_servers'] = ['138.231.136.38']
data['gateway'] = '138.231.136.4'
data['network_id'] = '138.231.136.0'
data['subnet'] = '255.255.248.0'
# Ra gards ne concerne que les 2620 # Ra gards ne concerne que les 2620
if "2620" in switch['info'][0].value: if "2620" in switch['info'][0].value:
data['ra_filter'] = True data['ra_filter'] = True
@ -529,7 +546,7 @@ def conf_switch(hostname):
# Switch avec des ports gigabit uniquement # Switch avec des ports gigabit uniquement
if imodel in GIGABIT_MODELS: if imodel in GIGABIT_MODELS:
data['gigabit'] = True data['gigabit'] = True
# Build ports ! # Build ports !
ports_list = PortList(get_port_dict(switch).itervalues()) ports_list = PortList(get_port_dict(switch).itervalues())
data['ports'] = ports_list data['ports'] = ports_list
@ -548,9 +565,11 @@ def conf_switch(hostname):
V_NO: 'no'}[assign] V_NO: 'no'}[assign]
vlan.setdefault(attr, PortList()) vlan.setdefault(attr, PortList())
vlan[attr].extend(p) vlan[attr].extend(p)
if name == 'adm': if name == 'adm' and not data['public']:
vlan['ip_cfg'] = (gethostbyname(hostname), '255.255.255.0') vlan['ip_cfg'] = (gethostbyname(hostname), '255.255.255.0')
if name == 'adherent': if name == 'adherent':
if data['public']:
vlan['ip_cfg'] = (gethostbyname(hostname), '255.255.248.0')
# igmp snooping (multicast) mais nous ne sommes pas querier # igmp snooping (multicast) mais nous ne sommes pas querier
vlan['extra'] = 'ip igmp\nno ip igmp querier' vlan['extra'] = 'ip igmp\nno ip igmp querier'
vlans[name] = vlan vlans[name] = vlan
@ -581,7 +600,7 @@ if __name__ == "__main__":
help="Affiche un tableau ascii du plan de connexion du switch") help="Affiche un tableau ascii du plan de connexion du switch")
options = parser.parse_args(sys.argv[1:]) options = parser.parse_args(sys.argv[1:])
if options.check: if options.check:
check_conf_ldap(options.hostname) check_conf_ldap(options.hostname)
elif options.pretty: elif options.pretty: