[global] Passage à tout unicode et quelques corrections mineures.
* Typos * Docstrings unicode * Erreurs unicode * Ajout de _post_delete et _post_create * ?
This commit is contained in:
parent
b2abbef3b4
commit
60ded9f830
7 changed files with 244 additions and 237 deletions
173
objets.py
173
objets.py
|
@ -43,16 +43,9 @@ import sys
|
|||
import re
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import ldap
|
||||
from ldap.modlist import addModlist, modifyModlist
|
||||
|
||||
## import de /usr/scripts/
|
||||
if not "/usr/scripts/" in sys.path:
|
||||
sys.path.append('/usr/scripts/')
|
||||
|
||||
import gestion.config as config
|
||||
|
||||
## import locaux
|
||||
import lc_ldap
|
||||
import crans_utils
|
||||
|
@ -61,10 +54,17 @@ import ldap_locks
|
|||
import services
|
||||
import variables
|
||||
|
||||
## import de /usr/scripts/
|
||||
if not "/usr/scripts/" in sys.path:
|
||||
sys.path.append('/usr/scripts/')
|
||||
|
||||
import gestion.config as config
|
||||
from gestion.gen_confs.dhcpd_new import dydhcp
|
||||
|
||||
#: Champs à ignorer dans l'historique
|
||||
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp", "historique"]
|
||||
|
||||
def new_cransldapobject(conn, dn, mode='ro', ldif = None):
|
||||
def new_cransldapobject(conn, dn, mode='ro', uldif=None):
|
||||
"""Crée un objet :py:class:`CransLdapObject` en utilisant la classe correspondant à
|
||||
l'``objectClass`` du ``ldif``
|
||||
--pour usage interne à la librairie uniquement !"""
|
||||
|
@ -75,8 +75,8 @@ def new_cransldapobject(conn, dn, mode='ro', ldif = None):
|
|||
classe = AssociationCrans
|
||||
elif dn == variables.invite_dn:
|
||||
classe = BaseInvites
|
||||
elif ldif:
|
||||
classe = ObjectFactory.get(ldif['objectClass'][0])
|
||||
elif uldif:
|
||||
classe = ObjectFactory.get(uldif['objectClass'][0])
|
||||
else:
|
||||
res = conn.search_s(dn, 0)
|
||||
if not res:
|
||||
|
@ -84,7 +84,7 @@ def new_cransldapobject(conn, dn, mode='ro', ldif = None):
|
|||
_, attrs = res[0]
|
||||
classe = ObjectFactory.get(attrs['objectClass'][0])
|
||||
|
||||
return classe(conn, dn, mode, ldif)
|
||||
return classe(conn, dn, mode, uldif)
|
||||
|
||||
class CransLdapObject(object):
|
||||
"""Classe de base des objets :py:class:`CransLdap`.
|
||||
|
@ -98,10 +98,10 @@ class CransLdapObject(object):
|
|||
|
||||
attribs = []
|
||||
|
||||
def __init__(self, conn, dn, mode='ro', ldif = None):
|
||||
def __init__(self, conn, dn, mode='ro', uldif=None):
|
||||
'''
|
||||
Créée une instance d'un objet Crans (machine, adhérent,
|
||||
etc...) à ce ``dn``, si ``ldif`` est précisé, n'effectue pas de
|
||||
etc...) à ce ``dn``, si ``uldif`` est précisé, n'effectue pas de
|
||||
recherche dans la base ldap.
|
||||
'''
|
||||
|
||||
|
@ -116,25 +116,21 @@ class CransLdapObject(object):
|
|||
self.dn = dn
|
||||
|
||||
orig = {}
|
||||
if ldif:
|
||||
self.attrs = attributs.AttrsDict(self.conn, ldif, Parent=self)
|
||||
self._modifs = attributs.AttrsDict(self.conn, ldif, Parent=self)
|
||||
orig = ldif
|
||||
if uldif:
|
||||
self.attrs = attributs.AttrsDict(self.conn, uldif, Parent=self)
|
||||
self._modifs = attributs.AttrsDict(self.conn, uldif, Parent=self)
|
||||
|
||||
elif dn != variables.base_dn:
|
||||
res = self.conn.search_s(dn, 0)
|
||||
if not res:
|
||||
raise ValueError ('objet inexistant: %s' % dn)
|
||||
self.dn, res_attrs = res[0]
|
||||
self.dn, ldif = res[0]
|
||||
|
||||
# L'objet sortant de la base ldap, on ne fait pas de vérifications sur
|
||||
# l'état des données.
|
||||
self.attrs = attributs.AttrsDict(self.conn, res_attrs, Parent=self)
|
||||
|
||||
# Pour test en cas de mode w ou rw
|
||||
orig = res[0][1]
|
||||
|
||||
self._modifs = attributs.AttrsDict(self.conn, res[0][1], Parent=self)
|
||||
uldif = lc_ldap.ldif_to_ldif(ldif)
|
||||
self.attrs = attributs.AttrsDict(self.conn, uldif, Parent=self)
|
||||
self._modifs = attributs.AttrsDict(self.conn, uldif, Parent=self)
|
||||
|
||||
if mode in ['w', 'rw']:
|
||||
if not self.may_be(variables.modified, self.conn.droits + self.conn._check_parent(dn) + self.conn._check_self(dn)):
|
||||
|
@ -142,69 +138,76 @@ class CransLdapObject(object):
|
|||
|
||||
self.mode = mode
|
||||
|
||||
# Je m'interroge sur la pertinence de cette partie, je pense qu'elle n'est
|
||||
# pas utile. -- PEB 27/01/2013
|
||||
if mode in ['w', 'rw']:
|
||||
### Vérification que `λv. str(Attr(v))` est bien une projection
|
||||
### C'est-à-dire que si on str(Attr(str(Attr(v)))) on retombe sur str(Attr(v))
|
||||
oldif = orig
|
||||
nldif = self.attrs.to_ldif()
|
||||
# Vérification que `λv. str(Attr(v))` est bien une projection
|
||||
# C'est-à-dire que si on str(Attr(str(Attr(v)))) on retombe sur str(Attr(v))
|
||||
oldif = lc_ldap.ldif_to_uldif(self.attrs.to_ldif())
|
||||
nldif = lc_ldap.ldif_to_uldif(attributs.AttrsDict(self.conn, lc_ldap.ldif_to_uldif(self.attrs.to_ldif()), Parent=self).to_ldif())
|
||||
|
||||
for attr, vals in oldif.items():
|
||||
if nldif[attr] != vals:
|
||||
for v in nldif[attr]:
|
||||
if v in vals:
|
||||
vals.remove(v)
|
||||
nvals = [nldif[attr][v.index(v)] for v in vals ]
|
||||
nvals = [nldif[attr][vals.index(v)] for v in vals ]
|
||||
raise EnvironmentError("λv. str(Attr(v)) n'est peut-être pas une projection (ie non idempotente):", attr, nvals, vals)
|
||||
|
||||
# def _get_fields(self):
|
||||
# """Renvoie la liste des champs LDAP de l'objet"""
|
||||
# return self.attribs
|
||||
# attribs = property(_get_fields)
|
||||
|
||||
def history_add(self, login, chain):
|
||||
"""Ajoute une ligne à l'historique de l'objet.
|
||||
###ATTENTION : C'est un kludge pour pouvoir continuer à faire "comme avant",
|
||||
### mais on devrait tout recoder pour utiliser l'historique LDAP"""
|
||||
assert isinstance(login, str) or isinstance(login, unicode)
|
||||
assert isinstance(chain, str) or isinstance(chain, unicode)
|
||||
assert isinstance(login, unicode)
|
||||
assert isinstance(chain, unicode)
|
||||
|
||||
new_line = "%s, %s : %s" % (time.strftime("%d/%m/%Y %H:%M"), login, chain)
|
||||
new_line = u"%s, %s : %s" % (time.strftime("%d/%m/%Y %H:%M"), login, chain)
|
||||
# Attention, le __setitem__ est surchargé, mais pas .append sur l'historique
|
||||
self["historique"] = self.get("historique", []) + [new_line]
|
||||
|
||||
def _check_optionnal(self, comment):
|
||||
"""Vérifie que les attributs qui ne sont pas optionnels sont effectivement peuplés."""
|
||||
objet = self.ldap_name
|
||||
|
||||
for attribut in self.attribs:
|
||||
if not attribut.optional:
|
||||
nom_attr = attribut.ldap_name
|
||||
if len(self._modifs.get(nom_attr, [])) <= 0:
|
||||
raise attributs.OptionalError("L'objet %s que vous %s doit posséder au moins un attribut %s" % (objet, comment, nom_attr))
|
||||
|
||||
def _post_creation(self):
|
||||
"""Fonction qui effectue quelques tâches lorsque la création est
|
||||
faite"""
|
||||
pass
|
||||
|
||||
def _post_deletion(self):
|
||||
"""Fonction qui effectue quelques tâches lorsque la création est
|
||||
faite"""
|
||||
pass
|
||||
|
||||
def create(self):
|
||||
"""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
|
||||
de le faire."""
|
||||
objet = self.__class__.__name__
|
||||
|
||||
for attribut in self.attribs:
|
||||
if not attribut.optional:
|
||||
nom_attr = attribut.__name__
|
||||
if len(self._modifs.get(nom_attr, [])) <= 0:
|
||||
raise attributs.OptionalError("L'objet %s que vous créez doit posséder au moins un attribut %s" % (objet, nom_attr))
|
||||
self._check_optionnal(comment="créez")
|
||||
|
||||
# Création de la requête LDAP
|
||||
modlist = addModlist(self._modifs.to_ldif())
|
||||
# Requête LDAP de création de l'objet
|
||||
self.conn.add_s(self.dn, modlist)
|
||||
services.services_to_restart(self.conn, {}, self._modifs)
|
||||
self._post_creation()
|
||||
|
||||
def bury(self, comm, login):
|
||||
"""Sauvegarde l'objet dans un fichier dans le cimetière."""
|
||||
self.history_add(login, u"destruction (%s)" % comm)
|
||||
self.save()
|
||||
#On produit un ldif
|
||||
ldif=u"dn: %s\n" % self.dn
|
||||
# On produit un ldif
|
||||
ldif = u"dn: %s\n" % self.dn
|
||||
for key in self.attrs.keys():
|
||||
for value in self.attrs[key]:
|
||||
ldif+=u"%s: %s\n" % (key, value)
|
||||
ldif += u"%s: %s\n" % (key, value)
|
||||
|
||||
import datetime
|
||||
file="%s %s" % (datetime.datetime.now(), self.dn)
|
||||
f = open('/home/cimetiere_lc/%s/%s' % (self['objectClass'][0],file.replace(' ','_')), 'w')
|
||||
file = "%s %s" % (datetime.datetime.now(), self.dn)
|
||||
f = open('/home/cimetiere_lc/%s/%s' % (self['objectClass'][0], file.replace(' ', '_')), 'w')
|
||||
f.write(ldif.encode("UTF-8"))
|
||||
f.close()
|
||||
|
||||
|
@ -218,6 +221,7 @@ class CransLdapObject(object):
|
|||
raise EnvironmentError("Vous n'avez pas le droit de supprimer %s." % self.dn)
|
||||
self.bury(comm, login)
|
||||
self.conn.delete_s(self.dn)
|
||||
self._post_deletion()
|
||||
services.services_to_restart(self.conn, self.attrs, {})
|
||||
|
||||
def save(self):
|
||||
|
@ -227,13 +231,7 @@ class CransLdapObject(object):
|
|||
if self.mode not in ['w', 'rw']:
|
||||
raise EnvironmentError("Objet en lecture seule, réessayer en lecture/écriture")
|
||||
|
||||
objet = self.__class__.__name__
|
||||
|
||||
for attribut in self.attribs:
|
||||
if not attribut.optional:
|
||||
nom_attr = attribut.__name__
|
||||
if len(self._modifs.get(nom_attr, [])) <= 0:
|
||||
raise attributs.OptionalError("L'objet %s que vous créez doit posséder au moins un attribut %s" % (objet, nom_attr))
|
||||
self._check_optionnal(comment="modifiez")
|
||||
|
||||
# On récupère la liste des modifications
|
||||
modlist = self.get_modlist()
|
||||
|
@ -246,12 +244,14 @@ class CransLdapObject(object):
|
|||
services.services_to_restart(self.conn, self.attrs, self._modifs)
|
||||
|
||||
# Vérification des modifications
|
||||
self.attrs = attributs.AttrsDict(self.conn, self.conn.search_s(self.dn, 0)[0][1], Parent=self)
|
||||
old_ldif = 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)
|
||||
differences = []
|
||||
# On fait les différences entre les deux dicos
|
||||
for attr in set(self.attrs.keys()).union(set(self._modifs.keys())):
|
||||
exp_vals = set([unicode(i) for i in self.attrs.get(attr,[])])
|
||||
new_vals = set([unicode(i) for i in self._modifs.get(attr,[])])
|
||||
exp_vals = set([unicode(i) for i in self.attrs.get(attr, [])])
|
||||
new_vals = set([unicode(i) for i in self._modifs.get(attr, [])])
|
||||
if exp_vals != new_vals:
|
||||
differences.append({"missing": exp_vals - new_vals, "having": new_vals - exp_vals})
|
||||
if differences:
|
||||
|
@ -307,7 +307,7 @@ class CransLdapObject(object):
|
|||
raise ValueError("L'objet que vous modifiez n'a pas d'attribut %s" % (attr))
|
||||
# Les valeurs sont nécessairement stockées en liste
|
||||
if not isinstance(values, list):
|
||||
values = [ values ]
|
||||
values = [values]
|
||||
|
||||
# On génére une liste des attributs, le dictionnaire ldif
|
||||
# sert à permettre les vérifications de cardinalité
|
||||
|
@ -317,7 +317,7 @@ class CransLdapObject(object):
|
|||
attrs_before_verif = [ attributs.attrify(val, attr, self.conn, Parent=self) for val in values ]
|
||||
if attr in self.attrs.keys():
|
||||
for attribut in attrs_before_verif:
|
||||
attribut.check_uniqueness([str(content) for content in self.attrs[attr]])
|
||||
attribut.check_uniqueness([content.value for content in self.attrs[attr]])
|
||||
|
||||
# On groupe les attributs précédents, et les nouveaux
|
||||
mixed_attrs = attrs_before_verif + self.attrs[attr]
|
||||
|
@ -390,7 +390,7 @@ class CransLdapObject(object):
|
|||
return blacklist_liste
|
||||
|
||||
def blacklist(self, sanction, commentaire, debut="now", fin = '-'):
|
||||
u"""
|
||||
"""
|
||||
Blacklistage de la ou de toutes la machines du propriétaire
|
||||
* debut et fin sont le nombre de secondes depuis epoch
|
||||
* pour un début ou fin immédiate mettre now
|
||||
|
@ -502,6 +502,7 @@ class proprio(CransLdapObject):
|
|||
return bool_carte
|
||||
return True
|
||||
|
||||
# XXX - To Delete
|
||||
def update_solde(self, diff, comment=u"", login=None):
|
||||
"""Modifie le solde du proprio. diff peut être négatif ou positif."""
|
||||
if login is None:
|
||||
|
@ -578,17 +579,29 @@ class machine(CransLdapObject):
|
|||
black.extend(filter((lambda bl: bl.is_actif()), attrs.get("blacklist",[])))
|
||||
return black
|
||||
|
||||
def _post_creation(self):
|
||||
"""Fonction qui effectue quelques tâches lorsque la création est
|
||||
faite"""
|
||||
if self._proprio:
|
||||
if self._proprio._machines:
|
||||
self._proprio._machines.append(self)
|
||||
|
||||
def _post_deletion(self):
|
||||
"""Fonction qui effectue quelques tâches lorsque l'on veut effacer"""
|
||||
if self._proprio:
|
||||
if self._proprio._machines:
|
||||
self._proprio._machines.remove(self)
|
||||
|
||||
class AssociationCrans(proprio):
|
||||
u""" Association crans (propriétaire particulier)."""
|
||||
def save(self):
|
||||
raise EnvironmentError("AssociationCrans.save(): done.")
|
||||
pass
|
||||
|
||||
def ressuscite(self, comm, login):
|
||||
raise EnvironmentError("Ressusciter le Crans ? Hum…")
|
||||
pass
|
||||
|
||||
def delete(self, comm, login):
|
||||
raise EnvironmentError("Casser le Crans ? Hum…")
|
||||
pass
|
||||
pass
|
||||
|
||||
class BaseInvites(proprio):
|
||||
u"""Un artefact de la base ldap"""
|
||||
|
@ -609,13 +622,11 @@ class adherent(proprio):
|
|||
|
||||
def __init__(self, conn, dn, mode='ro', ldif = None):
|
||||
super(adherent, self).__init__(conn, dn, mode, ldif)
|
||||
if u'cransAccount' in [ str(o) for o in self['objectClass']]:
|
||||
if u'cransAccount' in [ unicode(o) for o in self['objectClass']]:
|
||||
self.attribs = self.attribs + [attributs.uid, attributs.canonicalAlias, attributs.solde,
|
||||
attributs.contourneGreylist, attributs.derniereConnexion,
|
||||
attributs.homepageAlias, attributs.mailAlias, attributs.loginShell ]
|
||||
|
||||
|
||||
|
||||
def compte(self, login = None, uidNumber=0, hash_pass = '', shell=config.login_shell):
|
||||
u"""Renvoie le nom du compte crans. S'il n'existe pas, et que uid
|
||||
est précisé, le crée."""
|
||||
|
@ -707,9 +718,10 @@ class machineWifi(machine):
|
|||
self.history_add(login, u"rid")
|
||||
self.history_add(login, u"ipHostNumber (N/A -> %s)" % ip[0])
|
||||
self.save()
|
||||
from gen_confs.dhcpd_new import dydhcp
|
||||
dhcp=dydhcp()
|
||||
dhcp.add_host(str(self['ipHostNumber'][0]), str(self['macAddress'][0]), str(self['host'][0]))
|
||||
|
||||
for server in config.dhcp_servers:
|
||||
dhcp=dydhcp(server)
|
||||
dhcp.add_host(str(self['ipHostNumber'][0]), str(self['macAddress'][0]), str(self['host'][0]))
|
||||
|
||||
@crans_object
|
||||
class machineCrans(machine):
|
||||
|
@ -730,6 +742,16 @@ class borneWifi(machine):
|
|||
attributs.prise, attributs.positionBorne, attributs.nvram]
|
||||
ldap_name = "borneWifi"
|
||||
|
||||
@crans_object
|
||||
class switchCrans(machine):
|
||||
can_be_by = { variables.created: [attributs.nounou],
|
||||
variables.modified: [attributs.nounou],
|
||||
variables.deleted: [attributs.nounou],
|
||||
}
|
||||
attribs = machine.attribs + [attributs.nombrePrises]
|
||||
|
||||
ldap_name = "switchCrans"
|
||||
|
||||
@crans_object
|
||||
class facture(CransLdapObject):
|
||||
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||
|
@ -742,3 +764,4 @@ class facture(CransLdapObject):
|
|||
@crans_object
|
||||
class service(CransLdapObject):
|
||||
ldap_name = "service"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue