* Correction de plusieurs bugs, on peut théoriquement créer des machines

Mais il faut éviter, parce qu'elles peuvent prendre des ip en .0 ou .255
    Il reste quelques détails genre 'historique' et 'ouverture de ports' à régler...
This commit is contained in:
Pierre-Elliott Bécue 2013-01-28 03:16:35 +01:00
parent e3e0485045
commit 18571ae112
3 changed files with 42 additions and 15 deletions

View file

@ -35,7 +35,7 @@
import re, sys, netaddr, time
from unicodedata import normalize
from crans_utils import format_tel, format_mac, mailexist, validate_name
from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac
sys.path.append("/usr/scripts/gestion")
import config, annuaires_pg
@ -177,8 +177,8 @@ class objectClass(Attr):
""" Internal purpose (et à fin pédagogique) """
def parse_value(self, val, ldif):
if val not in [ 'top', 'posixAccount', 'shadowAccount', 'proprio',
'adherent', 'club', 'machine', 'machineCrans',
if val not in [ 'top', 'organizationalUnit', 'posixAccount', 'shadowAccount',
'proprio', 'adherent', 'club', 'machine', 'machineCrans',
'borneWifi', 'machineWifi', 'machineFixe',
'cransAccount', 'service', 'facture', 'freeMid' ]:
raise ValueError("Pourquoi insérer un objectClass=%r ?" % val)
@ -399,7 +399,7 @@ class dnsAttr(Attr):
def parse_value(self, dns, ldif):
dns = dns.lower()
name, net = dns.split('.', 1)
if self.ctxt_check and (net not in ['crans.org', 'wifi.crans.org'] or
if self.ctxt_check and (net not in ['adm.crans.org', 'crans.org', 'wifi.crans.org'] or
not re.match('[a-z][-_a-z0-9]+', name)):
raise ValueError("Nom d'hote invalide %r" % dns)
self.value = dns
@ -443,7 +443,7 @@ class macAddress(Attr):
class ipHostNumber(Attr):
singlevalue = True
optional = False
optional = True
unique = True
legend = u"Adresse IPv4 de la machine"
hname = "IPv4"
@ -452,12 +452,28 @@ class ipHostNumber(Attr):
def parse_value(self, ip, ldif):
if ip == '<automatique>':
ip = Rid(rid= ldif['rid'][0]).ipv4()
ip = ip4_of_rid(ldif['rid'][0])
self.value = netaddr.ip.IPAddress(ip)
def __unicode__(self):
return unicode(self.value)
class ip6HostNumber(Attr):
singlevalue = True
optional = True
unique = True
legend = u"Adresse IPv6 de la machine"
hname = "IPv6"
category = 'base_tech'
can_modify = [nounou]
def parse_value(self, ip, ldif):
if ip == '<automatique>':
ip = ip6_of_mac(ldif['macAddress'][0], ldif['rid'][0])
self.value = netaddr.ip.IPAddress(ip)
def __unicode__(self):
return unicode(self.value)
class mid(Attr):
singlevalue = True
@ -804,6 +820,7 @@ CRANS_ATTRIBUTES= {
'sshFingerprint' : sshFingerprint,
'macAddress': macAddress,
'ipHostNumber': ipHostNumber,
'ip6HostNumber': ip6HostNumber,
'hostAlias' : hostAlias,
'ipsec' : ipsec,
'puissance' : puissance,

View file

@ -36,6 +36,9 @@ from unicodedata import normalize
def ip4_of_rid(rid):
"""Convertit un rid en son IP associée"""
# Au cas où
rid = int(rid)
for net, plage in config.rid.items():
if rid >= plage[0] and rid <= plage[1]:
break
@ -57,6 +60,8 @@ def prefixev6_of_rid(rid):
Cette fonction retourne l'ip de début de ce sous-réseau.
"""
rid = int(rid)
for net, plage in config.rid.items():
if rid >= plage[0] and rid <= plage[1]:
break

View file

@ -258,19 +258,22 @@ class lc_ldap(ldap.ldapobject.LDAPObject):
else: raise ValueError("Realm inconnu: %r" % realm)
# On récupère la plage des mids
plage = xrange( *(config.rid[realm]))
# On récupère le premier id libre dans la plages s'il n'est pas
# déjà précisé dans le ldiff
rid = uldif.setdefault('rid', [ unicode(self._find_id('rid', plage)) ])
# La machine peut-elle avoir une ipv4 ?
if 'v6' not in realm:
uldif['ipHostNumber'] = [ unicode(crans_utils.ip4_of_rid(rid[0])) ]
uldif['ip6HostNumber'] = [ unicode(crans_utils.ip6_of_mac(uldif['macAddress'][0], rid[0])) ]
uldif['ipHostNumber'] = [ unicode(crans_utils.ip4_of_rid(int(rid[0]))) ]
uldif['ip6HostNumber'] = [ unicode(crans_utils.ip6_of_mac(uldif['macAddress'][0], int(rid[0]))) ]
# Mid
uldif['mid'] = [ unicode(self._find_id('mid')) ]
# On récupère la plage des mids
plage = xrange( *(config.rid[realm]))
# Tout doit disparaître !!
machine = self._create_entity('mid=%s,%s' % (mid[0], parent), uldif)
machine = self._create_entity('mid=%s,%s' % (uldif['mid'][0], parent), uldif)
if machine.may_be(created, self.droits + self._is_parent(machine)):
machine.create()
else:
@ -483,7 +486,7 @@ class CransLdapObject(object):
# Création de la requête LDAP
modlist = addModlist(cldif_to_ldif(self.attrs))
# Requête LDAP de création de l'objet
self.add_s(self.dn, modlist)
self.conn.add_s(self.dn, modlist)
def save(self):
@ -513,12 +516,14 @@ class CransLdapObject(object):
if differences:
raise EnvironmentError("Les modifications apportées à l'objet %s n'ont pas été correctement sauvegardées\n%s" % (self.dn, differences))
def may_be(self, what, obj):
"""Teste si celui qui est bindé peut effectuer ce qui est dans what, pour
def may_be(self, what, liste):
"""Teste si liste peut faire ce qui est dans what, pour
what élément de {create, delete, modify}.
On passe une liste de droits plutôt que l'objet car il faut ajouter
les droits soi et parent.
Retourne un booléen
"""
if set(obj.droits).intersection(self.can_be_by[what]) != set([]):
if set(liste).intersection(self.can_be_by[what]) != set([]):
return True
else:
return False