[global] On diminue le risque de lock résiduel, et on corrige une faille des fonctions new[A-Z]*
* En cas d'erreur au create ou au save, on supprime les locks malgré tout * Les fonctions new* modifiaient directement le dico qu'on leur passait en argument, on fait désormais une copie de celui-ci, de façon à ce que test.py n'instancie pas toujours le même objet en croyant instancier des objets différents à chaque fois * Cela permet de trouver une typo dans services.py * crans_utils a été un peu corrigé.
This commit is contained in:
parent
e0bce3f7d3
commit
616acdbb7a
6 changed files with 52 additions and 21 deletions
|
@ -664,7 +664,6 @@ class macAddress(Attr):
|
||||||
|
|
||||||
def parse_value(self, mac):
|
def parse_value(self, mac):
|
||||||
self.value = format_mac(mac)
|
self.value = format_mac(mac)
|
||||||
# XXX self.parent['ip6HostNumber'] = cequ'ilfaut
|
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value).lower()
|
return unicode(self.value).lower()
|
||||||
|
@ -700,7 +699,10 @@ class ip6HostNumber(Attr):
|
||||||
ldap_name = "ip6HostNumber"
|
ldap_name = "ip6HostNumber"
|
||||||
|
|
||||||
def parse_value(self, ip6):
|
def parse_value(self, ip6):
|
||||||
ip = ip6_of_mac(str(self.parent['macAddress'][0]), int(str(self.parent['rid'][0])))
|
if self.parent != None:
|
||||||
|
ip = ip6_of_mac(str(self.parent['macAddress'][0]), int(str(self.parent['rid'][0])))
|
||||||
|
else:
|
||||||
|
ip = ip6
|
||||||
self.value = netaddr.ip.IPAddress(ip)
|
self.value = netaddr.ip.IPAddress(ip)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -136,7 +136,7 @@ def ip6_of_mac(mac, rid):
|
||||||
if net != "special":
|
if net != "special":
|
||||||
return netaddr.IPAddress(netaddr.IPNetwork(config.prefix[net][0]).first + int(euid64v6, 16))
|
return netaddr.IPAddress(netaddr.IPNetwork(config.prefix[net][0]).first + int(euid64v6, 16))
|
||||||
else:
|
else:
|
||||||
return config.ipv6_machines_speciales[rid]
|
return netaddr.IPAddress(config.ipv6_machines_speciales[rid])
|
||||||
|
|
||||||
def strip_accents(a):
|
def strip_accents(a):
|
||||||
""" Supression des accents de la chaîne fournie"""
|
""" Supression des accents de la chaîne fournie"""
|
||||||
|
|
20
lc_ldap.py
20
lc_ldap.py
|
@ -47,6 +47,7 @@ import attributs
|
||||||
import objets
|
import objets
|
||||||
import ldap_locks
|
import ldap_locks
|
||||||
import variables
|
import variables
|
||||||
|
import copy
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
## import de /usr/scripts/
|
## import de /usr/scripts/
|
||||||
|
@ -218,10 +219,13 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
_, adherents = self.allMachinesAdherents(mode)
|
_, adherents = self.allMachinesAdherents(mode)
|
||||||
return adherents
|
return adherents
|
||||||
|
|
||||||
def newMachine(self, parent, realm, uldif, login=None):
|
def newMachine(self, parent, realm, mldif, login=None):
|
||||||
"""Crée une nouvelle machine: ``realm`` peut être:
|
"""Crée une nouvelle machine: ``realm`` peut être:
|
||||||
fil, fil-v6, wifi, wifi-v6, adm, gratuit, personnel-ens, special
|
fil, fil-v6, wifi, wifi-v6, adm, gratuit, personnel-ens, special
|
||||||
|
mldif est un uldif pour la machine
|
||||||
--Partiellement implémenté"""
|
--Partiellement implémenté"""
|
||||||
|
# On ne veut pas modifier mldif directement
|
||||||
|
uldif = copy.deepcopy(mldif)
|
||||||
if login is None:
|
if login is None:
|
||||||
login = self.current_login
|
login = self.current_login
|
||||||
#adm, serveurs, bornes, wifi, adherents, gratuit ou personnel-ens"""
|
#adm, serveurs, bornes, wifi, adherents, gratuit ou personnel-ens"""
|
||||||
|
@ -239,7 +243,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
uldif['objectClass'] = [u'machineWifi']
|
uldif['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", "fil-v6", "personnel-ens"]:
|
||||||
uldif['objectClass'] = [u'machineFixe']
|
uldif['objectClass'] = [u'machineFixe']
|
||||||
assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club)
|
assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club)
|
||||||
|
|
||||||
|
@ -249,7 +253,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
# On récupère la plage des mids
|
# On récupère la plage des mids
|
||||||
plage = itertools.chain(*[xrange(a,b+1) for (a,b) in config.rid_primaires[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 ldif
|
||||||
rid = uldif.setdefault('rid', [unicode(self._find_id('rid', plage)) ])
|
rid = uldif.setdefault('rid', [unicode(self._find_id('rid', plage)) ])
|
||||||
|
|
||||||
# La machine peut-elle avoir une ipv4 ?
|
# La machine peut-elle avoir une ipv4 ?
|
||||||
|
@ -262,14 +266,14 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
|
|
||||||
# Tout doit disparaître !!
|
# Tout doit disparaître !!
|
||||||
machine = self._create_entity('mid=%s,%s' % (uldif['mid'][0], parent), uldif)
|
machine = self._create_entity('mid=%s,%s' % (uldif['mid'][0], parent), uldif)
|
||||||
machine.history_add(login, u"inscription")
|
|
||||||
if machine.may_be(variables.created, self.droits + self._check_parent(machine.dn)):
|
if machine.may_be(variables.created, self.droits + self._check_parent(machine.dn)):
|
||||||
return machine
|
return machine
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError("Vous n'avez pas le droit de créer cette machine.")
|
raise EnvironmentError("Vous n'avez pas le droit de créer cette machine.")
|
||||||
|
|
||||||
def newAdherent(self, uldif):
|
def newAdherent(self, aldif):
|
||||||
"""Crée un nouvel adhérent"""
|
"""Crée un nouvel adhérent"""
|
||||||
|
uldif = copy.deepcopy(aldif)
|
||||||
aid = uldif.setdefault('aid', [ unicode(self._find_id('aid')) ])
|
aid = uldif.setdefault('aid', [ unicode(self._find_id('aid')) ])
|
||||||
uldif['objectClass'] = [u'adherent']
|
uldif['objectClass'] = [u'adherent']
|
||||||
adherent = self._create_entity('aid=%s,%s' % (aid[0], variables.base_dn), uldif)
|
adherent = self._create_entity('aid=%s,%s' % (aid[0], variables.base_dn), uldif)
|
||||||
|
@ -278,8 +282,9 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError("Vous n'avez pas le droit de créer cet adhérent.")
|
raise EnvironmentError("Vous n'avez pas le droit de créer cet adhérent.")
|
||||||
|
|
||||||
def newClub(self, uldif):
|
def newClub(self, cldif):
|
||||||
"""Crée un nouveau club"""
|
"""Crée un nouveau club"""
|
||||||
|
uldif = copy.deepcopy(cldif)
|
||||||
cid = uldif.setdefault('cid', [ unicode(self._find_id('cid')) ])
|
cid = uldif.setdefault('cid', [ unicode(self._find_id('cid')) ])
|
||||||
uldif['objectClass'] = [u'club']
|
uldif['objectClass'] = [u'club']
|
||||||
club = self._create_entity('cid=%s,%s' % (cid[0], variables.base_dn), uldif)
|
club = self._create_entity('cid=%s,%s' % (cid[0], variables.base_dn), uldif)
|
||||||
|
@ -288,9 +293,10 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError("Vous n'avez pas le droit de créer cet adhérent.")
|
raise EnvironmentError("Vous n'avez pas le droit de créer cet adhérent.")
|
||||||
|
|
||||||
def newFacture(self, uldif):
|
def newFacture(self, fldif):
|
||||||
"""Crée une nouvelle facture
|
"""Crée une nouvelle facture
|
||||||
--Non implémenté !"""
|
--Non implémenté !"""
|
||||||
|
uldif = copy.deepcopy(fldif)
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def _create_entity(self, dn, uldif):
|
def _create_entity(self, dn, uldif):
|
||||||
|
|
37
objets.py
37
objets.py
|
@ -44,6 +44,7 @@ import re
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
import ldap
|
import ldap
|
||||||
|
import traceback
|
||||||
from ldap.modlist import addModlist, modifyModlist
|
from ldap.modlist import addModlist, modifyModlist
|
||||||
|
|
||||||
## import locaux
|
## import locaux
|
||||||
|
@ -189,25 +190,37 @@ class CransLdapObject(object):
|
||||||
faite"""
|
faite"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create(self):
|
def create(self, login=None):
|
||||||
"""Crée l'objet dans la base ldap, cette méthode vise à faire en sorte que
|
"""Crée l'objet dans la base ldap, cette méthode vise à faire en sorte que
|
||||||
l'objet se crée lui-même, si celui qui essaye de le modifier a les droits
|
l'objet se crée lui-même, si celui qui essaye de le modifier a les droits
|
||||||
de le faire."""
|
de le faire."""
|
||||||
|
if login is None:
|
||||||
|
login = self.conn.current_login
|
||||||
self._check_optionnal(comment="créez")
|
self._check_optionnal(comment="créez")
|
||||||
|
|
||||||
|
self.history_add(login, u"Inscription")
|
||||||
|
|
||||||
# Création de la requête LDAP
|
# Création de la requête LDAP
|
||||||
modlist = addModlist(self._modifs.to_ldif())
|
modlist = addModlist(self._modifs.to_ldif())
|
||||||
# Requête LDAP de création de l'objet
|
# Requête LDAP de création de l'objet
|
||||||
self.conn.add_s(self.dn, modlist)
|
try:
|
||||||
|
self.conn.add_s(self.dn, modlist)
|
||||||
|
except Exception:
|
||||||
|
print traceback.format_exc()
|
||||||
|
return
|
||||||
# On nettoie les locks
|
# On nettoie les locks
|
||||||
for key, values in self._modifs.to_ldif().iteritems():
|
for key, values in self._modifs.to_ldif().iteritems():
|
||||||
for value in values:
|
for value in values:
|
||||||
self.conn.lockholder.removelock(key, value)
|
self.conn.lockholder.removelock(key, value)
|
||||||
self.conn.lockholder.purge(id(self))
|
self.conn.lockholder.purge(id(self))
|
||||||
|
|
||||||
# Services à relancer
|
# Services à relancer
|
||||||
services.services_to_restart(self.conn, {}, self._modifs)
|
services.services_to_restart(self.conn, {}, self._modifs)
|
||||||
self._post_creation()
|
self._post_creation()
|
||||||
|
|
||||||
|
# Vérifications après insertion.
|
||||||
|
self.check_modifs()
|
||||||
|
|
||||||
def bury(self, comm, login):
|
def bury(self, comm, login):
|
||||||
"""Sauvegarde l'objet dans un fichier dans le cimetière."""
|
"""Sauvegarde l'objet dans un fichier dans le cimetière."""
|
||||||
self.history_add(login, u"destruction (%s)" % comm)
|
self.history_add(login, u"destruction (%s)" % comm)
|
||||||
|
@ -251,25 +264,33 @@ class CransLdapObject(object):
|
||||||
try:
|
try:
|
||||||
self.conn.modify_s(self.dn, modlist)
|
self.conn.modify_s(self.dn, modlist)
|
||||||
except:
|
except:
|
||||||
|
# On nettoie les locks
|
||||||
|
self.conn.lockholder.purge(id(self))
|
||||||
|
self._modifs = self.attrs
|
||||||
raise EnvironmentError("Impossible de modifier l'objet, peut-être n'existe-t-il pas ?")
|
raise EnvironmentError("Impossible de modifier l'objet, peut-être n'existe-t-il pas ?")
|
||||||
|
|
||||||
# On programme le redémarrage des services
|
# On programme le redémarrage des services
|
||||||
services.services_to_restart(self.conn, self.attrs, self._modifs)
|
services.services_to_restart(self.conn, self.attrs, self._modifs)
|
||||||
|
|
||||||
# On nettoie les locks
|
# Vérification des modifications.
|
||||||
self.conn.lockholder.purge(id(self))
|
self.check_modifs()
|
||||||
|
|
||||||
|
def check_modifs(self):
|
||||||
|
"""
|
||||||
|
Fonction qui vérifie que les modifications se sont bien
|
||||||
|
passées.
|
||||||
|
"""
|
||||||
# Vérification des modifications
|
# Vérification des modifications
|
||||||
old_ldif = self.conn.search_s(self.dn, ldap.SCOPE_BASE)[0][1]
|
old_uldif = lc_ldap.ldif_to_uldif(self.conn.search_s(self.dn, ldap.SCOPE_BASE)[0][1])
|
||||||
old_uldif = lc_ldap.ldif_to_uldif(old_ldif)
|
|
||||||
self.attrs = attributs.AttrsDict(self.conn, old_uldif, Parent=self)
|
self.attrs = attributs.AttrsDict(self.conn, old_uldif, Parent=self)
|
||||||
differences = []
|
differences = []
|
||||||
# On fait les différences entre les deux dicos
|
# On fait les différences entre les deux dicos
|
||||||
for attr in set(self.attrs.keys()).union(set(self._modifs.keys())):
|
for attr in set(self.attrs.keys()).union(set(self._modifs.keys())):
|
||||||
exp_vals = set([unicode(i) for i in self.attrs.get(attr, [])])
|
exp_vals = set([str(i) for i in self.attrs.get(attr, [])])
|
||||||
new_vals = set([unicode(i) for i in self._modifs.get(attr, [])])
|
new_vals = set([str(i) for i in self._modifs.get(attr, [])])
|
||||||
if exp_vals != new_vals:
|
if exp_vals != new_vals:
|
||||||
differences.append({"missing": exp_vals - new_vals, "having": new_vals - exp_vals})
|
differences.append({"missing": exp_vals - new_vals, "having": new_vals - exp_vals})
|
||||||
|
print differences[-1]
|
||||||
if differences:
|
if differences:
|
||||||
raise EnvironmentError("Les modifications apportées à l'objet %s n'ont pas été correctement sauvegardées\n%s" % (self.dn, differences))
|
raise EnvironmentError("Les modifications apportées à l'objet %s n'ont pas été correctement sauvegardées\n%s" % (self.dn, differences))
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ services_to_attrs['mail_modif'] = []
|
||||||
|
|
||||||
# génération des arguments du service à redémarrer (par defaut [])
|
# génération des arguments du service à redémarrer (par defaut [])
|
||||||
services_to_args={}
|
services_to_args={}
|
||||||
services_to_args['macip']=lambda x: issubclass(type(x.parent), objets.machine) and ([str(x)] if isinstance(x, attributs.ipHostNumber) else [ str(ip) for ip in x.parent.get('ipHostNumber',[]) ]) or ([ str(ip) for m in x.parent.machines() for ip in m.get('ipHostNumber',[])] if issubclass(type(x.parent), lc_ldap.proprio) else [])
|
services_to_args['macip']=lambda x: issubclass(type(x.parent), objets.machine) and ([str(x)] if isinstance(x, attributs.ipHostNumber) else [ str(ip) for ip in x.parent.get('ipHostNumber',[]) ]) or ([ str(ip) for m in x.parent.machines() for ip in m.get('ipHostNumber',[])] if issubclass(type(x.parent), objets.proprio) else [])
|
||||||
## Inutile pour blackliste pour le moment
|
## Inutile pour blackliste pour le moment
|
||||||
#services_to_args['blacklist']=lambda x: issubclass(type(x.parent), lc_ldap.machine) and [ str(ip) for m in x.parent.proprio().machines() for ip in m['ipHostNumber'] ] or [ str(ip) for m in x.parent.machines() for ip in m['ipHostNumber'] ]
|
#services_to_args['blacklist']=lambda x: issubclass(type(x.parent), lc_ldap.machine) and [ str(ip) for m in x.parent.proprio().machines() for ip in m['ipHostNumber'] ] or [ str(ip) for m in x.parent.machines() for ip in m['ipHostNumber'] ]
|
||||||
services_to_args['port']=lambda x: [str(x)] if isinstance(x, attributs.ipHostNumber) or isinstance(x, attributs.ip6HostNumber) else [ str(ip) for ip in x.parent.get('ipHostNumber',[]) ]
|
services_to_args['port']=lambda x: [str(x)] if isinstance(x, attributs.ipHostNumber) or isinstance(x, attributs.ip6HostNumber) else [ str(ip) for ip in x.parent.get('ipHostNumber',[]) ]
|
||||||
|
|
6
test.py
6
test.py
|
@ -51,9 +51,10 @@ machine_ldif = {
|
||||||
|
|
||||||
borne_ldif = {
|
borne_ldif = {
|
||||||
'macAddress' : [randomMAC()],
|
'macAddress' : [randomMAC()],
|
||||||
'host' : ["autotest-%s.crans.org" % randomStr() ],
|
'host' : [u"autotest-%s.crans.org" % randomStr() ],
|
||||||
'canal' : ["11"],
|
'canal' : [u"11"],
|
||||||
'puissance' : [u"52"],
|
'puissance' : [u"52"],
|
||||||
|
'hotspot' : [u'FALSE'],
|
||||||
}
|
}
|
||||||
|
|
||||||
club_ldif = {
|
club_ldif = {
|
||||||
|
@ -132,6 +133,7 @@ def tests_machines(parent_dn, realm_list, ipsec=False):
|
||||||
try:
|
try:
|
||||||
machine = conn.search('mid=%s' % machine['mid'][0], mode='rw')[0]
|
machine = conn.search('mid=%s' % machine['mid'][0], mode='rw')[0]
|
||||||
machine.delete()
|
machine.delete()
|
||||||
|
del(machine)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print ERREUR
|
print ERREUR
|
||||||
if show_traceback: print traceback.format_exc()
|
if show_traceback: print traceback.format_exc()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue