From f22849339914a0038a2f44868e0c23b708541e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Elliott=20B=C3=A9cue?= Date: Tue, 10 Mar 2015 20:06:18 +0100 Subject: [PATCH] =?UTF-8?q?Correctifs=20pour=20le=20commit=20pr=C3=A9c?= =?UTF-8?q?=C3=A9dent,=20et=20de=20quoi=20tester=20le=20cha=C3=AEnage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gestion/config/trigger.py | 4 +-- gestion/trigger/host.py | 3 ++- gestion/trigger/parsers/dhcp.py | 5 ++-- gestion/trigger/parsers/firewall.py | 3 ++- gestion/trigger/parsers/secours.py | 38 ++++++++++++++++++++++++++++ gestion/trigger/producer.py | 1 + gestion/trigger/readme.fr | 8 ++++-- gestion/trigger/services/ack.py | 5 ++-- gestion/trigger/services/dhcp.py | 2 +- gestion/trigger/services/event.py | 7 ++--- gestion/trigger/services/firewall.py | 2 +- gestion/trigger/services/secours.py | 37 +++++++++++++++++++++++++++ 12 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 gestion/trigger/parsers/secours.py create mode 100644 gestion/trigger/services/secours.py diff --git a/gestion/config/trigger.py b/gestion/config/trigger.py index 5f545b0a..1067b8e7 100644 --- a/gestion/config/trigger.py +++ b/gestion/config/trigger.py @@ -23,7 +23,7 @@ services = { 'dhcp' : ["dhcp"], 'dyson' : ["autostatus"], 'isc' : ["dhcp"], - 'komaz' : ["firewall", "secours"], + 'odlyd' : ["firewall", "secours"], 'owl' : ["users"], 'redisdead' : ["mailman", "modif_ldap", "solde", "users", "secours"], 'sable' : ["dns"], @@ -35,4 +35,4 @@ services = { # XXX - Uncomment this when in prod #all_services = set([service for service in itertools.chain(*services.values())]) -all_services = ['dhcp', 'firewall'] +all_services = ['dhcp', 'firewall', 'secours'] diff --git a/gestion/trigger/host.py b/gestion/trigger/host.py index 1fdb99b9..f0bac4ed 100644 --- a/gestion/trigger/host.py +++ b/gestion/trigger/host.py @@ -81,7 +81,7 @@ def record_service(ack=True): # The function does not return. func(*args, **kwargs) - LOGGER.debug("[%r] Ran %r on (%r, %r)", __ob_id, func.func_name, args, kwargs, ) + LOGGER.debug("[%r] Ran %r on (%r, %r)", __ob_id, func.func_name, args, kwargs,) if ack: # We send directly with routing key trigger.ack on the way. @@ -125,6 +125,7 @@ def chaining(pos): def add_pos(func): """Adds the chaining_pos variable to func""" + LOGGER.debug("%r chaining pos : %r", func.func_name, pos) setattr(func, "chaining_pos", pos) return func diff --git a/gestion/trigger/parsers/dhcp.py b/gestion/trigger/parsers/dhcp.py index cfc82626..7ebce849 100644 --- a/gestion/trigger/parsers/dhcp.py +++ b/gestion/trigger/parsers/dhcp.py @@ -13,10 +13,11 @@ This currently is used for mac/IP updates of LDAP database. """ import lc_ldap.attributs -from gestion.trigger.host import record_parser +from gestion.trigger.host import record_parser, chaining @record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) -def send_mac_ip(ob_id, body, diff): +@chaining(1) +def dhcp(ob_id, body, diff): """Computes mac_ip data to send from body and diff The dict contains lists of tuples, so we can iterate on them diff --git a/gestion/trigger/parsers/firewall.py b/gestion/trigger/parsers/firewall.py index bf47c310..bfa9529c 100644 --- a/gestion/trigger/parsers/firewall.py +++ b/gestion/trigger/parsers/firewall.py @@ -11,9 +11,10 @@ This is the parser for firewall service. """ import lc_ldap.attributs -from gestion.trigger.host import record_parser +from gestion.trigger.host import record_parser, chaining @record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) +@chaining(0) def send_mac_ip(ob_id, body, diff): """Computes mac_ip data to send from body and diff diff --git a/gestion/trigger/parsers/secours.py b/gestion/trigger/parsers/secours.py new file mode 100644 index 00000000..88fb1625 --- /dev/null +++ b/gestion/trigger/parsers/secours.py @@ -0,0 +1,38 @@ +#!/bin/bash /usr/scripts/python.sh +# -*- coding: utf-8 -*- +# +# Parser for firewall service. +# +# Author : Pierre-Elliott Bécue +# Licence : GPLv3 +# Date : 15/06/2014 +""" +This is the parser for firewall service. +""" + +import lc_ldap.attributs +from gestion.trigger.host import record_parser, chaining + +@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) +@chaining(0) +def secours(ob_id, body, diff): + """Computes mac_ip data to send from body and diff + + Body is a couple of two dicts (before, after) + + """ + macs = tuple([body[i].get(lc_ldap.attributs.macAddress.ldap_name, [''])[0] for i in xrange(0, 2)]) + ips = tuple([body[i].get(lc_ldap.attributs.ipHostNumber.ldap_name, [''])[0] for i in xrange(0, 2)]) + + # Mise à jour du parefeu mac_ip + if not macs[0]: + # Création d'une nouvelle machine. + fw_dict = {'add': [(macs[1], ips[1])]} + elif not macs[1]: + # Destruction d'une machine. + fw_dict = {'delete': [(macs[0], ips[0])]} + else: + # Mise à jour. + fw_dict = {'update': [(macs[0], ips[0], macs[1], ips[1])]} + return ("secours", ("mac_ip", fw_dict)) + diff --git a/gestion/trigger/producer.py b/gestion/trigger/producer.py index c9796faa..027002c3 100644 --- a/gestion/trigger/producer.py +++ b/gestion/trigger/producer.py @@ -19,6 +19,7 @@ import pika import cranslib.clogger as clogger # Trigger features +import gestion.secrets_new as secrets import gestion.config.trigger as trigger_config logger = clogger.CLogger("trigger", "EventProducer", trigger_config.log_level, trigger_config.debug) diff --git a/gestion/trigger/readme.fr b/gestion/trigger/readme.fr index b6483bf0..74bdd62b 100644 --- a/gestion/trigger/readme.fr +++ b/gestion/trigger/readme.fr @@ -24,7 +24,7 @@ Documentation succincte de trigger Tous les fichiers sont renseignés depuis /usr/scripts. * gestion/trigger/trigger.py est un fichier python qui importe un consumer de - la librairie cmb. Il marche de manière asynchrone, c'est-à-dire qu'il attend et + la librairie cmb. Il marche de manière synchrone, c'est-à-dire qu'il attend et traîte les messages un par un. Dans gestion/config/trigger.py, il y a la liste des services que chaque hôte gère. Ainsi, gestion/trigger/trigger.py sait, en fonction de l'hôte sur lequel il se trouve, comment il doit se comporter, et ce @@ -64,9 +64,10 @@ par exemple, pour un parser : {{{ @record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) -def send_mac_ip(body, diff): +def send_mac_ip(ob_id, body, diff): }}} +ob_id est un hash (??) body est le message reçu par civet sans transformation. diff est le diff calculé à la volée. Le nom de la fonction n'est pas important. Le décorateur prend les noms d'attributs à surveiller en paramètre. La fonction doit retourner un tuple @@ -80,6 +81,8 @@ Pour un service, voici un exemple : def dhcp(body=None): }}} +on devrait appeler "body" autrement, pour éviter de confusionner avec le body +obtenu à l'étape précédente -- Daniel body contient le "body" construit dans un parseur. La fonction est décorée, et son nom est stocké dans la TriggerFactory. Comme souligné précédemment, le nom de la fonction est important, au même titre que le nom des fichiers dans @@ -88,6 +91,7 @@ trigger/parsers et triggers/services. Il faut ensuite référencer le service dans config/trigger.py pour les serveurs où il est important, et relancer trigger sur ces machines. Lors des tests, il ne faut pas hésiter à passer trigger en debug dans le fichier config/trigger.py. +Utilises testing.sh (en rajoutant une variable d'env pour ça), stp. -- Daniel Parmi les choses importantes, l'idéal est d'avoir des dépendances les plus paresseuses possibles d'un point de vue évaluation. Ainsi, civet qui ne fait diff --git a/gestion/trigger/services/ack.py b/gestion/trigger/services/ack.py index f10a17ab..3b96851c 100644 --- a/gestion/trigger/services/ack.py +++ b/gestion/trigger/services/ack.py @@ -39,12 +39,11 @@ def ack(ob_id, service_name): if todo is None: todo = EventTracker.get_off_record(ob_id) logger.info("Emptied one list in the chain %r. Trying to continue. Got %r", ob_id, todo) + else: + todo = [] if todo: for msg in todo: logger.info("Sending %r on the road \\o/", msg) # XXX - uncomment this when in production trigger_send(*msg) - else: - logger.info("Aaaaaand, nothing.") - diff --git a/gestion/trigger/services/dhcp.py b/gestion/trigger/services/dhcp.py index 00683e66..850a1ad8 100644 --- a/gestion/trigger/services/dhcp.py +++ b/gestion/trigger/services/dhcp.py @@ -41,7 +41,7 @@ else: dhcp_omapi_key = None ldap_conn = None -@record_service +@record_service() def dhcp(ob_id, body=None): """Regenerates dhcp service taking body into account. diff --git a/gestion/trigger/services/event.py b/gestion/trigger/services/event.py index 33fc979b..7fb123c6 100644 --- a/gestion/trigger/services/event.py +++ b/gestion/trigger/services/event.py @@ -123,7 +123,7 @@ class EventTracker(object): if dico == True: return [] - if isinstance(bool, dico): + if isinstance(dico, bool): dico = {} return [ @@ -257,9 +257,10 @@ def event(ob_id, before, after, more): #In [16]: b #Out[16]: [('7', 3), (5, 6), ('lol', 'lal'), (3, 'lol')] functions = list(set([function for function in itertools.chain(*[TriggerFactory.get_parser(key) for key in diff]) if function is not None])) + LOGGER.debug("[%r] in service event, functions are %r.", ob_id, functions) # Compute the whole list of messages. This returns a list of 2-tuples. We remove None messages, which - # may occur, since there is chained-services. + # should not occcur... But, whatever. msgs_to_send = [msg for msg in [function(ob_id, (before, after), diff) for function in functions] if msg is not None] LOGGER.debug("[%r] in service event, messages are %r.", ob_id, msgs_to_send) @@ -278,5 +279,5 @@ def event(ob_id, before, after, more): def trigger_send(ob_id, routing_key, body): """Sends a message via civet/trigger""" - body = tuple([ob_id] + [elem for elem in body]) + body = tuple([ob_id] + [body]) PRODUCER.send_message("trigger.%s" % (routing_key,), body) diff --git a/gestion/trigger/services/firewall.py b/gestion/trigger/services/firewall.py index 033e7563..ed84e11e 100644 --- a/gestion/trigger/services/firewall.py +++ b/gestion/trigger/services/firewall.py @@ -41,7 +41,7 @@ class FwFactory(object): def fwrecord(fun): FwFactory.register(fun.func_name, fun) -@record_service +@record_service() def firewall(ob_id, body=()): """Regens the specific service diff --git a/gestion/trigger/services/secours.py b/gestion/trigger/services/secours.py new file mode 100644 index 00000000..3739bf51 --- /dev/null +++ b/gestion/trigger/services/secours.py @@ -0,0 +1,37 @@ +#!/bin/bash /usr/scripts/python.sh +# -*- coding: utf-8 -*- +# +# Service in charge of firewall for trigger. +# Contains multiple subservices for each special +# part of firewall. +# +# Author : Pierre-Elliott Bécue +# Licence : GPLv3 +# Date : 15/06/2014 +""" +Firewall service module. is uses the firewall library as it's, it +is not designed to replace it, just to call specific functions from +it to regenerate what needs to. +""" + +import cranslib.clogger as clogger +import gestion.config.trigger as trigger_config +logger = clogger.CLogger("trigger", "secours", trigger_config.log_level, trigger_config.debug) + +import lc_ldap.shortcuts + +from gestion.trigger.host import record_service +import gestion.trigger.firewall4.firewall4 as firewall4 + +@record_service() +def secours(ob_id, body=()): + """Regens the specific service + + """ + if len(body) != 2: + logger.warning("Received body %r, this format is incorrect, discarding.", body) + return + (service, data) = body + logger.info("Calling service %s for data %r", service, data) + # XXX - Uncomment when in prod + #FwFactory.get(service)(data)