From 18571ae1128859628fb035152c768cfcf6f9bfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Elliott=20B=C3=A9cue?= Date: Mon, 28 Jan 2013 03:16:35 +0100 Subject: [PATCH] =?UTF-8?q?=20*=20Correction=20de=20plusieurs=20bugs,=20on?= =?UTF-8?q?=20peut=20th=C3=A9oriquement=20cr=C3=A9er=20des=20machines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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... --- attributs.py | 29 +++++++++++++++++++++++------ crans_utils.py | 5 +++++ lc_ldap.py | 23 ++++++++++++++--------- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/attributs.py b/attributs.py index 1c33333..e6341fa 100644 --- a/attributs.py +++ b/attributs.py @@ -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 == '': - 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 == '': + 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, diff --git a/crans_utils.py b/crans_utils.py index cb93d8a..61d7fe0 100644 --- a/crans_utils.py +++ b/crans_utils.py @@ -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 diff --git a/lc_ldap.py b/lc_ldap.py index bceea7e..a520e78 100644 --- a/lc_ldap.py +++ b/lc_ldap.py @@ -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