* Maintenant, on va pouvoir identifier formellement les machines v6-only et les autres, sans perdre
 la possibilité de passer de l'une à l'autre rapidement (avec les changements qui vont bien)
This commit is contained in:
Pierre-Elliott Bécue 2013-05-30 01:15:24 +02:00
parent 60ded9f830
commit cd75ed7bd4
5 changed files with 79 additions and 35 deletions

View file

@ -45,6 +45,7 @@ import random
import string import string
from unicodedata import normalize from unicodedata import normalize
from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac
import itertools
sys.path.append("/usr/scripts/") sys.path.append("/usr/scripts/")
import cranslib.deprecated import cranslib.deprecated
@ -682,7 +683,7 @@ class ipHostNumber(Attr):
def parse_value(self, ip): def parse_value(self, ip):
if ip == '<automatique>': if ip == '<automatique>':
ip = ip4_of_rid(str(self.parent['rid'][0])) ip = ip4_of_rid(str(self.parent['rid'][0]))
self.value = netaddr.ip.IPAddress(ip) self.value = netaddr.IPAddress(ip)
def __unicode__(self): def __unicode__(self):
return unicode(self.value) return unicode(self.value)
@ -735,7 +736,7 @@ class rid(Attr):
# On veut éviter les rid qui recoupent les ipv4 finissant par # On veut éviter les rid qui recoupent les ipv4 finissant par
# .0 ou .255 # .0 ou .255
plages = [xrange(config.rid[a][0], config.rid[a][1]+1) for a in config.rid.keys() if ('v6' not in a) and ('special' not in a)] plages = [itertools.chain(*[xrange(plage[0], plage[1]+1) for plage in value]) for (key, value) in config.rid_primaires.iteritems() if ('v6' not in key) and ('special' not in key)]
for plage in plages: for plage in plages:
if rid in plage: if rid in plage:

View file

@ -44,24 +44,57 @@ from unicodedata import normalize
DEVNULL = open(os.devnull, 'w') DEVNULL = open(os.devnull, 'w')
def find_rid_plage(rid):
"""Trouve la plage du rid fourni"""
for (tp, plages) in config.rid_primaires.iteritems():
if isinstance(plages, list):
for begin, end in plages:
if begin <= rid <= end:
return tp, (begin, end)
else:
(begin, end) = plages
if begin <= rid <= end:
return tp, (begin, end)
else:
return 'Inconnu', (0, 0)
def find_ipv4_plage(ipv4):
"""Trouve la plage de l'ipv4 fournie"""
for (tp, plage) in config.NETs_primaires.iteritems():
for sousplage in map(netaddr.IPNetwork, plage):
if ipv4 in sousplage:
return tp, sousplage
def ip4_of_rid(rid): def ip4_of_rid(rid):
"""Convertit un rid en son IP associée""" """Convertit un rid en son IP associée"""
# Au cas où # Au cas où
rid = int(rid) rid = int(rid)
for net, plage in config.rid.items(): net, plage = find_rid_plage(rid)
if rid >= plage[0] and rid <= plage[1]: if net == 'Inconnu':
break
else:
raise ValueError("Rid dans aucune plage: %d" % rid) raise ValueError("Rid dans aucune plage: %d" % rid)
if net == 'special': if net == 'special':
try: try:
return netaddr.IPAddress(config.rid_machines_speciales[rid]) return netaddr.IPAddress(config.rid_machines_speciales[rid])
except KeyError: except KeyError:
return ValueError("Machine speciale inconnue: %d" % rid) raise ValueError(u"Machine speciale inconnue: %d" % rid)
try:
return netaddr.IPAddress(netaddr.IPNetwork(config.NETs[net][0]).first + rid - plage[0]) return netaddr.IPAddress(netaddr.IPNetwork(config.NETs[net][0]).first + rid - plage[0])
except KeyError:
raise EnvironmentError("Les machines v6-only ne peuvent pas avoir d'ipv4 (%s)" % (net))
def rid_of_ip4(ipv4):
"""Convertit une ipv4 en rid, si possible"""
# Est-ce une machine spéciale ?
for (rid, ip) in config.rid_machines_speciales.iteritems():
if str(ipv4) == ip:
return rid
# Le cas non-échéant, on va devoir faire de la deep NETs inspection
realm, sousplage = find_ipv4_plage(ipv4)
return config.rid[realm][0][0] + int(ipv4 - sousplage.first)
def prefixev6_of_rid(rid): def prefixev6_of_rid(rid):
""" """
@ -73,10 +106,8 @@ def prefixev6_of_rid(rid):
# Au cas où # Au cas où
rid = int(rid) rid = int(rid)
for net, plage in config.rid.items(): net, plage = find_rid_plage(rid)
if rid >= plage[0] and rid <= plage[1]: if net == 'Inconnu':
break
else:
raise ValueError("Rid dans aucune plage: %d" % rid) raise ValueError("Rid dans aucune plage: %d" % rid)
# fil-v6 ou wifi-v6, we don't care # fil-v6 ou wifi-v6, we don't care
@ -89,10 +120,8 @@ def ip6_of_mac(mac, rid):
# Au cas où # Au cas où
rid = int(rid) rid = int(rid)
for net, plage in config.rid.items(): net, plage = find_rid_plage(rid)
if rid >= plage[0] and rid <= plage[1]: if net == 'Inconnu':
break
else:
raise ValueError("Rid dans aucune plage: %d" % rid) raise ValueError("Rid dans aucune plage: %d" % rid)
# En théorie, format_mac est inutile, car on ne devrait avoir # En théorie, format_mac est inutile, car on ne devrait avoir

View file

@ -47,6 +47,7 @@ import attributs
import objets import objets
import ldap_locks import ldap_locks
import variables import variables
import itertools
## import de /usr/scripts/ ## import de /usr/scripts/
if not "/usr/scripts/" in sys.path: if not "/usr/scripts/" in sys.path:
@ -232,8 +233,8 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
uldif['objectClass'] = [u'borneWifi'] uldif['objectClass'] = [u'borneWifi']
assert isinstance(owner, objets.AssociationCrans) assert isinstance(owner, objets.AssociationCrans)
elif realm in ["wifi", "wifi-v6"]: elif realm in ["wifi-adh", "wifi-v6"]:
uldif['objectClass'] = [u'machineWifi'] ldif['objectClass'] = [u'machineWifi']
assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club) assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club)
elif realm in ["adherents", "adherents-v6", "personnel-ens"]: elif realm in ["adherents", "adherents-v6", "personnel-ens"]:
@ -244,7 +245,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
raise ValueError("Realm inconnu: %r" % realm) raise ValueError("Realm inconnu: %r" % realm)
# On récupère la plage des mids # On récupère la plage des mids
plage = xrange( *(config.rid[realm])) plage = itertools.chain(*[xrange(a,b+1) for (a,b) in config.rid_primaires[realm]])
# On récupère le premier id libre dans la plages s'il n'est pas # On récupère le premier id libre dans la plages s'il n'est pas
# déjà précisé dans le ldiff # déjà précisé dans le ldiff
rid = uldif.setdefault('rid', [unicode(self._find_id('rid', plage)) ]) rid = uldif.setdefault('rid', [unicode(self._find_id('rid', plage)) ])

View file

@ -708,20 +708,20 @@ class machineWifi(machine):
attribs = machine.attribs + [attributs.ipsec] attribs = machine.attribs + [attributs.ipsec]
ldap_name = "machineWifi" ldap_name = "machineWifi"
def set_ipv4(self, login=None): # À passer là où il faut
u"""Définie une ipv4 à la machine si elle n'est possède pas déjà une.""" # def set_ipv4(self, login=None):
if login is None: # u"""Définie une ipv4 à la machine si elle n'est possède pas déjà une."""
login = self.conn.current_login # if login is None:
if not 'ipHostNumber' in self.attrs.keys() or not self['ipHostNumber']: # login = self.conn.current_login
rid = self['rid']=[ unicode(self.conn._find_id('rid', range(config.rid['wifi'][0], config.rid['wifi'][1]))) ] # if not 'ipHostNumber' in self.attrs.keys() or not self['ipHostNumber']:
ip = self['ipHostNumber'] = [ unicode(crans_utils.ip4_of_rid(int(rid[0]))) ] # rid = self['rid']=[ unicode(self.conn._find_id('rid', range(config.rid['wifi'][0], config.rid['wifi'][1]+1))) ]
self.history_add(login, u"rid") # ip = self['ipHostNumber'] = [ unicode(crans_utils.ip4_of_rid(int(rid[0]))) ]
self.history_add(login, u"ipHostNumber (N/A -> %s)" % ip[0]) # self.history_add(login, u"rid")
self.save() # self.history_add(login, u"ipHostNumber (N/A -> %s)" % ip[0])
# self.save()
for server in config.dhcp_servers: # from gen_confs.dhcpd_new import dydhcp
dhcp=dydhcp(server) # dhcp=dydhcp()
dhcp.add_host(str(self['ipHostNumber'][0]), str(self['macAddress'][0]), str(self['host'][0])) # dhcp.add_host(str(self['ipHostNumber'][0]), str(self['macAddress'][0]), str(self['host'][0]))
@crans_object @crans_object
class machineCrans(machine): class machineCrans(machine):

17
test.py
View file

@ -49,6 +49,13 @@ machine_ldif = {
'host' : [u"autotest-%s.crans.org" % randomStr() ] 'host' : [u"autotest-%s.crans.org" % randomStr() ]
} }
borne_ldif = {
'macAddress' : [randomMAC()],
'host' : ["autotest-%s.crans.org" % randomStr() ],
'canal' : ["11"],
'puissance' : ["52 khz"],
}
club_ldif = { club_ldif = {
'nom' : [ u'autotest-club' ], 'nom' : [ u'autotest-club' ],
'chbre' : [ u'EXT' ], 'chbre' : [ u'EXT' ],
@ -90,6 +97,8 @@ def test_list_of_dict(keys, list):
anim("\tTest de l'attribut %s" % key) anim("\tTest de l'attribut %s" % key)
ok = True ok = True
for item in list: for item in list:
if key == "chbre":
print item['aid'][0]
try: item.get(key, []) try: item.get(key, [])
except psycopg2.OperationalError as error: except psycopg2.OperationalError as error:
print ERREUR print ERREUR
@ -108,7 +117,11 @@ def tests_machines(parent_dn, realm_list, ipsec=False):
for realm in realm_list: for realm in realm_list:
anim("Creation de machines %s" % realm) anim("Creation de machines %s" % realm)
try: try:
machine = conn.newMachine(parent_dn, realm, machine_ldif) if realm == 'bornes':
mldif = borne_ldif
else:
mldif = machine_ldif
machine = conn.newMachine(parent_dn, realm, mldif)
if ipsec: machine['ipsec'] = u'auto' if ipsec: machine['ipsec'] = u'auto'
machine.create() machine.create()
except Exception as error: except Exception as error:
@ -189,7 +202,7 @@ else:
print OK print OK
tests_machines(adherent.dn, ["adherents", "fil-v6", "personnel-ens"]) tests_machines(adherent.dn, ["adherents", "fil-v6", "personnel-ens"])
tests_machines(adherent.dn, ["wifi", "wifi-v6"], ipsec=True) tests_machines(adherent.dn, ["wifi-adh", "wifi-v6"], ipsec=True)