[trigger] MetaService en place, et amélioration du débug
This commit is contained in:
parent
d29343392b
commit
a52ef72a54
8 changed files with 202 additions and 146 deletions
|
@ -13,9 +13,9 @@ class CLogger(logging.Logger):
|
||||||
Crans logger
|
Crans logger
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, loggerName, level):
|
def __init__(self, loggerName, service, level, debug=False):
|
||||||
"""
|
"""
|
||||||
Initialise le logger
|
Initializes logger. The debug variable is useful to have a print to stdout (when debugging)
|
||||||
"""
|
"""
|
||||||
super(CLogger, self).__init__(loggerName)
|
super(CLogger, self).__init__(loggerName)
|
||||||
|
|
||||||
|
@ -27,10 +27,17 @@ class CLogger(logging.Logger):
|
||||||
self.fh.setLevel(self.fhlevel)
|
self.fh.setLevel(self.fhlevel)
|
||||||
|
|
||||||
# Creates formatter
|
# Creates formatter
|
||||||
self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
self.formatter = logging.Formatter('%%(asctime)s - %%(name)s - %(service)s - %%(levelname)s - %%(message)s' % {'service': service})
|
||||||
|
|
||||||
# Adds formatter to FileHandler
|
# Adds formatter to FileHandler
|
||||||
self.fh.setFormatter(self.formatter)
|
self.fh.setFormatter(self.formatter)
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
self.sh = logging.StreamHandler()
|
||||||
|
self.shlevel = logging.DEBUG
|
||||||
|
self.sh.setLevel(self.shlevel)
|
||||||
|
self.sh.setFormatter(self.formatter)
|
||||||
|
self.addHandler(self.sh)
|
||||||
|
|
||||||
# Adds FileHandler to Handlers
|
# Adds FileHandler to Handlers
|
||||||
self.addHandler(self.fh)
|
self.addHandler(self.fh)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
|
debug = True
|
||||||
|
|
||||||
# Serveur maître
|
# Serveur maître
|
||||||
master = "civet.adm.crans.org"
|
master = "civet.adm.crans.org"
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TriggerFactory(object):
|
||||||
return cls._meths.values()
|
return cls._meths.values()
|
||||||
|
|
||||||
def record(cls):
|
def record(cls):
|
||||||
TriggerFactory.register(cls.__name__, cls)
|
TriggerFactory.register(cls.__name__.lower(), cls)
|
||||||
|
|
||||||
def trigger(what):
|
def trigger(what):
|
||||||
return TriggerFactory.get(what)
|
return TriggerFactory.get(what)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# Licence : GPLv3
|
# Licence : GPLv3
|
||||||
|
|
||||||
import lc_ldap.shortcuts
|
import lc_ldap.shortcuts
|
||||||
from gestion.trigger.host import record
|
import gestion.config.trigger as trigger_config
|
||||||
from gestion.trigger.services.service import BasicService
|
from gestion.trigger.services.service import BasicService
|
||||||
from cranslib.conffile import ConfFile
|
from cranslib.conffile import ConfFile
|
||||||
import cranslib.clogger as clogger
|
import cranslib.clogger as clogger
|
||||||
|
@ -23,82 +23,25 @@ from gestion.trigger.pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE
|
||||||
from gestion.trigger.pypureomapi import Omapi, OmapiMessage
|
from gestion.trigger.pypureomapi import Omapi, OmapiMessage
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
logger = clogger.CLogger("trigger.dhcp", "debug")
|
logger = clogger.CLogger("trigger", "dhcp", "debug", trigger_config.debug)
|
||||||
hostname = socket.gethostname().split(".")[0] + ".adm.crans.org"
|
hostname = socket.gethostname().split(".")[0] + ".adm.crans.org"
|
||||||
dhcp_omapi_keyname = secrets_new.get("dhcp_omapi_keyname")
|
|
||||||
dhcp_omapi_key = secrets_new.get("dhcp_omapi_keys")[hostname]
|
|
||||||
ldap_conn = lc_ldap.shortcuts.lc_ldap_readonly()
|
ldap_conn = lc_ldap.shortcuts.lc_ldap_readonly()
|
||||||
|
|
||||||
def add_dhcp_host(mac, ip, name=None):
|
|
||||||
"""Adds a dhcp host using omapi
|
|
||||||
|
|
||||||
"""
|
class Dhcp(BasicService):
|
||||||
|
|
||||||
if '<automatique>' in [ip, mac]:
|
|
||||||
return
|
|
||||||
msg = OmapiMessage.open(b"host")
|
|
||||||
msg.message.append((b"create", struct.pack("!I", 1)))
|
|
||||||
msg.message.append((b"exclusive", struct.pack("!I", 1)))
|
|
||||||
msg.obj.append((b"hardware-address", pack_mac(mac)))
|
|
||||||
msg.obj.append((b"hardware-type", struct.pack("!I", 1)))
|
|
||||||
msg.obj.append((b"ip-address", pack_ip(ip)))
|
|
||||||
if name:
|
|
||||||
msg.obj.append((b"name", bytes(name)))
|
|
||||||
conn = Omapi(hostname, 9991, dhcp_omapi_keyname, dhcp_omapi_key)
|
|
||||||
response = conn.query_server(msg)
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def delete_dhcp_host(mac, ip):
|
|
||||||
"""Deletes dhcp host using omapi
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
if '<automatique>' in [ip, mac]:
|
|
||||||
return
|
|
||||||
msg = OmapiMessage.open(b"host")
|
|
||||||
msg.obj.append((b"hardware-address", pack_mac(mac)))
|
|
||||||
msg.obj.append((b"hardware-type", struct.pack("!I", 1)))
|
|
||||||
msg.obj.append((b"ip-address", pack_ip(ip)))
|
|
||||||
conn = Omapi(hostname, 9991, dhcp_omapi_keyname, dhcp_omapi_key)
|
|
||||||
response = conn.query_server(msg)
|
|
||||||
if response.opcode == OMAPI_OP_UPDATE:
|
|
||||||
response = conn.query_server(OmapiMessage.delete(response.handle))
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def lease_clean():
|
|
||||||
"""Clean the lease file
|
|
||||||
|
|
||||||
"""
|
|
||||||
# TODO : use ConfigFile structure
|
|
||||||
leasefile = open(dhcp_config.dhcplease)
|
|
||||||
newleasefile = open(dhcp_config.dhcplease + '.new', 'w')
|
|
||||||
config = ""
|
|
||||||
line = leasefile.readline()
|
|
||||||
write = True
|
|
||||||
while line:
|
|
||||||
if line.strip().startswith('host'):
|
|
||||||
write = False
|
|
||||||
if write:
|
|
||||||
newleasefile.write(line)
|
|
||||||
if not write and line.strip().endswith('}'):
|
|
||||||
write = True
|
|
||||||
line = leasefile.readline()
|
|
||||||
leasefile.close()
|
|
||||||
newleasefile.close()
|
|
||||||
os.rename(dhcp_config.dhcplease+'.new', dhcp_config.dhcplease)
|
|
||||||
|
|
||||||
@record
|
|
||||||
class dhcp(BasicService):
|
|
||||||
"""Class responsible of dhcp service.
|
"""Class responsible of dhcp service.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Class lookup table to define which changes call which function.
|
# Class lookup table to define which changes call which function.
|
||||||
changes_trigger = {
|
changes_trigger = {
|
||||||
lc_ldap.attributs.macAddress.ldap_name: (dhcp.send_mac_ip,),
|
lc_ldap.attributs.macAddress.ldap_name: ('send_mac_ip',),
|
||||||
lc_ldap.attributs.ipHostNumber.ldap_name: (dhcp.send_mac_ip,),
|
lc_ldap.attributs.ipHostNumber.ldap_name: ('send_mac_ip',),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dhcp_omapi_keyname = None
|
||||||
|
dhcp_omapi_key = None #secrets_new.get("dhcp_omapi_keys")[hostname]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def send_mac_ip(cls, body, diff):
|
def send_mac_ip(cls, body, diff):
|
||||||
"""Computes mac_ip data to send from body and diff
|
"""Computes mac_ip data to send from body and diff
|
||||||
|
@ -111,14 +54,14 @@ class dhcp(BasicService):
|
||||||
# Régénération du DHCP :
|
# Régénération du DHCP :
|
||||||
if not macs[0]:
|
if not macs[0]:
|
||||||
# Création d'une nouvelle machine.
|
# Création d'une nouvelle machine.
|
||||||
dhcp = {'add': [(macs[1], ips[1], hostnames[1])]}
|
dhcp_dict = {'add': [(macs[1], ips[1], hostnames[1])]}
|
||||||
elif not macs[1]:
|
elif not macs[1]:
|
||||||
# Destruction d'une machine.
|
# Destruction d'une machine.
|
||||||
dhcp = {'delete': [(macs[0], ips[0])]}
|
dhcp_dict = {'delete': [(macs[0], ips[0])]}
|
||||||
else:
|
else:
|
||||||
# Mise à jour.
|
# Mise à jour.
|
||||||
dhcp = {'update': [(macs[0], ips[0], macs[1], ips[1], hostnames[1])]}
|
dhcp_dict = {'update': [(macs[0], ips[0], macs[1], ips[1], hostnames[1])]}
|
||||||
return ("dhcp", dhcp)
|
return ("dhcp", dhcp_dict)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def regen(cls, body=None):
|
def regen(cls, body=None):
|
||||||
|
@ -132,12 +75,12 @@ class dhcp(BasicService):
|
||||||
|
|
||||||
if body and isinstance(body, dict):
|
if body and isinstance(body, dict):
|
||||||
for (mac, ip, name) in body.get("add", []):
|
for (mac, ip, name) in body.get("add", []):
|
||||||
add_dhcp_host(mac, ip, name)
|
cls.add_dhcp_host(mac, ip, name)
|
||||||
for (mac, ip) in body.get("delete", []):
|
for (mac, ip) in body.get("delete", []):
|
||||||
delete_dhcp_host(mac, ip)
|
cls.delete_dhcp_host(mac, ip)
|
||||||
for (rmac, rip, mac, ip, name) in body.get("update", []):
|
for (rmac, rip, mac, ip, name) in body.get("update", []):
|
||||||
delete_dhcp_host(rmac, rip)
|
cls.delete_dhcp_host(rmac, rip)
|
||||||
add_dhcp_host(mac, ip, name)
|
cls.add_dhcp_host(mac, ip, name)
|
||||||
elif body == True:
|
elif body == True:
|
||||||
hosts = {}
|
hosts = {}
|
||||||
host_template = """
|
host_template = """
|
||||||
|
@ -186,9 +129,85 @@ class dhcp(BasicService):
|
||||||
step = "Nettoyage des fichiers de leases"
|
step = "Nettoyage des fichiers de leases"
|
||||||
affichage.prettyDoin(step, "...")
|
affichage.prettyDoin(step, "...")
|
||||||
try:
|
try:
|
||||||
lease_clean()
|
cls.lease_clean()
|
||||||
affichage.prettyDoin(step, "Ok")
|
affichage.prettyDoin(step, "Ok")
|
||||||
except:
|
except:
|
||||||
affichage.prettyDoin(step, "Erreur")
|
affichage.prettyDoin(step, "Erreur")
|
||||||
print "During lease clean, an error occured."
|
print "During lease clean, an error occured."
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def check_secrets(cls):
|
||||||
|
"""This method allows lazy evaluation for dhcp_omapi_keyname
|
||||||
|
and dhcp_omapi_key, since event imports all services. This is actually
|
||||||
|
the best lazy eval we can hope, since property won't work on
|
||||||
|
classmethods.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if cls.dhcp_omapi_keyname is None:
|
||||||
|
cls.dhcp_omapi_keyname = secrets_new.get("dhcp_omapi_keyname")
|
||||||
|
if cls.dhcp_omapi_key is None:
|
||||||
|
cls.dhcp_omapi_key = secrets_new.get("dhcp_omapi_keys")[hostname]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_dhcp_host(cls, mac, ip, name=None):
|
||||||
|
"""Adds a dhcp host using omapi
|
||||||
|
|
||||||
|
"""
|
||||||
|
cls.check_secrets()
|
||||||
|
|
||||||
|
if '<automatique>' in [ip, mac]:
|
||||||
|
return
|
||||||
|
msg = OmapiMessage.open(b"host")
|
||||||
|
msg.message.append((b"create", struct.pack("!I", 1)))
|
||||||
|
msg.message.append((b"exclusive", struct.pack("!I", 1)))
|
||||||
|
msg.obj.append((b"hardware-address", pack_mac(mac)))
|
||||||
|
msg.obj.append((b"hardware-type", struct.pack("!I", 1)))
|
||||||
|
msg.obj.append((b"ip-address", pack_ip(ip)))
|
||||||
|
if name:
|
||||||
|
msg.obj.append((b"name", bytes(name)))
|
||||||
|
conn = Omapi(hostname, 9991, cls.dhcp_omapi_keyname, cls.dhcp_omapi_key)
|
||||||
|
_ = conn.query_server(msg)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete_dhcp_host(cls, mac, ip):
|
||||||
|
"""Deletes dhcp host using omapi
|
||||||
|
|
||||||
|
"""
|
||||||
|
cls.check_secrets()
|
||||||
|
|
||||||
|
if '<automatique>' in [ip, mac]:
|
||||||
|
return
|
||||||
|
msg = OmapiMessage.open(b"host")
|
||||||
|
msg.obj.append((b"hardware-address", pack_mac(mac)))
|
||||||
|
msg.obj.append((b"hardware-type", struct.pack("!I", 1)))
|
||||||
|
msg.obj.append((b"ip-address", pack_ip(ip)))
|
||||||
|
conn = Omapi(hostname, 9991, cls.dhcp_omapi_keyname, cls.dhcp_omapi_key)
|
||||||
|
response = conn.query_server(msg)
|
||||||
|
if response.opcode == OMAPI_OP_UPDATE:
|
||||||
|
_ = conn.query_server(OmapiMessage.delete(response.handle))
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def lease_clean():
|
||||||
|
"""Clean the lease file
|
||||||
|
|
||||||
|
"""
|
||||||
|
# TODO : use ConfigFile structure
|
||||||
|
leasefile = open(dhcp_config.dhcplease)
|
||||||
|
newleasefile = open(dhcp_config.dhcplease + '.new', 'w')
|
||||||
|
line = leasefile.readline()
|
||||||
|
write = True
|
||||||
|
while line:
|
||||||
|
if line.strip().startswith('host'):
|
||||||
|
write = False
|
||||||
|
if write:
|
||||||
|
newleasefile.write(line)
|
||||||
|
if not write and line.strip().endswith('}'):
|
||||||
|
write = True
|
||||||
|
line = leasefile.readline()
|
||||||
|
leasefile.close()
|
||||||
|
newleasefile.close()
|
||||||
|
os.rename(dhcp_config.dhcplease+'.new', dhcp_config.dhcplease)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import cPickle
|
||||||
import pika
|
import pika
|
||||||
import importlib
|
import importlib
|
||||||
import itertools
|
import itertools
|
||||||
|
import traceback
|
||||||
|
|
||||||
# Trigger features
|
# Trigger features
|
||||||
import gestion.config.trigger as trigger_config
|
import gestion.config.trigger as trigger_config
|
||||||
|
@ -30,20 +31,24 @@ import cranslib.clogger as clogger
|
||||||
# lc_ldap
|
# lc_ldap
|
||||||
import lc_ldap.attributs
|
import lc_ldap.attributs
|
||||||
|
|
||||||
logger = clogger.CLogger("trigger.event", "info")
|
logger = clogger.CLogger("trigger", "event", "debug", trigger_config.debug)
|
||||||
|
|
||||||
services = [importlib.import_module("gestion.trigger.services.%s" % (config_service,)) for config_service in trigger_config.all_services]
|
for config_service in trigger_config.all_services:
|
||||||
|
try:
|
||||||
|
services.append(importlib.import_module("gestion.trigger.services.%s" % (config_service,)))
|
||||||
|
except Exception as e:
|
||||||
|
logger.critical("Fatal : import of %r failed, see following traceback. %r", config_service, traceback.format_exc())
|
||||||
|
|
||||||
class Event(cmb.BasicProducer):
|
class EventProducer(cmb.BasicProducer):
|
||||||
"""
|
"""
|
||||||
Event tracker
|
EventProducer tracker
|
||||||
"""
|
"""
|
||||||
def __init__(self, app_id):
|
def __init__(self, app_id):
|
||||||
"""Extended
|
"""Extended
|
||||||
|
|
||||||
"""
|
"""
|
||||||
logger.info("Starting trigger Event program…")
|
logger.info("Starting trigger EventProducer program…")
|
||||||
super(Event, self).__init__(trigger_config.master, 'trigger', app_id)
|
super(EventProducer, self).__init__(trigger_config.master, 'trigger', app_id)
|
||||||
self._connection = self.connect()
|
self._connection = self.connect()
|
||||||
self.get_chan()
|
self.get_chan()
|
||||||
|
|
||||||
|
@ -127,7 +132,6 @@ def compare_lists(list1, list2):
|
||||||
|
|
||||||
return moins, plus
|
return moins, plus
|
||||||
|
|
||||||
@record
|
|
||||||
class event(BasicService):
|
class event(BasicService):
|
||||||
"""Event service class. It extends BasicService, but should not implement
|
"""Event service class. It extends BasicService, but should not implement
|
||||||
any change trigger, since it's this service which is designed to call
|
any change trigger, since it's this service which is designed to call
|
||||||
|
@ -187,5 +191,5 @@ class event(BasicService):
|
||||||
# trigger_send(*msg)
|
# trigger_send(*msg)
|
||||||
|
|
||||||
def trigger_send(routing_key, body):
|
def trigger_send(routing_key, body):
|
||||||
sender = Event("civet")
|
sender = EventProducer("civet")
|
||||||
sender.send_message("trigger.%s" % (routing_key,), body)
|
sender.send_message("trigger.%s" % (routing_key,), body)
|
||||||
|
|
|
@ -15,57 +15,22 @@ it to regenerate what needs to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import lc_ldap.shortcuts
|
import lc_ldap.shortcuts
|
||||||
from gestion.trigger.host import record
|
import gestion.config.trigger as trigger_config
|
||||||
from gestion.trigger.services.service import BasicService
|
from gestion.trigger.services.service import BasicService
|
||||||
import cranslib.clogger as clogger
|
import cranslib.clogger as clogger
|
||||||
import gestion.config.firewall as firewall_config
|
|
||||||
import gestion.trigger.firewall4.firewall4 as firewall4
|
import gestion.trigger.firewall4.firewall4 as firewall4
|
||||||
|
|
||||||
logger = clogger.CLogger("trigger.firewall", "debug")
|
logger = clogger.CLogger("trigger", "firewall", "debug", trigger_config.debug)
|
||||||
|
|
||||||
class FwFunFactory(object):
|
class Firewall(BasicService):
|
||||||
"""Factory containing which function is part of the trigger set
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
_meths = {}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register(cls, key, value):
|
|
||||||
"""Stores in factory the function name and its value
|
|
||||||
|
|
||||||
"""
|
|
||||||
cls._meths[key] = value
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get(cls, key):
|
|
||||||
"""Gets what is stored
|
|
||||||
|
|
||||||
"""
|
|
||||||
return cls._meths.get(key, None)
|
|
||||||
|
|
||||||
def fwrecord(function):
|
|
||||||
"""Records function in FwFunFactory
|
|
||||||
|
|
||||||
"""
|
|
||||||
FwFunFactory.register(function.func_name, function)
|
|
||||||
|
|
||||||
def fwcall(fwfun):
|
|
||||||
"""Calls in function from FwFunFactory
|
|
||||||
|
|
||||||
"""
|
|
||||||
return FwFunFactory.get(fwfun)
|
|
||||||
|
|
||||||
@record
|
|
||||||
class firewall(BasicService):
|
|
||||||
"""Firewall service that handles any modification in the firewall.
|
"""Firewall service that handles any modification in the firewall.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Class lookup table to define which changes call which function.
|
# Class lookup table to define which changes call which function.
|
||||||
changes_trigger = {
|
changes_trigger = {
|
||||||
lc_ldap.attributs.macAddress.ldap_name: (firewall.send_mac_ip,),
|
lc_ldap.attributs.macAddress.ldap_name: ('send_mac_ip',),
|
||||||
lc_ldap.attributs.ipHostNumber.ldap_name: (firewall.send_mac_ip,),
|
lc_ldap.attributs.ipHostNumber.ldap_name: ('send_mac_ip',),
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -98,10 +63,10 @@ class firewall(BasicService):
|
||||||
return
|
return
|
||||||
(service, data) = body
|
(service, data) = body
|
||||||
logger.info("Calling service %s for data %r", service, data)
|
logger.info("Calling service %s for data %r", service, data)
|
||||||
fwcall(service)(data)
|
getattr(cls, service)(data)
|
||||||
|
|
||||||
@fwrecord
|
@classmethod
|
||||||
def mac_ip(body):
|
def mac_ip(cls, body):
|
||||||
host_fw = firewall4.firewall()
|
host_fw = firewall4.firewall()
|
||||||
if body and isinstance(body, dict):
|
if body and isinstance(body, dict):
|
||||||
for (mac, ip) in body.get("add", []):
|
for (mac, ip) in body.get("add", []):
|
||||||
|
|
|
@ -6,11 +6,65 @@ This module provides a basic service class to other services. It should *NOT*
|
||||||
be referenced in configuration of trigger.
|
be referenced in configuration of trigger.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import collections
|
||||||
|
|
||||||
|
import cranslib.clogger as clogger
|
||||||
|
import gestion.config.trigger as trigger_config
|
||||||
|
from gestion.trigger.host import TriggerFactory
|
||||||
|
|
||||||
|
logger = clogger.CLogger("trigger", "service", "debug", trigger_config.debug)
|
||||||
|
|
||||||
|
class MetaService(type):
|
||||||
|
"""Metaclass designed to handle all services.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(mcs, cname, cpar, cattrs):
|
||||||
|
"""Method producing the new class itself
|
||||||
|
At first, I wanted to put the changes_trigger modification in __new__,
|
||||||
|
using direct modification of cattrs['changes_trigger'] by pointing the
|
||||||
|
required methods (classmethods). The problem was that these methods were
|
||||||
|
bound at the return of type.__new__, for a reason I could not exactly
|
||||||
|
explain.
|
||||||
|
|
||||||
|
I found a workaround using __init__, so the point would be to remove
|
||||||
|
__new__, and directly use type.__new__, but this comment seems useful,
|
||||||
|
so __new__ will survive.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return super(MetaService, mcs).__new__(mcs, cname, cpar, cattrs)
|
||||||
|
|
||||||
|
def __init__(cls, cname, cpar, cattrs):
|
||||||
|
"""Used to register the generated classes in TriggerFactory, and modify the behavior of
|
||||||
|
changes_trigger by pointing functions instead of their names. This allows to cancel any
|
||||||
|
positional requirement in class definition.
|
||||||
|
|
||||||
|
Do NEVER return something in __init__ function.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not cname == "BasicService":
|
||||||
|
TriggerFactory.register(cname.lower(), cls)
|
||||||
|
changes_trigger = collections.defaultdict(list)
|
||||||
|
# I love getattr
|
||||||
|
text_changes_trigger = getattr(cls, "changes_trigger", {})
|
||||||
|
for (ldap_attr_name, funcs_name) in text_changes_trigger.items():
|
||||||
|
for func_name in funcs_name:
|
||||||
|
# I really love getattr.
|
||||||
|
get = getattr(cls, func_name, None)
|
||||||
|
if get is None:
|
||||||
|
logger.critical("Fatal, bad function (%r) reference in %r.", func_name, cname)
|
||||||
|
continue
|
||||||
|
changes_trigger[ldap_attr_name].append(get)
|
||||||
|
setattr(cls, "changes_trigger", changes_trigger)
|
||||||
|
super(MetaService, cls).__init__(cname, cpar, cattrs)
|
||||||
|
|
||||||
class BasicService(object):
|
class BasicService(object):
|
||||||
"""Basic service handler. Other services should inherit fron this one.
|
"""Basic service handler. Other services should inherit fron this one.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
__metaclass__ = MetaService
|
||||||
|
|
||||||
changes_trigger = {}
|
changes_trigger = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -11,16 +11,19 @@
|
||||||
# Date : 29/04/2014
|
# Date : 29/04/2014
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import cranslib.clogger as clogger
|
|
||||||
import cmb
|
|
||||||
import cPickle
|
import cPickle
|
||||||
import socket
|
import socket
|
||||||
|
import traceback
|
||||||
|
import sys
|
||||||
|
|
||||||
import gestion.config.trigger as trigger_config
|
import gestion.config.trigger as trigger_config
|
||||||
import gestion.affichage as affichage
|
import gestion.affichage as affichage
|
||||||
import sys
|
|
||||||
from gestion.trigger.host import trigger
|
from gestion.trigger.host import trigger
|
||||||
|
import cranslib.clogger as clogger
|
||||||
|
import cmb
|
||||||
|
|
||||||
hostname = socket.gethostname().split(".")[0]
|
hostname = socket.gethostname().split(".")[0]
|
||||||
|
logger = clogger.CLogger("trigger", "trigger", "info", trigger_config.debug)
|
||||||
|
|
||||||
# Ce bloc contient le peu de "magie" de la librairie, on utilise les services listés dans config/trigger.py
|
# Ce bloc contient le peu de "magie" de la librairie, on utilise les services listés dans config/trigger.py
|
||||||
# comme référence. Pour éviter toute redondance, la commande importe donc les services utiles suivant cette
|
# comme référence. Pour éviter toute redondance, la commande importe donc les services utiles suivant cette
|
||||||
|
@ -30,8 +33,10 @@ hostname = socket.gethostname().split(".")[0]
|
||||||
import importlib
|
import importlib
|
||||||
services = {}
|
services = {}
|
||||||
for config_service in trigger_config.services[hostname]:
|
for config_service in trigger_config.services[hostname]:
|
||||||
|
try:
|
||||||
services[config_service] = importlib.import_module("gestion.trigger.services.%s" % (config_service,))
|
services[config_service] = importlib.import_module("gestion.trigger.services.%s" % (config_service,))
|
||||||
logger = clogger.CLogger("trigger", "info")
|
except Exception as e:
|
||||||
|
logger.critical("Fatal : import of %r failed, see following traceback. %r", config_service, traceback.format_exc())
|
||||||
|
|
||||||
class EvenementListener(cmb.AsynchronousConsumer):
|
class EvenementListener(cmb.AsynchronousConsumer):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue