ucsschool.importer.utils package

Submodules

ucsschool.importer.utils.config_pyhook module

Base class for configuration hooks.

class ucsschool.importer.utils.config_pyhook.ConfigPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.importer.utils.import_pyhook.ImportPyHook

Hook to manipulate the configuration after reading the configuration files and applying the command line arguments.

The base class’ __init__() provides the following attributes:

  • self.dry_run # whether hook is executed during a dry-run (1)

  • self.lo # LDAP connection object (2)

  • self.logger # Python logging instance

If multiple hook classes are found, hook functions with higher priority numbers run before those with lower priorities. None disables a function (no need to remove it / comment it out).

(1) Hooks are only executed during dry-runs, if the class attribute supports_dry_run is set to True (default is False). Hooks with supports_dry_run == True must not modify LDAP objects. Therefore the LDAP connection object self.lo will be a read-only connection during a dry-run. (2) Read-write cn=admin connection in a real run, read-only cn=admin connection during a dry-run.

Parameters
priority = {'post_config_files_read': None}
post_config_files_read(config, used_conffiles, used_kwargs)[source]

Hook that runs after reading the configuration files used_conffiles and applying the command line arguments used_kwargs. Resulting configuration is config, which can be manipulated and must be returned.

Parameters
  • config (ReadOnlyDict) – configuration that will be used by the import if not modified here, not yet read-only.

  • used_conffiles (list) – configuration files read and applied

  • used_kwargs (dict) – command line options read and applied

Returns

config dict

Return type

ReadOnlyDict

ucsschool.importer.utils.configuration_checks module

Configuration checks.

After the configuration has been read, checks run.

To add your own checks, subclass ConfigurationChecks, save the module in /usr/share/ucs-school-import/checks and add its module name (without .py) to the list in the configuration key configuration_checks.

Remove defaults from your configuration_checks only if you know what you are doing.


Example: Save the following to /usr/share/ucs-school-import/checks/mychecks.py:

>>> from ucsschool.importer.exceptions import InitialisationError
>>> from ucsschool.importer.utils.configuration_checks import ConfigurationChecks
>>>
>>> class MyConfigurationChecks(ConfigurationChecks):
>>>     def test_nonzero_deactivation_grace(self):
>>>             if self.config.get('deletion_grace_period', {}).get('deactivation', 0) == 0:
>>>                     raise InitialisationError('deletion_grace_period:deactivation must not be zero.')

Then add a configuration entry to /var/lib/ucs-school-import/configs/user_import.json:

{
[..]
    "configuration_checks": ["defaults", "mychecks"]
}
class ucsschool.importer.utils.configuration_checks.ConfigurationChecks(config)[source]

Bases: object

Base class for configuration checks.

Provides the configuration singleton in self.config, a read-only LDAP connection object in self.lo and a logging instance in self.logger.

All methods with names starting with test_ will be executed in alphanumerical order. Failing tests should raise a py:exception:ucsschool.importer.exceptions.InitialisationError exception.

ucsschool.importer.utils.format_pyhook module

Base class for all Python based format hooks.

class ucsschool.importer.utils.format_pyhook.FormatPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.importer.utils.import_pyhook.ImportPyHook

Format hook base class

See ImportPyHook base class for documentation regarding the class’ attributes.

Parameters
priority = {'patch_fields_staff': None, 'patch_fields_student': None, 'patch_fields_teacher': None, 'patch_fields_teacher_and_staff': None}
properties = ()
patch_fields_staff(property_name, fields)[source]

Run code before formatting an property using a schema in format_from_scheme().

Parameters
  • property_name (str) – Name of property_name that will be formatted

  • fields (dict) – dictionary with the users attributes and udm_properties

Returns

fields dictionary that be used by format_from_scheme()

Return type

dict

patch_fields_student(property_name, fields)[source]

Run code before formatting an property using a schema in format_from_scheme().

Parameters
  • property_name (str) – Name of property_name that will be formatted

  • fields (dict) – dictionary with the users attributes and udm_properties

Returns

fields dictionary that be used by format_from_scheme()

Return type

dict

patch_fields_teacher(property_name, fields)[source]

Run code before formatting an property using a schema in format_from_scheme().

Parameters
  • property_name (str) – Name of property_name that will be formatted

  • fields (dict) – dictionary with the users attributes and udm_properties

Returns

fields dictionary that be used by format_from_scheme()

Return type

dict

patch_fields_teacher_and_staff(property_name, fields)[source]

Run code before formatting a property using a schema in format_from_scheme().

Parameters
  • property_name (str) – Name of property_name that will be formatted

  • fields (dict) – dictionary with the users attributes and udm_properties

Returns

fields dictionary that be used by format_from_scheme()

Return type

dict

ucsschool.importer.utils.import_pyhook module

Base class for all Python based import hooks.

class ucsschool.importer.utils.import_pyhook.ImportPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.lib.pyhooks.pyhook.PyHook

Base class for Python based import hooks.

  • self.dry_run # whether hook is executed during a dry-run (1)

  • self.lo # LDAP connection object (2)

  • self.logger # Python logging instance

If multiple hook classes are found, hook functions with higher priority numbers run before those with lower priorities. None disables a function (no need to remove it / comment it out).

(1) Hooks are only executed during dry-runs, if the class attribute supports_dry_run is set to True (default is False). Hooks with supports_dry_run == True must not modify LDAP objects. Therefore the LDAP connection object self.lo will be a read-only connection during a dry-run. (2) Read-write cn=admin connection in a real run, read-only cn=admin connection during a dry-run.

Parameters
supports_dry_run = False
dry_run

Whether this is a dry-run

lo

LDAP connection object

logger

Python logging instance

class ucsschool.importer.utils.import_pyhook.ImportPyHookLoader(pyhooks_base_path)[source]

Bases: object

Load and initialize hooks.

If hooks should be instantiated with arguments, use init_hook() before call_hook().

init_hook(hook_cls, filter_func=None, *args, **kwargs)[source]

Load and initialize hook class hook_cls.

Parameters
  • hook_cls (ucsschool.importer.utils.import_pyhook.ImportPyHook or str) – class object - load and run hooks that are a subclass of this

  • filter_func (callable or None) – function to filter out undesired hook classes (takes a class and returns a bool), passed to PyHooksLoader

  • args (tuple) – arguments to pass to __init__ of hooks

  • kwargs (dict) – arguments to pass to __init__ of hooks

Returns

mapping from method names to list of methods of initialized hook objects, sorted by method priority

Return type

dict[str, list[callable]]

call_hooks(hook_cls, func_name, *args, **kwargs)[source]

Run hooks with name func_name from class hook_cls.

Parameters
  • hook_cls – class object - load and run hooks that are a subclass of this

  • func_name (str) – name of method to run in each hook

  • args – arguments to pass to hook function

  • kwargs – arguments to pass to hook function

Returns

list of when all executed hooks returned

Return type

list

ucsschool.importer.utils.import_pyhook.get_import_pyhooks(hook_cls, filter_func=None, *args, **kwargs)[source]

Retrieve (and initialize subclasses of hook_cls, if not yet done) pyhooks of type hook_cls. Results are cached.

If no argument must be passed to the hook_cls __init__() or PyHooksLoader, then it is not necessary to call this function, just use run_import_pyhooks() directly.

Convenience function for easy usage of PyHooksLoader.

Parameters
  • hook_cls (ucsschool.importer.utils.import_pyhook.ImportPyHook or str) – class object or fully dotted Python path to a class definition - load and run hooks that are a subclass of this

  • filter_func (callable or None) – function to filter out undesired hook classes (takes a class and returns a bool), passed to PyHooksLoader

  • args – arguments to pass to __init__ of hooks

  • kwargs – arguments to pass to __init__ of hooks

Returns

mapping from method names to list of methods of initialized hook objects, sorted by method priority

Return type

dict[str, list[callable]]

ucsschool.importer.utils.import_pyhook.run_import_pyhooks(hook_cls, func_name, *args, **kwargs)[source]

Execute method func_name of subclasses of hook_cls, load and initialize if required.

Convenience function for easy usage of PyHooksLoader.

Parameters
  • hook_cls (ucsschool.importer.utils.import_pyhook.ImportPyHook or str) – class object or fully dotted Python path to a class definition - load and run hooks that are a subclass of this

  • func_name (str) – name of method to run in each hook

  • args – arguments to pass to hook function func_name

  • kwargs – arguments to pass to hook function func_name

Returns

list of when all executed hooks returned

Return type

list

ucsschool.importer.utils.ldap_connection module

Create LDAP connections for import.

ucsschool.importer.utils.ldap_connection.get_admin_connection()[source]

Read-write cn=admin connection.

Return type

tuple(univention.admin.uldap.access, univention.admin.uldap.position)

ucsschool.importer.utils.ldap_connection.get_machine_connection()[source]

Read-write machine connection.

Return type

tuple(univention.admin.uldap.access, univention.admin.uldap.position)

ucsschool.importer.utils.ldap_connection.get_unprivileged_connection()[source]

Unprivileged read-write connection.

Return type

tuple(univention.admin.uldap.access, univention.admin.uldap.position)

class ucsschool.importer.utils.ldap_connection.ReadOnlyAccess(*args, **kwargs)[source]

Bases: univention.admin.uldap.access

LDAP access class that prevents LDAP write access.

Must be a descendant of univention.admin.uldap.access, or UDM will raise a TypeError.

Parameters
  • host (str) – The hostname of the LDAP server.

  • port (int) – The TCP port number of the LDAP server.

  • base (str) – The base distinguished name.

  • binddn (str) – The distinguished name of the account.

  • bindpw (str) – The user password for simple authentication.

  • start_tls (int) – Negotiate TLS with server. If 2 is given, the command will require the operation to be successful.

  • lo (univention.uldap.access) – LDAP connection.

Param:bool follow_referral

Follow LDAP referrals.

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

Add LDAP entry at distinguished name and attributes in add_list=(attribute-name, old-values. new-values) or (attribute-name, new-values).

Parameters
  • dn (str) – The distinguished name of the object to add.

  • al – The add-list of 2-tuples (attribute-name, new-values).

  • exceptions (bool) – Raise the low level exception instead of the wrapping UDM exceptions.

  • serverctrls (list[ldap.controls.LDAPControl]) – a list of ldap.controls.LDAPControl instances sent to the server along with the LDAP request

  • response (dict) – An optional dictionary to receive the server controls of the result.

Raises
modify(*args, **kwargs)[source]

Modify LDAP entry DN with attributes in changes=(attribute-name, old-values, new-values).

Parameters
  • dn (str) – The distinguished name of the object to modify.

  • changes – The modify-list of 3-tuples (attribute-name, old-values, new-values).

  • exceptions (bool) – Raise the low level exception instead of the wrapping UDM exceptions.

  • ignore_license (bool) – Ignore license check if True.

  • serverctrls (list[ldap.controls.LDAPControl]) – a list of ldap.controls.LDAPControl instances sent to the server along with the LDAP request

  • response (dict) – An optional dictionary to receive the server controls of the result.

Returns

The distinguished name.

Return type

str

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

Rename a LDAP object.

Parameters
  • dn (str) – The old distinguished name of the object to rename.

  • newdn (str) – The new distinguished name of the object to rename.

  • move_childs (int) – Also rename the sub children. Must be 0 always as 1 is not implemented.

  • ignore_license (bool) – Ignore license check if True.

  • serverctrls (list[ldap.controls.LDAPControl]) – a list of ldap.controls.LDAPControl instances sent to the server along with the LDAP request

  • response (dict) – An optional dictionary to receive the server controls of the result.

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

Delete a LDAP object.

Parameters
  • dn (str) – The distinguished name of the object to remove.

  • exceptions (bool) – Raise the low level exception instead of the wrapping UDM exceptions.

Raises
ucsschool.importer.utils.ldap_connection.get_readonly_connection()[source]

Read-only cn=admin connection.

Return type

tuple(univention.admin.uldap.access, univention.admin.uldap.position)

ucsschool.importer.utils.logging module

ucsschool.importer.utils.post_read_pyhook module

Base class for all Python based Post-Read-Pyhooks.

class ucsschool.importer.utils.post_read_pyhook.PostReadPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.importer.utils.import_pyhook.ImportPyHook

Hook that is called directly after data has been read from CSV/…

The base class’ __init__() provides the following attributes:

  • self.dry_run # whether hook is executed during a dry-run (1)

  • self.lo # LDAP connection object (2)

  • self.logger # Python logging instance

If multiple hook classes are found, hook functions with higher priority numbers run before those with lower priorities. None disables a function (no need to remove it / comment it out).

(1) Hooks are only executed during dry-runs, if the class attribute supports_dry_run is set to True (default is False). Hooks with supports_dry_run == True must not modify LDAP objects. Therefore the LDAP connection object self.lo will be a read-only connection during a dry-run. (2) Read-write cn=admin connection in a real run, read-only cn=admin connection during a dry-run.

Parameters
priority = {'all_entries_read': None, 'entry_read': None}
entry_read(entry_count, input_data, input_dict)[source]

Run code after an entry has been read and saved in input_data and input_dict. This hook may alter input_data and input_dict to modify the input data. This function may raise the exception UcsSchoolImportSkipImportRecord to ignore the read import data.

Parameters
  • entry_count (int) – index of the data entry (e.g. line of the CSV file)

  • input_data (list[str]) – input data as raw as possible (e.g. raw CSV columns). The input_data may be changed.

  • input_dict (dict[str, str]) – input data mapped to column names. The input_dict may be changed.

Returns

None

Raises

UcsSchoolImportSkipImportRecord – if an entry (e.g. a CSV line) should be skipped

all_entries_read(imported_users, errors)[source]

Run code after all entries have been read. ImportUser objects for all lines are passed to the hook. Also errors are passed. Please note that the “entry_read” hook method may skip one or several input records, so they may be missing in imported_users. errors contains a list of catched errors/exceptions.

Parameters
  • imported_users (list[ImportUser]) – list of ImportUser objects created from the input records

  • errors (list[Exception]) – list of exceptions that are caught during processing the input records

Returns

None

ucsschool.importer.utils.pre_read_pyhook module

ucsschool.importer.utils.result_pyhook module

Base class for all Python based Result-Pyhooks.

class ucsschool.importer.utils.result_pyhook.ResultPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.importer.utils.import_pyhook.ImportPyHook

Hook that is called after import has finished.

The base class’ __init__() provides the following attributes:

  • self.dry_run # whether hook is executed during a dry-run (1)

  • self.lo # LDAP connection object (2)

  • self.logger # Python logging instance

If multiple hook classes are found, hook functions with higher priority numbers run before those with lower priorities. None disables a function (no need to remove it / comment it out).

(1) Hooks are only executed during dry-runs, if the class attribute supports_dry_run is set to True (default is False). Hooks with supports_dry_run == True must not modify LDAP objects. Therefore the LDAP connection object self.lo will be a read-only connection during a dry-run. (2) Read-write cn=admin connection in a real run, read-only cn=admin connection during a dry-run.

Parameters
priority = {'user_result': None}
user_result(user_import_data)[source]

Run code after user import has finished. Relevant data from the UserImport class is passed to this hook, so result summaries etc are possible.

Parameters

user_import_data (UserImportData) – relevant data from the UserImport class

Returns

None

ucsschool.importer.utils.test_user_creator module

ucsschool.importer.utils.user_pyhook module

