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:
a subclass of
ListenerModuleHandlerwith 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: ListenerModuleConfiguration, *args: Any, **kwargs: Any)[source]#
Bases:
objectAdapter to convert the
univention.listener.listener_module interfaceto 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
- class univention.listener.ListenerModuleConfiguration(*args: Any, **kwargs: Any)[source]#
Bases:
objectInterface 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
get_listener_module_instance().- description = ''#
- get_active() bool[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:
- classmethod get_configuration_keys() list[str][source]#
List of known configuration keys. Subclasses can expand this to support additional attributes.
- get_listener_module_class() type[ListenerModuleHandler][source]#
Get the class to instantiate for a listener module.
- Returns:
subclass of
univention.listener.ListenerModuleHandler- Return type:
- get_listener_module_instance(*args: Any, **kwargs: Any) ListenerModuleHandler[source]#
Get an instance of the listener module.
- Parameters:
args (tuple) – passed to __init__ of
ListenerModuleHandlerkwargs (dict) – : passed to __init__ of
ListenerModuleHandler
- Returns:
instance of
ListenerModuleHandler- Return type:
- get_priority() float[source]#
- Returns:
priority of the handler. Defines the order in which this module is executed inside the listener
- Return type:
- ldap_filter = ''#
- listener_module_class: type[ListenerModuleHandler] = None#
- name = ''#
- exception univention.listener.ListenerModuleConfigurationError[source]#
Bases:
ListenerModuleError
- class univention.listener.ListenerModuleHandler(*args: str, **kwargs: str)[source]#
Bases:
objectListener 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.
- class Configuration(*args: Any, **kwargs: Any)[source]#
Bases:
ListenerModuleConfigurationOverwrite this with your own class of the same name. It can be any Python class with just the required attributes (description, ldap_filter) or a subclass of
ListenerModuleConfiguration.
- static as_root() Iterator[None][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 thatlistener.unsetuid()will not be possible afterwards, as that requires root privileges.
- clean() None[source]#
Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.
- config: ListenerModuleConfiguration | None = None#
- create(dn: str, new: Mapping[str, Sequence[bytes]]) None[source]#
Called when a new object was created.
- classmethod diff(old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], keys: Iterable[str] | None = None, ignore_metadata: bool = True) dict[str, tuple[Sequence[bytes] | None, Sequence[bytes] | None]][source]#
Find differences in old and new. Returns dict with keys pointing to old and new values.
- error_handler(dn: str, old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], command: str, exc_type: type[BaseException] | None, exc_value: BaseException | None, exc_traceback: TracebackType | None) None[source]#
Will be called for unhandled exceptions in create/modify/remove.
- initialize() None[source]#
Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.
- modify(dn: str, old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], old_dn: str | None) None[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.
- property po: position#
Get a LDAP position object for the base DN (ldap/base).
- Returns:
uldap.position object
- Return type:
- post_run() None[source]#
Called only, when no change happens for 15 seconds - for any listener module.
Use for example to close an LDAP connection.
- pre_run() None[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.
- remove(dn: str, old: Mapping[str, Sequence[bytes]]) None[source]#
Called when an object was deleted.
- ucr = <univention.config_registry.backend.ConfigRegistry object>#
- exception univention.listener.ListenerModuleRuntimeError[source]#
Bases:
ListenerModuleError
Submodules#
univention.listener.api_adapter module#
- class univention.listener.api_adapter.ListenerModuleAdapter(module_configuration: ListenerModuleConfiguration, *args: Any, **kwargs: Any)[source]#
Bases:
objectAdapter to convert the
univention.listener.listener_module interfaceto 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
univention.listener.exceptions module#
- exception univention.listener.exceptions.ListenerModuleConfigurationError[source]#
Bases:
ListenerModuleError
- exception univention.listener.exceptions.ListenerModuleRuntimeError[source]#
Bases:
ListenerModuleError
univention.listener.handler module#
- class univention.listener.handler.HandlerMetaClass(clsname: str, bases: tuple[type, ...], attrs: dict[str, Any])[source]#
Bases:
typeRead handler configuration, invoke adapter and set global variables in module to fulfill original API.
- class univention.listener.handler.ListenerModuleHandler(*args: str, **kwargs: str)[source]#
Bases:
objectListener 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: ListenerModuleConfiguration | None = None#
- ucr = <univention.config_registry.backend.ConfigRegistry object>#
- class Configuration(*args: Any, **kwargs: Any)[source]#
Bases:
ListenerModuleConfigurationOverwrite this with your own class of the same name. It can be any Python class with just the required attributes (description, ldap_filter) or a subclass of
ListenerModuleConfiguration.
- create(dn: str, new: Mapping[str, Sequence[bytes]]) None[source]#
Called when a new object was created.
- modify(dn: str, old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], old_dn: str | None) None[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.
- remove(dn: str, old: Mapping[str, Sequence[bytes]]) None[source]#
Called when an object was deleted.
- initialize() None[source]#
Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.
- clean() None[source]#
Called once when the Univention Directory Listener loads the module for the first time or when a resync it triggered.
- pre_run() None[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() None[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() Iterator[None][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 thatlistener.unsetuid()will not be possible afterwards, as that requires root privileges.
- classmethod diff(old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], keys: Iterable[str] | None = None, ignore_metadata: bool = True) dict[str, tuple[Sequence[bytes] | None, Sequence[bytes] | None]][source]#
Find differences in old and new. Returns dict with keys pointing to old and new values.
- error_handler(dn: str, old: Mapping[str, Sequence[bytes]], new: Mapping[str, Sequence[bytes]], command: str, exc_type: type[BaseException] | None, exc_value: BaseException | None, exc_traceback: TracebackType | None) None[source]#
Will be called for unhandled exceptions in create/modify/remove.
univention.listener.handler_configuration module#
- class univention.listener.handler_configuration.ListenerModuleConfiguration(*args: Any, **kwargs: Any)[source]#
Bases:
objectInterface 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
get_listener_module_instance().- name = ''#
- description = ''#
- ldap_filter = ''#
- listener_module_class: type[ListenerModuleHandler] = None#
- classmethod get_configuration_keys() list[str][source]#
List of known configuration keys. Subclasses can expand this to support additional attributes.
- get_priority() float[source]#
- Returns:
priority of the handler. Defines the order in which this module is executed inside the listener
- Return type:
- get_listener_module_instance(*args: Any, **kwargs: Any) ListenerModuleHandler[source]#
Get an instance of the listener module.
- Parameters:
- Returns:
instance of
ListenerModuleHandler- Return type:
- get_listener_module_class() type[ListenerModuleHandler][source]#
Get the class to instantiate for a listener module.
- Returns:
subclass of
univention.listener.ListenerModuleHandler- Return type:
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, mode='a', encoding=None, delay=False, errors=None)[source]#
Bases:
WatchedFileHandlerUsed by listener modules using the
univention.listenerAPI to write log files below/var/log/univention/listener_log/. Configuration can be done through the handler_kwargs argument ofget_listener_logger().Open the specified file and use it as the stream for logging.
- class univention.listener.handler_logging.ModuleHandler(level: int = 0, udebug_facility: int = 8)[source]#
Bases:
HandlerUsed by listener modules using the
univention.listenerAPI to write log messages throughunivention.debugto/var/log/univention/listener.logInitializes 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}#
- univention.listener.handler_logging.get_logger(name: str, path: str | None = None) Logger[source]#
Get a logging instance. Caching wrapper for
get_listener_logger().- Parameters:
- Returns:
a Python logging object
- Return type:
- univention.listener.handler_logging.calculate_loglevel(name: str) str[source]#
Returns the higher of listener/debug/level and listener/module/<name>/debug/level which is the lower log level.
- univention.listener.handler_logging.get_listener_logger(name: str, filename: str, level: str | None = None, handler_kwargs: dict[str, Any] | None = None, formatter_kwargs: dict[str, Any] | None = None) Logger[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
UniFileHandlerorUniStreamHandler. 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: