univention.listener package

Listener module API

To create a listener module (LM) with this API, create a Python file in /usr/lib/univention-directory-listener/system/ which includes:

  1. a subclass of ListenerModuleHandler

  2. with an inner class Configuration that has at least the class attributes name, description and ldap_filter

See /usr/share/doc/univention-directory-listener/examples/ for examples.

class univention.listener.ListenerModuleAdapter(module_configuration, *args, **kwargs)[source]

Bases: object

Adapter to convert the univention.listener.listener_module interface to the existing listener module interface.

Use in a classic listener module like this:

globals().update(ListenerModuleAdapter(MyListenerModuleConfiguration()).get_globals())

Parameters

module_configuration (ListenerModuleConfiguration) – configuration object

get_globals()[source]

Returns the variables to be written to the module namespace, that make up the legacy listener module interface.

Returns

a mapping with keys: name, description, filter_s, attributes, modrdn, handler, initialize, clean, prerun, postrun, setdata, ..

Return type

dict

exception univention.listener.ListenerModuleConfigurationError[source]

Bases: univention.listener.exceptions.ListenerModuleError

exception univention.listener.ListenerModuleRuntimeError[source]

Bases: univention.listener.exceptions.ListenerModuleError

class univention.listener.ListenerModuleConfiguration(*args, **kwargs)[source]

Bases: object

Interface class for accessing the configuration and code of a listener module.

Subclass this and set the class attributes or pass them through __init__. If more logic is needed, overwrite the corresponding get_<attribute> method. Setting name, description, ldap_filter and listener_module_class is mandatory.

To extend the configuration, add key names in get_configuration_keys() and create a get_<attribute> method.

The listener server will use an object of your subclass to access your listener module through:

  1. get_configuration()

  2. get_listener_module_instance()

name = ''
description = ''
ldap_filter = ''
listener_module_class = None
attributes = []
get_configuration()[source]

Get the configuration of a listener module.

Returns

configuration of listener module

Return type

dict

classmethod get_configuration_keys()[source]

List of known configuration keys. Subclasses can expand this to support additional attributes.

Returns

list of known configuration keys

Return type

list(str)

get_name()[source]
Returns

name of module

Return type

str

get_description()[source]
Returns

description string of module

Return type

str

get_ldap_filter()[source]
Returns

LDAP filter of module

Return type

str

get_attributes()[source]
Returns

attributes of matching LDAP objects the module will be notified about if changed

Return type

list(str)

get_priority()[source]
Returns

priority of the handler. Defines the order in which this module is executed inside the listener

Return type

float

get_listener_module_instance(*args, **kwargs)[source]

Get an instance of the listener module.

Parameters
Returns

instance of ListenerModuleHandler

Return type

ListenerModuleHandler

get_listener_module_class()[source]

Get the class to instantiate for a listener module.

Returns

subclass of univention.listener.ListenerModuleHandler

Return type

ListenerModuleHandler

get_active()[source]

If this listener module should run. Determined by the value of listener/module/<name>/deactivate.

Returns

whether the listener module should be activated

Return type

bool

class univention.listener.ListenerModuleHandler(*args, **kwargs)[source]

Bases: object

Listener module base class.

Subclass this to implement the logic of your listener module and have ListenerModuleConfiguration.get_listener_module_class() return the name of your subclass.

This class is not intended to be used directly. It should only be instantiated by ListenerModuleConfiguration.get_listener_module_instance().

When subclassing, in __init__() first call must be:

super(.., self).__init__(*args, **kwargs)

self.config will be set by the metaclass.

config = None
ucr = <univention.config_registry.backend.ConfigRegistry object>
class Configuration(*args, **kwargs)[source]

Bases: univention.listener.handler_configuration.ListenerModuleConfiguration

Overwrite this with your own class of the same name. It can be an any Python class with just the require attributes (name, description, ldap_filter) or a subclass of ListenerModuleConfiguration.

create(dn, new)[source]

Called when a new object was created.

Parameters
  • dn (str) – current objects DN

  • new (dict) – new LDAP objects attributes

modify(dn, old, new, old_dn)[source]

Called when an existing object was modified or moved.

A move can be be detected by looking at old_dn. Attributes can be modified during a move.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • old_dn (str or None) – previous DN if object was moved/renamed, None otherwise

remove(dn, old)[source]

Called when an object was deleted.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

initialize()[source]

Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.

clean()[source]

Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.

pre_run()[source]

Called before create/modify/remove if either the Univention Directory Listener has been restarted or when post_run() has run before.

Use for example to open an LDAP connection.

post_run()[source]

Called only, when no change happens for 15 seconds - for any listener module.

Use for example to close an LDAP connection.

static as_root()[source]

Contextmanager to temporarily change the effective UID of the current process to 0:

with self.as_root():

do something

Use listener.setuid() for any other user than root. But be aware that listener.unsetuid() will not be possible afterwards, as that requires root privileges.

classmethod diff(old, new, keys=None, ignore_metadata=True)[source]

Find differences in old and new. Returns dict with keys pointing to old and new values.

Parameters
  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • keys (list) – consider only those keys in comparison

  • ignore_metadata (bool) – ignore changed metadata attributes (if keys is not set)