Base class for all Python based User hooks.

class ucsschool.importer.utils.user_pyhook.UserPyHook(lo=None, dry_run=None, *args, **kwargs)[source]

Bases: ucsschool.importer.utils.import_pyhook.ImportPyHook

Base class for Python based user import hooks.

An example is provided in /usr/share/doc/ucs-school-import/hook_example.py

The base class’ __init__() provides the following attributes:

  • self.dry_run # whether hook is executed during a dry-run (1)

  • self.lo # LDAP connection object (2)

  • self.logger # Python logging instance

If multiple hook classes are found, hook functions with higher priority numbers run before those with lower priorities. None disables a function (no need to remove it / comment it out).

(1) Hooks are only executed during dry-runs, if the class attribute supports_dry_run is set to True (default is False). Hooks with supports_dry_run == True must not modify LDAP objects. Therefore the LDAP connection object self.lo will be a read-only connection during a dry-run. (2) Read-write cn=admin connection in a real run, read-only cn=admin connection during a dry-run.

Parameters
priority = {'post_create': None, 'post_modify': None, 'post_move': None, 'post_remove': None, 'pre_create': None, 'pre_modify': None, 'pre_move': None, 'pre_remove': None}
pre_create(user)[source]

Run code before creating a user.

  • The user does not exist in LDAP, yet.

  • user.dn is the future DN of the user, if username and school does not change.

  • user.input_data contains the (csv) input data, if the user was create during an import job

  • set priority[“pre_create”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

post_create(user)[source]

Run code after creating a user.

  • The hook is only executed if adding the user succeeded.

  • user will be an ImportUser, loaded from LDAP.

  • Do not run user.modify(), it will create a recursion. Please use

    user.modify_without_hooks().

  • set priority[“post_create”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

pre_modify(user)[source]

Run code before modifying a user.

  • user will be a ImportUser, loaded from LDAP.

  • set priority[“pre_modify”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

post_modify(user)[source]

Run code after modifying a user.

  • The hook is only executed if modifying the user succeeded.

  • user will be an ImportUser, loaded from LDAP.

  • Do not run user.modify(), it will create a recursion. Please use

    user.modify_without_hooks().

  • If running in an import job, the user may not have been removed, but merely deactivated. If

    user.udm_properties[“ucsschoolPurgeTimestamp”] is set, the user is marked for removal.

  • set priority[“post_modify”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

pre_move(user)[source]

Run code before changing a users primary school (position).

  • user will be an ImportUser, loaded from LDAP.

  • set priority[“pre_move”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

post_move(user)[source]

Run code after changing a users primary school (position).

  • The hook is only executed if moving the user succeeded.

  • user will be an ImportUser, loaded from LDAP.

  • Do not run user.modify(), it will create a recursion. Please use

    user.modify_without_hooks().

  • set priority[“post_move”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

pre_remove(user)[source]

Run code before deleting a user.

  • user will be an ImportUser, loaded from LDAP.

  • set priority[“pre_remove”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

post_remove(user)[source]

Run code after deleting a user.

  • The hook is only executed if the deleting the user succeeded.

  • user will be an ImportUser, loaded from LDAP.

  • The user was removed, do not try to modify() it.

  • set priority[“post_remove”] to an int, to enable this method

Parameters

user (ImportUser) – User (or a subclass of it, eg. ImportUser)

Returns

None

ucsschool.importer.utils.username_handler module

ucsschool.importer.utils.utils module

Diverse helper functions.

ucsschool.importer.utils.utils.get_ldap_mapping_for_udm_property(udm_prop, udm_type)[source]

Get the name of the LDAP attribute, a UDM property is mapped to.

Parameters
  • udm_prop (str) – name of UDM property

  • udm_type (str) – name of UDM module (e.g. ‘users/user’)

Returns

name of LDAP attribute or empty str if no mapping was found

Return type

str

ucsschool.importer.utils.utils.nullcontext()[source]

Context manager that does nothing.