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.
# Contains a trigger which calls good functions from factory.
#
# Author : Pierre-Elliott Bécue <becue@crans.org>
# License : GPLv3
# Date : 28/04/2014
# License : New BSD License
# Date : 10/03/2015
# 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
stores parsers and services metadata.
"""
stores parsers and services metadata."""
import collections
import functools
@ -26,8 +49,22 @@ LOGGER = clogger.CLogger("trigger", "host.py/ack", trigger_config.log_level, tri
PRODUCER = EventProducer("trigger.civet")
# *
# * Factory
# *
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):
"""Stores the attributes to watch and the function"""
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
def get_parser(cls, keyword):
"""Restitutes the parser using keywords"""
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):
@ -98,7 +145,7 @@ def trigger_service(what):
"""Calls the appropriate service"""
return TriggerFactory.get_service(what)
def record_parser(*args):
def record_parser(*watched):
"""Stores the function in TriggerFactory, using args as
keys for the dict"""
@ -114,7 +161,7 @@ def record_parser(*args):
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])
return ret
TriggerFactory.register_parser(args, enhanced_func)
TriggerFactory.register_parser(watched, enhanced_func)
return enhanced_func
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.
"""
import lc_ldap.attributs
import lc_ldap.attributs as attributs
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)
def dhcp(ob_id, operations, diff, more):
"""Computes mac_ip data to send from operations and diff

View file

@ -10,10 +10,10 @@
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
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name)
@record_parser(attributs.macAddress, attributs.ipHostNumber)
@chaining(0)
def send_mac_ip(ob_id, operations, diff, more):
"""Computes mac_ip data to send from operations and diff

View file

@ -10,10 +10,10 @@
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
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name)
@record_parser(attributs.macAddress, attributs.ipHostNumber)
@chaining(0)
def secours(ob_id, body, diff, more):
"""Computes mac_ip data to send from body and diff