Returns

key -> (old[key], new[key]) mapping

Return type

dict

error_handler(dn, old, new, command, exc_type, exc_value, exc_traceback)[source]

Will be called for unhandled exceptions in create/modify/remove.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • command (str) – LDAP modification type

  • exc_type (type) – exception class

  • exc_value (BaseException) – exception object

  • exc_traceback (traceback) – traceback object

property lo

LDAP connection object.

Returns

uldap.access object

Return type

univention.admin.uldap.access

property po

Get a LDAP position object for the base DN (ldap/base).

Returns

uldap.position object

Return type

univention.admin.uldap.position

Submodules

univention.listener.api_adapter module

class univention.listener.api_adapter.ListenerModuleAdapter(module_configuration, *args, **kwargs)[source]

Bases: object

Adapter to convert the univention.listener.listener_module interface to the existing listener module interface.

Use in a classic listener module like this:

globals().update(ListenerModuleAdapter(MyListenerModuleConfiguration()).get_globals())

Parameters

module_configuration (ListenerModuleConfiguration) – configuration object

get_globals()[source]

Returns the variables to be written to the module namespace, that make up the legacy listener module interface.

Returns

a mapping with keys: name, description, filter_s, attributes, modrdn, handler, initialize, clean, prerun, postrun, setdata, ..

Return type

dict

univention.listener.exceptions module

exception univention.listener.exceptions.ListenerModuleError[source]

Bases: Exception

exception univention.listener.exceptions.ListenerModuleConfigurationError[source]

Bases: univention.listener.exceptions.ListenerModuleError

exception univention.listener.exceptions.ListenerModuleRuntimeError[source]

Bases: univention.listener.exceptions.ListenerModuleError

univention.listener.handler module

class univention.listener.handler.HandlerMetaClass(clsname, bases, attrs)[source]

Bases: type

Read handler configuration and invoke adapter.

class univention.listener.handler.ListenerModuleHandler(*args, **kwargs)[source]

Bases: object

Listener module base class.

Subclass this to implement the logic of your listener module and have ListenerModuleConfiguration.get_listener_module_class() return the name of your subclass.

This class is not intended to be used directly. It should only be instantiated by ListenerModuleConfiguration.get_listener_module_instance().

When subclassing, in __init__() first call must be:

super(.., self).__init__(*args, **kwargs)

self.config will be set by the metaclass.

config = None
ucr = <univention.config_registry.backend.ConfigRegistry object>
class Configuration(*args, **kwargs)[source]

Bases: univention.listener.handler_configuration.ListenerModuleConfiguration

Overwrite this with your own class of the same name. It can be an any Python class with just the require attributes (name, description, ldap_filter) or a subclass of ListenerModuleConfiguration.

create(dn, new)[source]

Called when a new object was created.

Parameters
  • dn (str) – current objects DN

  • new (dict) – new LDAP objects attributes

modify(dn, old, new, old_dn)[source]

Called when an existing object was modified or moved.

A move can be be detected by looking at old_dn. Attributes can be modified during a move.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • old_dn (str or None) – previous DN if object was moved/renamed, None otherwise

remove(dn, old)[source]

Called when an object was deleted.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

initialize()[source]

Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.

clean()[source]

Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.

pre_run()[source]

Called before create/modify/remove if either the Univention Directory Listener has been restarted or when post_run() has run before.

Use for example to open an LDAP connection.

post_run()[source]

Called only, when no change happens for 15 seconds - for any listener module.

Use for example to close an LDAP connection.

static as_root()[source]

Contextmanager to temporarily change the effective UID of the current process to 0:

with self.as_root():

do something

Use listener.setuid() for any other user than root. But be aware that listener.unsetuid() will not be possible afterwards, as that requires root privileges.

classmethod diff(old, new, keys=None, ignore_metadata=True)[source]

Find differences in old and new. Returns dict with keys pointing to old and new values.

Parameters
  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • keys (list) – consider only those keys in comparison

  • ignore_metadata (bool) – ignore changed metadata attributes (if keys is not set)

Returns

key -> (old[key], new[key]) mapping

Return type

dict

error_handler(dn, old, new, command, exc_type, exc_value, exc_traceback)[source]

Will be called for unhandled exceptions in create/modify/remove.

Parameters
  • dn (str) – current objects DN

  • old (dict) – previous LDAP objects attributes

  • new (dict) – new LDAP objects attributes

  • command (str) – LDAP modification type

  • exc_type (type) – exception class

  • exc_value (BaseException) – exception object

  • exc_traceback (traceback) – traceback object

property lo

LDAP connection object.

Returns

uldap.access object

Return type

univention.admin.uldap.access

property po

Get a LDAP position object for the base DN (ldap/base).

Returns

uldap.position object

Return type

univention.admin.uldap.position

univention.listener.handler_configuration module

class univention.listener.handler_configuration.ListenerModuleConfiguration(*args, **kwargs)[source]

Bases: object

Interface class for accessing the configuration and code of a listener module.

Subclass this and set the class attributes or pass them through __init__. If more logic is needed, overwrite the corresponding get_<attribute> method. Setting name, description, ldap_filter and listener_module_class is mandatory.

To extend the configuration, add key names in get_configuration_keys() and create a get_<attribute> method.

The listener server will use an object of your subclass to access your listener module through:

  1. get_configuration()

  2. get_listener_module_instance()

name = ''
description = ''
ldap_filter = ''
listener_module_class = None
attributes = []
get_configuration()[source]

Get the configuration of a listener module.

Returns

configuration of listener module

Return type

dict

classmethod get_configuration_keys()[source]

List of known configuration keys. Subclasses can expand this to support additional attributes.

Returns

list of known configuration keys

Return type

list(str)

get_name()[source]
Returns

name of module

Return type

str

get_description()[source]
Returns

description string of module

Return type

str

get_ldap_filter()[source]
Returns

LDAP filter of module

Return type

str

get_attributes()[source]
Returns

attributes of matching LDAP objects the module will be notified about if changed

Return type

list(str)

get_priority()[source]
Returns

priority of the handler. Defines the order in which this module is executed inside the listener

Return type

float

get_listener_module_instance(*args, **kwargs)[source]

Get an instance of the listener module.

Parameters
  • args (tuple) – passed to __init__ of ListenerModuleHandler

  • kwargs (dict) – : passed to __init__ of ListenerModuleHandler

Returns

instance of ListenerModuleHandler

Return type

ListenerModuleHandler

get_listener_module_class()[source]

Get the class to instantiate for a listener module.

Returns

subclass of univention.listener.ListenerModuleHandler

Return type

ListenerModuleHandler

get_active()[source]

If this listener module should run. Determined by the value of listener/module/<name>/deactivate.

Returns

whether the listener module should be activated

Return type

bool

univention.listener.handler_logging module

Get a Python logging object below a listener module root logger. The new logging object can log to a stream or a file. The listener module root logger will log messages of all of its children additionally to the common listener.log.

class univention.listener.handler_logging.UniFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)[source]

Bases: logging.handlers.TimedRotatingFileHandler

Used by listener modules using the univention.listener API to write log files below /var/log/univention/listener_log/. Configuration can be done through the handler_kwargs argument of get_listener_logger().

Use the specified filename for streamed logging

class univention.listener.handler_logging.ModuleHandler(level=0, udebug_facility=8)[source]

Bases: logging.Handler

Used by listener modules using the univention.listener API to write log messages through univention.debug to /var/log/univention/listener.log

Initializes the instance - basically setting the formatter to None and the filter list to empty.

LOGGING_TO_UDEBUG = {'CRITICAL': 0, 'DEBUG': 3, 'ERROR': 0, 'INFO': 2, 'NOTSET': 3, 'WARN': 1, 'WARNING': 1}
emit(record)[source]

Do whatever it takes to actually log the specified logging record.

This version is intended to be implemented by subclasses and so raises a NotImplementedError.

univention.listener.handler_logging.get_logger(name, path=None)[source]

Get a logging instance. Caching wrapper for get_listener_logger().

Parameters
  • name (str) – name of the logger instance will be <root loggers name>.name

  • path (str) – path to log file to create. If unset will be /var/log/univention/listener_modules/<name>.log.

Returns

a Python logging object

Return type

logging.Logger

univention.listener.handler_logging.calculate_loglevel(name)[source]

Returns the higher of listener/debug/level and listener/module/<name>/debug/level which is the lower log level.

Parameters

name (str) – name of logger instance

Returns

log level

Return type

int

univention.listener.handler_logging.get_listener_logger(name, filename, level=None, handler_kwargs=None, formatter_kwargs=None)[source]

Get a logger object below the listener module root logger. The logger will additionally log to the common listener.log.

  • The logger will use UniFileHandler(TimedRotatingFileHandler) for files if not configured differently through handler_kwargs[cls].

  • A call with the same name will return the same logging object.

  • There is only one handler per name-target combination.

  • If name and target are the same, and only the log level changes, it will return the logging object with the same handlers and change both the log level of the respective handler and of the logger object to be the lowest of the previous and the new level.

  • The loglevel will be the lowest one of INFO and the UCRVs listener/debug/level and listener/module/<name>/debug/level.

  • Complete output customization is possible, setting kwargs for the constructors of the handler and formatter.

  • Using custom handler and formatter classes is possible by configuring the cls key of handler_kwargs and formatter_kwargs.

Parameters
  • name (str) – name of the logger instance will be <root loggers name>.name

  • level (str) – loglevel (DEBUG, INFO etc) or if not set it will be chosen automatically (see above)

  • target (str) – (file path)

  • handler_kwargs (dict) – will be passed to the handlers constructor. It cannot be used to modify a handler, as it is only used at creation time. If it has a key cls it will be used as handler instead of UniFileHandler or UniStreamHandler. It should be a subclass of one of those!

  • formatter_kwargs (dict) – will be passed to the formatters constructor, if it has a key cls it will be used to create a formatter instead of :py:class`logging.Formatter`.

Returns

a Python logging object

Return type

logging.Logger

univention.listener.handler_logging.info_to_syslog(msg)[source]