[trigger] Event probablement fonctionnel, need further tests.

This commit is contained in:
Pierre-Elliott Bécue 2014-06-14 16:44:44 +02:00
parent 31336bcc30
commit d45f55dae6
2 changed files with 110 additions and 3 deletions

View file

@ -15,7 +15,7 @@ services = {
'dhcp' : ["dhcp"], 'dhcp' : ["dhcp"],
'dyson' : ["autostatus"], 'dyson' : ["autostatus"],
'isc' : ["dhcp"], 'isc' : ["dhcp"],
'komaz' : ["firewall", "secours"], 'komaz' : ["mac_ip", "secours"],
'owl' : ["userdel"], 'owl' : ["userdel"],
'redisdead' : ["mailman", "modif_ldap", "solde", "userdel", "secours"], 'redisdead' : ["mailman", "modif_ldap", "solde", "userdel", "secours"],
'sable' : ["dns"], 'sable' : ["dns"],

View file

@ -13,6 +13,7 @@ import gestion.config.trigger as trigger_config
from gestion.trigger.host import record from gestion.trigger.host import record
import cranslib.clogger as clogger import cranslib.clogger as clogger
import pika import pika
import lc_ldap.attributs
logger = clogger.CLogger("trigger", "info") logger = clogger.CLogger("trigger", "info")
@ -50,10 +51,116 @@ class Event(cmb.BasicProducer):
def announce(self, body): def announce(self, body):
self.send_message("trigger.announce", body) self.send_message("trigger.announce", body)
def diff_o_matic(body=()):
"""Fait un diff exhaustif des deux dicos"""
if not body:
raise("diff_o_matic received %r as an argument, which is unusable." % (body,))
before = body[1] or {}
after = body[2] or {}
# set(dico) retourne un set de dico.keys()
keys_pool = set(before).union(set(after))
diff = {}
for key in key_pool:
if before.has_key(key):
if not isinstance(before[key], list):
blist = [before[key]]
else:
blist = before[key]
else:
blist = []
if after.has_key(key):
if not isinstance(after[key], list):
alist = [after[key]]
else:
alist = after[key]
else:
alist = []
moins, plus = compare_lists(blist, alist)
if moins != [] or plus != []:
diff[key] = (moins, plus)
return diff
def compare_lists(list1, list2):
"""Compare deux listes, retourne deux listes, une
avec les données perdues, et une avec les données
apparues
Insensible à la casse.
"""
moins, plus = [], []
llist2 = [a.lower() for a in list2]
for elem in [] + list1:
try:
ind = list2.index(elem.lower())
except ValueError:
moins.append(elem)
continue
list1.remove(elem)
list2.pop(ind)
plus = plus + list2
return moins, plus
@record @record
def event(body={}): def event(body=()):
"""Trigger event qui transcrit toute modif ldap en truc exploitable par """Trigger event qui transcrit toute modif ldap en truc exploitable par
trigger. Warning, bootstrap incoming. trigger. Warning, bootstrap incoming.
body est exceptionnellement un tuple. Pour être précis, un 3-tuple.
Le premier élément est le dn de l'objet LDAP, il est pas indispensable.
Le deuxième est un dico qui recense l'état complet de l'objet modifié avant
validation des modifications.
Le troisième est un dico qui recense l'état complet de l'objet modifié après
modification.
Si l'objet vient d'être créé, le deuxième élément est None.
Si l'objet vient d'être supprimé, le troisième élément vaut None.
Il faut donc faire un diff, générer la liste des triggers à envoyer, puis
les envoyer.
""" """
pass
diff = diff_o_matic(body)
# À cette étape, on a un dico des attrs ayant subi une modif
# a["macAddress"] par exemple, pourrait ressembler à
# (["aa:bb:cc:dd:ee:fg"], ["aa:bb:cc:dd:ee:ff"]), la liste de gauche
# étant les trucs perdus, celle de droite ceux gagnés. Suivant le type
# des attributs, ça peut être un remplacement (mac, ip...), ou juste
# des retraits/ajouts (mailAlias...)
# Avec ça on peut trigger tout ce qu'on veut.
# Si la mac ou l'IP a changé…
if diff.has_key(lc_ldap.attributs.ipHostNumber.ldap_name) or diff.has_key(lc_ldap.attributs.macAddress.ldap_name):
trigger_mac_ip(body, diff)
def trigger_mac_ip(body, diff):
macs = tuple([body[i].get(lc_ldap.attributs.macAddress.ldap_name, [''])[0] for i in xrange(1, 3)])
ips = tuple([body[i].get(lc_ldap.attributs.ipHostNumber.ldap_name, [''])[0] for i in xrange(1, 3)])
hostnames = tuple([body[i].get(lc_ldap.attributs.host.ldap_name, [''])[0] for i in xrange(1, 3)])
# Régénération du DHCP :
if not macs[0]:
# Création d'une nouvelle machine.
to_send = {'add': (macs[1], ips[1], hostnames[1])}
elif not macs[1]:
# Destruction d'une machine.
to_send = {'delete': (macs[0], ips[0])}
else:
# Mise à jour.
to_send = {'update': (macs[0], ips[0], macs[1], ips[1], hostnames[1])}
trigger_send('dhcp', to_send)
# Régénération du parefeu.
trigger_send('mac_ip', to_send)
def trigger_send(ttype, to_send):
print "Sending trigger %s with %s" % (ttype, to_send)