[lc_ldap] On met en place un système de propagation de certaines modifications.

* Quand on modifie un attribut qui devrait en modifier d'autres, on peut
 invoquer check_changes pour voir ce qui devrait être changé, puis
 validate_changes pour rendre ces changements effectifs. Il ne reste plus
 qu'à appeler save pour enregistrer le tout.
 * Correction de petits problèmes sur les locks : quand save réussissait,
 ils n'étaient pas virés.
This commit is contained in:
Pierre-Elliott Bécue 2013-07-04 02:06:13 +02:00
parent 9540bc572c
commit c2968c6b15
5 changed files with 133 additions and 28 deletions

View file

@ -225,7 +225,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
def newMachine(self, parent, realm, mldif, login=None):
"""Crée une nouvelle machine: ``realm`` peut être:
fil, fil-v6, wifi, wifi-v6, adm, gratuit, personnel-ens, special
fil, adherents-v6, wifi, wifi-adh-v6, adm, gratuit, personnel-ens, special
mldif est un uldif pour la machine
--Partiellement implémenté"""
# On ne veut pas modifier mldif directement
@ -243,22 +243,20 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
uldif['objectClass'] = [u'borneWifi']
assert isinstance(owner, objets.AssociationCrans)
elif realm in ["wifi-adh", "wifi-v6"]:
elif realm in ["wifi-adh", "wifi-adh-v6"]:
uldif['objectClass'] = [u'machineWifi']
assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club)
elif realm in ["adherents", "fil-v6", "personnel-ens"]:
elif realm in ["adherents", "adherents-v6", "personnel-ens"]:
uldif['objectClass'] = [u'machineFixe']
assert isinstance(owner, objets.adherent) or isinstance(owner, objets.club)
else:
raise ValueError("Realm inconnu: %r" % realm)
# On récupère la plage des mids
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
# 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', realm))])
# La machine peut-elle avoir une ipv4 ?
if 'v6' not in realm:
@ -307,9 +305,9 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
'''Crée une nouvelle entité ldap avec le dn ``dn`` et les
attributs de ``ldif``. Attention, ldif doit contenir des
données encodées.'''
# Ajout des locks, on instancie les attributs qui ne sont pas
# des id, ceux-ci étant déjà lockés.
for key, values in uldif.iteritems():
if key.endswith('id'):
continue
attribs = [attributs.attrify(val, key, self) for val in values]
for attribut in attribs:
if attribut.unique:
@ -323,12 +321,17 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
self.lockholder.removelock(key, str(attribut))
raise
def _find_id(self, attr, plage=None):
def _find_id(self, attr, realm=None):
'''Trouve un id libre. Si une plage est fournie, cherche
l'id dans celle-ci, sinon, prend le plus élevé possible.'''
res = self.search_s(variables.base_dn, ldap.SCOPE_SUBTREE, '%s=*' % attr, attrlist = [attr])
nonfree = [ int(r[1].get(attr)[0]) for r in res if r[1].get(attr) ]
nonfree.sort()
plage = None
# On récupère la plage des mids
if realm != None:
plage = itertools.chain(*[xrange(a,b+1) for (a,b) in config.rid_primaires[realm]])
if plage != None:
for i in plage:
@ -342,6 +345,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
else:
try:
self.lockholder.addlock(attr, str(i))
self.lockholder.removelock(attr, str(i))
break
except:
continue
@ -353,6 +357,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
while True:
try:
self.lockholder.addlock(attr, str(i))
self.lockholder.removelock(attr, str(i))
break
except ldap_locks.LockError:
i += 1