explicit.is.better.than.too.explicit.dude.

This commit is contained in:
Pierre-Elliott Bécue 2015-03-10 21:51:08 +01:00
parent c0aa3c0e48
commit b470c860c0
4 changed files with 65 additions and 18 deletions

View file

@ -6,12 +6,35 @@
# decorated with @record. # decorated with @record.
# Contains a trigger which calls good functions from factory. # Contains a trigger which calls good functions from factory.
# #
# Author : Pierre-Elliott Bécue <becue@crans.org> # License : New BSD License
# License : GPLv3 # Date : 10/03/2015
# Date : 28/04/2014 # Copyright : Pierre-Elliott Bécue <becue@crans.org>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the <organization> nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""This module provides host functions for trigger, such as the TriggerFactory which """This module provides host functions for trigger, such as the TriggerFactory which
stores parsers and services metadata. stores parsers and services metadata."""
"""
import collections import collections
import functools import functools
@ -26,8 +49,22 @@ LOGGER = clogger.CLogger("trigger", "host.py/ack", trigger_config.log_level, tri
PRODUCER = EventProducer("trigger.civet") PRODUCER = EventProducer("trigger.civet")
# *
# * Factory
# *
class TriggerFactory(object): class TriggerFactory(object):
"""Factory containing which function is part of the trigger set """The TriggerFactory is designed to store services and parsers.
* services are functions decorated with record_service, and, possibly,
chaining. Such functions are designed to do some operations on
servers in order to take into account LDAP modifications (or,
potentially, whatever else).
* parsers are functions decorated with record parsers, which are
triggered by some keywords (eg, ldap attributes names whose values
have been modified). They return stuff to do, and a service to
call.
""" """
@ -53,17 +90,27 @@ class TriggerFactory(object):
def register_parser(cls, keys, parser): def register_parser(cls, keys, parser):
"""Stores the attributes to watch and the function""" """Stores the attributes to watch and the function"""
for key in keys: for key in keys:
cls._parsers[key].append(parser) if not isinstance(key, str) and not isinstance(key, unicode):
key = getattr(key, 'ldap_name', None)
if key is not None:
cls._parsers[key].append(parser)
else:
LOGGER.debug("Problem when recording parser %r on keys %r.", parser.func_name, keys)
@classmethod @classmethod
def get_parser(cls, keyword): def get_parser(cls, keyword):
"""Restitutes the parser using keywords""" """Restitutes the parser using keywords"""
return cls._parsers[keyword] return cls._parsers[keyword]
def record_service(ack=True): # *
"""Records in the triggerfactory the function # * Factory manipulation
# *
The function provided are services to regen def record_service(ack=True):
"""Records a service in the TriggerFactory.
It uses its name as a key for reference, the value being
the function itself.
""" """
def enhance_func(func): def enhance_func(func):
@ -98,7 +145,7 @@ def trigger_service(what):
"""Calls the appropriate service""" """Calls the appropriate service"""
return TriggerFactory.get_service(what) return TriggerFactory.get_service(what)
def record_parser(*args): def record_parser(*watched):
"""Stores the function in TriggerFactory, using args as """Stores the function in TriggerFactory, using args as
keys for the dict""" keys for the dict"""
@ -114,7 +161,7 @@ def record_parser(*args):
ret = [elem for elem in ret] + [getattr(func, "chaining_pos", 0)] ret = [elem for elem in ret] + [getattr(func, "chaining_pos", 0)]
LOGGER.debug("[%r] In record_parser.find_parser, for %r got chaining_pos %r", __ob_id, func.func_name, ret[-1]) LOGGER.debug("[%r] In record_parser.find_parser, for %r got chaining_pos %r", __ob_id, func.func_name, ret[-1])
return ret return ret
TriggerFactory.register_parser(args, enhanced_func) TriggerFactory.register_parser(watched, enhanced_func)
return enhanced_func return enhanced_func
return find_parser return find_parser

View file

@ -12,10 +12,10 @@ Handles the parser for trigger about dhcp service
This currently is used for mac/IP updates of LDAP database. This currently is used for mac/IP updates of LDAP database.
""" """
import lc_ldap.attributs import lc_ldap.attributs as attributs
from gestion.trigger.host import record_parser, chaining from gestion.trigger.host import record_parser, chaining
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) @record_parser(attributs.macAddress, attributs.ipHostNumber)
@chaining(1) @chaining(1)
def dhcp(ob_id, operations, diff, more): def dhcp(ob_id, operations, diff, more):
"""Computes mac_ip data to send from operations and diff """Computes mac_ip data to send from operations and diff

View file

@ -10,10 +10,10 @@
This is the parser for firewall service. This is the parser for firewall service.
""" """
import lc_ldap.attributs import lc_ldap.attributs as attributs
from gestion.trigger.host import record_parser, chaining from gestion.trigger.host import record_parser, chaining
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) @record_parser(attributs.macAddress, attributs.ipHostNumber)
@chaining(0) @chaining(0)
def send_mac_ip(ob_id, operations, diff, more): def send_mac_ip(ob_id, operations, diff, more):
"""Computes mac_ip data to send from operations and diff """Computes mac_ip data to send from operations and diff

View file

@ -10,10 +10,10 @@
This is the parser for firewall service. This is the parser for firewall service.
""" """
import lc_ldap.attributs import lc_ldap.attributs as attributs
from gestion.trigger.host import record_parser, chaining from gestion.trigger.host import record_parser, chaining
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name) @record_parser(attributs.macAddress, attributs.ipHostNumber)
@chaining(0) @chaining(0)
def secours(ob_id, body, diff, more): def secours(ob_id, body, diff, more):
"""Computes mac_ip data to send from body and diff """Computes mac_ip data to send from body and diff