ucsschool.lib.models package

Contents

ucsschool.lib.models package#

Submodules#

ucsschool.lib.models.attributes module#

exception ucsschool.lib.models.attributes.ValidationError[source]#

Bases: Exception

class ucsschool.lib.models.attributes.Attribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: object

syntax = None#
extended = False#
value_type = None#
value_default = None#
map_if_none = False#
udm_name = None#
validate(value: Any) None[source]#
class ucsschool.lib.models.attributes.CommonName(label: str, aka: List[str] | None = None)[source]#

Bases: Attribute

udm_name = 'name'#
syntax = None#
validate(value: str) None[source]#
ucsschool.lib.models.attributes.is_valid_win_directory_name(name: str) bool[source]#

Check that a string is a valid Windows directory name.

Needed to prevent bug when a user with a reserved name tries to log in to a Windows computer.

Parameters:

name – The name to check.

Returns:

True if the name is valid, False otherwise.

class ucsschool.lib.models.attributes.Username(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = 'username'#
syntax#

alias of uid_umlauts

validate(value)[source]#
class ucsschool.lib.models.attributes.DHCPServerName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = 'server'#
class ucsschool.lib.models.attributes.DHCPServiceName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = 'service'#
class ucsschool.lib.models.attributes.GroupName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

syntax#

alias of gid

class ucsschool.lib.models.attributes.SchoolClassName(label: str, aka: List[str] | None = None)[source]#

Bases: GroupName

class ucsschool.lib.models.attributes.ShareName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

syntax#

alias of string_numbers_letters_dots_spaces

class ucsschool.lib.models.attributes.SubnetName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = 'subnet'#
syntax#

alias of reverseLookupSubnet

class ucsschool.lib.models.attributes.DHCPSubnetName(label: str, aka: List[str] | None = None)[source]#

Bases: SubnetName

udm_name = 'subnet'#
syntax#

alias of ipv4Address

class ucsschool.lib.models.attributes.SchoolName(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = 'name'#
validate(value: str) None[source]#
class ucsschool.lib.models.attributes.DCName(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

validate(value: str) None[source]#
class ucsschool.lib.models.attributes.Firstname(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'firstname'#
class ucsschool.lib.models.attributes.Lastname(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'lastname'#
class ucsschool.lib.models.attributes.Birthday(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'birthday'#
syntax#

alias of iso8601Date

map_if_none = True#
class ucsschool.lib.models.attributes.UserExpirationDate(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'userexpiry'#
syntax#

alias of date2

map_if_none = True#
class ucsschool.lib.models.attributes.Email(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'mailPrimaryAddress'#
syntax#

alias of primaryEmailAddressValidDomain

validate(value: str) None[source]#
class ucsschool.lib.models.attributes.Password(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'password'#
class ucsschool.lib.models.attributes.Disabled(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'disabled'#
syntax#

alias of disabled

class ucsschool.lib.models.attributes.SchoolAttribute(label: str, aka: List[str] | None = None)[source]#

Bases: CommonName

udm_name = None#
class ucsschool.lib.models.attributes.SchoolClassesAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = None#
value_type#

alias of dict

value_default#

alias of dict

class ucsschool.lib.models.attributes.SchoolClassAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

class ucsschool.lib.models.attributes.WorkgroupAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

class ucsschool.lib.models.attributes.WorkgroupsAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = None#
value_type#

alias of dict

value_default#

alias of dict

class ucsschool.lib.models.attributes.Description(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'description'#
class ucsschool.lib.models.attributes.DisplayName(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'displayName'#
extended = True#
class ucsschool.lib.models.attributes.EmptyAttributes(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'emptyAttributes'#
class ucsschool.lib.models.attributes.ContainerPath(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

syntax#

alias of boolean

class ucsschool.lib.models.attributes.ShareFileServer(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

syntax#

alias of UDM_Objects

extended = True#
class ucsschool.lib.models.attributes.Groups(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

syntax#

alias of GroupDN

value_type#

alias of list

class ucsschool.lib.models.attributes.Users(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'users'#
syntax#

alias of UserDN

value_type#

alias of list

class ucsschool.lib.models.attributes.IPAddress(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'ip'#
syntax#

alias of ipAddress

value_type#

alias of list

class ucsschool.lib.models.attributes.SubnetMask(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

class ucsschool.lib.models.attributes.DHCPSubnetMask(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'subnetmask'#
syntax#

alias of v4netmask

class ucsschool.lib.models.attributes.DHCPServiceAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

class ucsschool.lib.models.attributes.BroadcastAddress(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'broadcastaddress'#
syntax#

alias of ipv4Address

class ucsschool.lib.models.attributes.NetworkBroadcastAddress(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

syntax#

alias of ipv4Address

class ucsschool.lib.models.attributes.NetworkAttribute(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'network'#
syntax#

alias of ipAddress

class ucsschool.lib.models.attributes.Netmask(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'netmask'#
syntax#

alias of netmask

class ucsschool.lib.models.attributes.MACAddress(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'mac'#
syntax#

alias of MAC_Address

value_type#

alias of list

class ucsschool.lib.models.attributes.InventoryNumber(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

class ucsschool.lib.models.attributes.Hosts(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'hosts'#
value_type#

alias of list

syntax#

alias of UDM_Objects

class ucsschool.lib.models.attributes.Schools(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'school'#
value_type#

alias of list

value_default#

alias of list

syntax#

alias of string

extended = True#
class ucsschool.lib.models.attributes.RecordUID(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'ucsschoolRecordUID'#
syntax#

alias of string

extended = True#
class ucsschool.lib.models.attributes.SourceUID(label: str, aka: List[str] | None = None, udm_name: str | None = None, required: bool | None = False, unlikely_to_change: bool | None = False, internal: bool | None = False, map_to_udm: bool | None = True)[source]#

Bases: Attribute

udm_name = 'ucsschoolSourceUID'#
syntax#

alias of string

extended = True#
class ucsschool.lib.models.attributes.RolesSyntax[source]#

Bases: string

regex: Pattern | None = re.compile('^(?P<role>.+):(?P<context_type>.+):(?P<context>.+)$')#

Regular expression to validate the value.

classmethod parse(text: str) str[source]#

Validate the value by parsing it.

Returns:

the parsed textual value.

Raises:

univention.admin.uexceptions.valueError – if the value is invalid.

class ucsschool.lib.models.attributes.Roles(*args, **kwargs)[source]#

Bases: Attribute

udm_name = 'ucsschoolRole'#
value_type#

alias of list

value_default#

alias of list

syntax#

alias of RolesSyntax

extended = True#

ucsschool.lib.models.base module#

exception ucsschool.lib.models.base.NoObject(dn: str = None, type: Type[UCSSchoolModel] = None, *args: Any)[source]#

Bases: noObject

exception ucsschool.lib.models.base.UnknownModel(dn: str, cls: Type[UCSSchoolModel])[source]#

Bases: NoObject

exception ucsschool.lib.models.base.WrongModel(dn: str, model: Type[UCSSchoolModel], wrong_model: Type[UCSSchoolModel])[source]#

Bases: NoObject

exception ucsschool.lib.models.base.WrongObjectType(dn: str, cls: Type[UCSSchoolModel])[source]#

Bases: NoObject

exception ucsschool.lib.models.base.MultipleObjectsError(objs: Sequence[UCSSchoolModel], *args: Any, **kwargs: Any)[source]#

Bases: Exception

class ucsschool.lib.models.base.UCSSchoolHelperAbstractClass(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: object

Base class of all UCS@school models. Hides UDM.

Attributes used for a class are defined like this:

class MyModel(UCSSchoolHelperAbstractClass):
    my_attribute = Attribute('Label', required=True, udm_name='myAttr')

From there on my_attribute=value may be passed to :py:meth:__init__(), my_model.my_attribute can be accessed and the value will be saved as obj['myAttr'] in UDM when saving this instance. If an attribute of a base class is not wanted, it can be overridden:

class MyModel(UCSSchoolHelperAbstractClass):
    school = None

Meta information about the class are defined like this:

class MyModel(UCSSchoolHelperAbstractClass):
    class Meta:
        udm_module = 'my/model'

The meta information is then accessible in cls._meta.

Important functions:

:py:meth:__init__(**kwargs):

kwargs should be the defined attributes

:py:meth:create(lo)

lo is an LDAP connection, specifically univention.admin.access. creates a new object. Returns False is the object already exists. And True after the creation

:py:meth:modify(lo)

modifies an existing object. Returns False if the object does not exist and True after the modification (regardless whether something actually changed or not)

:py:meth:remove(lo)

deletes the object. Returns False if the object does not exist and True after the deletion.

:py:meth:get_all(lo, school, filter_str, easy_filter=False)

classmethod; retrieves all objects found for this school. filter can be a string that is used to narrow down a search. Each property of the class’ udm_module that is include_in_default_search is queried for that string. Example:

User.get_all(lo, 'school', filter_str='name', easy_filter=True)

will search in cn=users,ou=school,$base for users/user UDM objects with |(username=*name*)(firstname=*name*)(...) and return User objects (not UDM objects) With easy_filter=False (default) it will use this very filter_str

:py:meth:get_container(school)

a classmethod that points to the container where new instances are created and existing ones are searched.

:py:meth:dn

property, current distinguishable name of the instance. Calculated on the fly, it changes if instance.name or instance.school changes. instance.old_dn will be set to the original dn when the instance was created

:py:meth:get_udm_object(lo)

searches UDM for an entry that corresponds to self. Normally uses the old_dn or dn. If cls._meta.name_is_unique then any object with self.name will match

:py:meth:exists(lo)

whether this object can be found in UDM.

:py:meth:from_udm_obj(udm_obj, school, lo)

classmethod; maps the info of udm_obj into a new instance (and sets school)

:py:meth:from_dn(dn, school, lo)

finds dn in LDAP and uses from_udm_obj

:py:meth:get_first_udm_obj(lo, filter_str)

returns the first found object of type cls._meta.udm_module that matches an arbitrary filter_str

More features:

Validation:

There are some auto checks built in: Attributes of the model that have a UDM syntax attached are validated against this syntax. Attributes that are required must be present. Attributes that are unlikely_to_change give a warning (not error) if the object already exists with other values. If the Meta information states that name_is_unique, the complete LDAP is searched for the instance’s name before continuing. :py:meth:validate() can be further customized.

%(module)s is 'windows' for cls._meta.udm_module == 'computers/windows' by default and can be explicitely set with:

class Meta:
    hook_path = 'computer'

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

hook_sep_char = '\t'#
name: str = <ucsschool.lib.models.attributes.CommonName object>#
school: str = <ucsschool.lib.models.attributes.SchoolAttribute object>#
classmethod cache(*args: Any, **kwargs: Any) UCSSchoolModel[source]#

Initializes a new instance and caches it for subsequent calls. Useful when using School.cache(school_name) a lot in different functions, in loops, etc.

classmethod invalidate_all_caches() None[source]#
classmethod invalidate_cache() None[source]#
classmethod supports_school() bool[source]#
classmethod supports_schools() bool[source]#
classmethod get_machine_connection() LoType[source]#

get a cached ldap connection to the Primary Directory Node using this host’s credentials

property position: str | None#
property dn: str#

Generates a DN where the lib would assume this instance to be. Changing name or school of self will most likely change the outcome of self.dn as well

set_attributes(**kwargs: Any) None[source]#

A function to set the attributes of a UCS@school object in one function call. Only attributes that exist in self._attributes are set. The rest of the kwargs are simply ignored.

Parameters:

kwargs – The attributes to set.

set_dn(dn: str) None[source]#

Does not really set dn, as this is generated on-the-fly. Instead, sets old_dn in case it was missed in the beginning or after create/modify/remove/move Also resets cached udm_obj as it may point to somewhere else

validate(lo: LoType, validate_unlikely_changes: bool | None = False, check_name: bool | None = True) None[source]#
validate_roles(lo: LoType) None[source]#
add_warning(attribute: str, warning_message: str) None[source]#
add_error(attribute: str, error_message: str) None[source]#
exists(lo: LoType) bool[source]#
exists_outside_school(lo: LoType) bool[source]#
call_hooks(hook_time: str, func_name: str, lo: LoType) None[source]#

Calls Python based hooks (*.py files in /usr/share/u-s-i/pyhooks).

In the case of post, this method is only called, if the corresponding function (create(), modify(), move() or remove()) returned True.

Parameters:
classmethod hook_init(hook: PYHOOKS_BASE_CLASS) None[source]#

Overwrite this method to add individual initialization code to all hooks of a ucsschool.lib.model class. (See .SchoolClass.hook_init() for an example.)

Parameters:

hook – instance of a subclass of ucsschool.lib.model.hook.Hook

Returns:

None

Return type:

None

create(lo: LoType, validate: bool | None = True) bool[source]#

Creates a new UDM instance. Calls pre-hooks. If the object already exists, returns False. If the object does not yet exist, creates it, returns True and calls post-hooks.

create_without_hooks(lo: LoType, validate: bool) bool[source]#
create_without_hooks_roles(lo: LoType) bool[source]#

Run by py:meth:create_without_hooks() before py:meth:validate() (and thus before py:meth:do_create()).

do_create(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

modify(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None) bool[source]#

Modifies an existing UDM instance. Calls pre-hooks. If the object does not exist, returns False. If the object exists, modifies it, returns True and calls post-hooks.

modify_without_hooks(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None) bool[source]#
modify_without_hooks_roles(udm_obj: UdmObject) bool[source]#

Run by py:meth:modify_without_hooks() before py:meth:do_modify().

update_ucsschool_roles(lo: LoType) None[source]#

Run by py:meth:modify_without_hooks() before py:meth:validate().

do_modify(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_modify(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_modify(udm_obj, lo)

move(lo: LoType, udm_obj: UdmObject | None = None, force: bool | None = False) bool[source]#
move_without_hooks(lo: LoType, udm_obj: UdmObject | None, force: bool | None = False) bool[source]#
do_move(udm_obj: UdmObject, lo: LoType) None[source]#
do_move_roles(udm_obj: UdmObject, lo: LoType, old_school: str, new_school: str) None[source]#
change_school(school: str, lo: LoType) bool[source]#
do_school_change(udm_obj: UdmObject, lo: LoType, old_school: str) None[source]#
remove(lo: LoType) bool[source]#

Removes an existing UDM instance. Calls pre-hooks. If the object does not exist, returns False. If the object exists, removes it, returns True and calls post-hooks.

remove_without_hooks(lo: LoType) bool[source]#
classmethod get_name_from_dn(dn: str) str[source]#
classmethod get_school_from_dn(dn: str) str[source]#
classmethod find_field_label_from_name(field: str) str[source]#
get_error_msg() str[source]#
get_warning_msg() str[source]#
create_validation_msg(items: Iterable[Tuple[str, List[str]]]) str[source]#
get_udm_object(lo: LoType) UdmObject[source]#

Returns the UDM object that corresponds to self. If self._meta.name_is_unique it searches for any UDM object with self.name. If not (which is the default) it searches for self.old_dn or self.dn Returns None if no object was found. Caches the result, even None If you want to re-search, you need to explicitely set self._udm_obj_searched = False

get_school_obj(lo: LoType) School[source]#
get_superordinate(lo: LoType) UdmObject[source]#
get_own_container() str | None[source]#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_search_base(school_name: str) SchoolSearchBase[source]#
classmethod init_udm_module(lo: LoType) None[source]#
classmethod get_all(lo: LoType, school: str, filter_str: str | None = None, easy_filter: bool | None = False, superordinate: SuperOrdinateType | None = None, school_prefix: bool | None = False) List[UCSSchoolModel][source]#

Returns a list of all objects that can be found in cls.get_container() with the correct udm_module If filter_str is given, all udm properties with include_in_default_search are queried for that string (so that it should be the value)

classmethod lookup(lo: LoType, school: str, filter_s: UldapFilter | None = '', superordinate: SuperOrdinateType | None = None) List[UdmObject][source]#
classmethod build_easy_filter(filter_str: str) conjunction | None[source]#
classmethod from_udm_obj(udm_obj: UdmObject, school: str, lo: LoType) UCSSchoolModel[source]#

Creates a new instance with attributes of the udm_obj. Uses get_class_for_udm_obj()

classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type[UCSSchoolModel][source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

classmethod from_dn(dn: str, school: str, lo: LoType, superordinate: SuperOrdinateType | None = None) UCSSchoolModel[source]#

Returns a new instance based on the UDM object found at dn raises noObject if the udm_module does not match the dn or dn is not found

classmethod get_only_udm_obj(lo: LoType, filter_str: str, superordinate: str | None = None, base: SuperOrdinateType | None = None) UdmObject[source]#

Returns the one UDM object of class cls._meta.udm_module that matches a given filter. If more than one is found, a MultipleObjectsError is raised If none is found, None is returned

classmethod get_first_udm_obj(lo: LoType, filter_str: str, superordinate: str | UdmObject | None = None) UdmObject[source]#

Returns the first UDM object of class cls._meta.udm_module that matches a given filter

classmethod find_udm_superordinate(dn: str, lo: LoType) SuperOrdinateType | None[source]#
to_dict() Dict[str, Any][source]#

Returns a dictionary somewhat representing this instance. This dictionary is usually used when sending the instance to a browser as JSON. By default the attributes are present as well as the dn and the udm_module.

logger = <Proxy at 0x7f8f1358e8c0 wrapping <Logger ucsschool.lib.models.base (DEBUG)> at 0x7f8f0883be90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.base.RoleSupportMixin[source]#

Bases: object

Attribute and methods to handle the ucsschool_roles / ucsschoolRoles attribute.

ucsschool_roles: List[str] = <ucsschool.lib.models.attributes.Roles object>#
default_roles: List[str] = []#
get_schools() Set[str][source]#
get_schools_from_udm_obj(udm_obj: UdmObject) List[str][source]#
property roles_as_dicts: List[Dict[str, str]]#

Get self.ucsschool_roles as a dict.

do_move_roles(udm_obj: UdmObject, lo: LoType, old_school: str, new_school: str) None[source]#
validate_roles(lo: LoType) None[source]#
create_without_hooks_roles(lo: LoType) None[source]#

Run by py:meth:create_without_hooks() before py:meth:validate() (and thus before py:meth:do_create()).

update_ucsschool_roles(lo: LoType) None[source]#

Run by py:meth:modify_without_hooks() before py:meth:validate().

Add ucsschool_roles entries of context_type=school to object, if it got new/additional school(s) and object has no role(s) in those yet.

Delete ucsschool_roles entries of context_type=school of object, if it was removed from school(s).

ucsschool.lib.models.computer module#

class ucsschool.lib.models.computer.AnyComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

classmethod get_container(school: str | None = None) str[source]#

raises NotImplementedError by default. Needs to be overridden!

class Meta[source]#

Bases: object

udm_module = 'computers/computer'#
logger = <Proxy at 0x7f8f132d20c0 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.SchoolDC(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type[SchoolDC][source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

logger = <Proxy at 0x7f8f131d29c0 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.SchoolDCSlave(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolDC

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

groups: List[str] = <ucsschool.lib.models.attributes.Groups object>#
do_create(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

get_schools_from_udm_obj(udm_obj: UdmObject) str[source]#
move_without_hooks(lo: LoType, udm_obj: UdmObject | None = None, force: bool | None = False) bool[source]#
update_ucsschool_roles(lo: LoType) None[source]#

Update roles using membership in groups ‘OU*-DC-Edukativnetz’ and ‘OU*-DC-Verwaltungsnetz’ instead of a ‘schools’ attribute.

class Meta[source]#

Bases: object

udm_module = 'computers/domaincontroller_slave'#
name_is_unique = True#
allow_school_change = True#
logger = <Proxy at 0x7f8f131d2d40 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.SchoolComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

ip_address: List[str] = <ucsschool.lib.models.attributes.IPAddress object>#
subnet_mask: str = <ucsschool.lib.models.attributes.SubnetMask object>#
mac_address: List[str] = <ucsschool.lib.models.attributes.MACAddress object>#
inventory_number: str = <ucsschool.lib.models.attributes.InventoryNumber object>#
zone: str = <ucsschool.lib.models.attributes.Attribute object>#
type_name = 'Computer'#
DEFAULT_PREFIX_LEN = 24#
classmethod lookup(lo: LoType, school: str, filter_s: str | None = '', superordinate: SuperOrdinateType | None = None) List[UdmObject][source]#

This override limits the returned objects to actual ucsschoolComputers. Does not contain School Replica Directory Nodes and others anymore.

get_inventory_numbers() List[str][source]#
property teacher_computer: bool#

True if the computer is a teachers computer.

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

create(lo: LoType, validate: bool | None = True) bool[source]#

Creates a new UDM instance. Calls pre-hooks. If the object already exists, returns False. If the object does not yet exist, creates it, returns True and calls post-hooks.

create_without_hooks(lo: LoType, validate: bool) bool[source]#
modify_without_hooks(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None) bool[source]#
get_ipv4_network() IPv4Interface[source]#
get_network() Network[source]#
create_network(lo: LoType) Network[source]#
validate(lo: LoType, validate_unlikely_changes: bool | None = False) None[source]#
classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type[SchoolComputer][source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

classmethod from_udm_obj(udm_obj: UdmObject, school: str, lo: LoType) SchoolComputer[source]#

Creates a new instance with attributes of the udm_obj. Uses get_class_for_udm_obj()

to_dict() Dict[str, Any][source]#

Returns a dictionary somewhat representing this instance. This dictionary is usually used when sending the instance to a browser as JSON. By default the attributes are present as well as the dn and the udm_module.

class Meta[source]#

Bases: object

udm_module = 'computers/computer'#
name_is_unique = True#
logger = <Proxy at 0x7f8f131d3d40 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.WindowsComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolComputer

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

type_name = 'Windows system'#
default_roles: List[str] = ['win_computer']#
class Meta[source]#

Bases: Meta

udm_module = 'computers/windows'#
hook_path = 'computer'#
logger = <Proxy at 0x7f8f132200c0 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.MacComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolComputer

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

type_name = 'Mac OS X'#
default_roles: List[str] = ['mac_computer']#
class Meta[source]#

Bases: Meta

udm_module = 'computers/macos'#
hook_path = 'computer'#
logger = <Proxy at 0x7f8f13220380 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.IPComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolComputer

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

type_name = 'Device with IP address'#
default_roles: List[str] = ['ip_computer']#
class Meta[source]#

Bases: Meta

udm_module = 'computers/ipmanagedclient'#
hook_path = 'computer'#
logger = <Proxy at 0x7f8f13220600 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.UbuntuComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolComputer

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

type_name = 'Ubuntu system'#
default_roles: List[str] = ['ubuntu_computer']#
class Meta[source]#

Bases: Meta

udm_module = 'computers/ubuntu'#
hook_path = 'computer'#
logger = <Proxy at 0x7f8f132208c0 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.computer.LinuxComputer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SchoolComputer

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

type_name = 'Linux system'#
default_roles: List[str] = ['linux_computer']#
class Meta[source]#

Bases: Meta

udm_module = 'computers/linux'#
hook_path = 'computer'#
logger = <Proxy at 0x7f8f13220b80 wrapping <Logger ucsschool.lib.models.computer (DEBUG)> at 0x7f8f086a4810 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#

ucsschool.lib.models.dhcp module#

class ucsschool.lib.models.dhcp.DHCPService(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.DHCPServiceName object>#
hostname: str = <ucsschool.lib.models.attributes.Attribute object>#
domainname: str = <ucsschool.lib.models.attributes.Attribute object>#
do_create(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

add_server(dc_name: str, lo: LoType, force_dhcp_server_move: bool | None = False) None[source]#

Create the given DHCP server within the DHCP service. If the DHCP server object already exists somewhere else within the LDAP tree, it may be moved to the DHCP service.

PLEASE NOTE: In multiserver environments an existing DHCP server object is always moved to the current DHCP service. In single server environments the DHCP server object is ONLY moved, if the UCR variable dhcpd/ldap/base matches to the current DHCP service.

get_servers(lo: LoType) List[DHCPServer][source]#
class Meta[source]#

Bases: object

udm_module = 'dhcp/service'#
logger = <Proxy at 0x7f8f133000c0 wrapping <Logger ucsschool.lib.models.dhcp (DEBUG)> at 0x7f8f08014e50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.dhcp.AnyDHCPService(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: DHCPService

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school: str = None#
classmethod get_container(school: str = None) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_servers(lo: LoType) List[DHCPServer][source]#
logger = <Proxy at 0x7f8f13300200 wrapping <Logger ucsschool.lib.models.dhcp (DEBUG)> at 0x7f8f08014e50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.dhcp.DHCPServer(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.DHCPServerName object>#
dhcp_service: DHCPService = <ucsschool.lib.models.attributes.DHCPServiceAttribute object>#
get_own_container() str[source]#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_superordinate(lo: LoType) UdmObject[source]#
classmethod find_any_dn_with_name(name: str, lo: LoType) str[source]#
class Meta[source]#

Bases: object

udm_module = 'dhcp/server'#
name_is_unique = True#
logger = <Proxy at 0x7f8f131ba040 wrapping <Logger ucsschool.lib.models.dhcp (DEBUG)> at 0x7f8f08014e50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.dhcp.DHCPSubnet(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.DHCPSubnetName object>#
subnet_mask: str = <ucsschool.lib.models.attributes.DHCPSubnetMask object>#
broadcast: str = <ucsschool.lib.models.attributes.BroadcastAddress object>#
dhcp_service: DHCPService = <ucsschool.lib.models.attributes.DHCPServiceAttribute object>#
get_own_container() str[source]#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_superordinate(lo: LoType) UdmObject[source]#
get_ipv4_subnet() IPv4Network[source]#
classmethod find_all_dns_below_base(dn: str, lo: LoType) List[str][source]#
class Meta[source]#

Bases: object

udm_module = 'dhcp/subnet'#
logger = <Proxy at 0x7f8f132d1040 wrapping <Logger ucsschool.lib.models.dhcp (DEBUG)> at 0x7f8f08014e50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#

ucsschool.lib.models.group module#

class ucsschool.lib.models.group.EmailAttributesMixin[source]#

Bases: object

email: str = <ucsschool.lib.models.attributes.Email object>#
allowed_email_senders_users: List[str] = <ucsschool.lib.models.attributes.Users object>#
allowed_email_senders_groups: List[str] = <ucsschool.lib.models.attributes.Groups object>#
class ucsschool.lib.models.group.Group(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.GroupName object>#
description: str = <ucsschool.lib.models.attributes.Description object>#
users: List[str] = <ucsschool.lib.models.attributes.Users object>#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod is_school_group(school: str, group_dn: str) bool[source]#
classmethod is_school_workgroup(school: str, group_dn: str) bool[source]#
classmethod is_school_class(school: str, group_dn: str) bool[source]#
classmethod is_computer_room(school: str, group_dn: str) bool[source]#
self_is_workgroup() bool[source]#
self_is_class() bool[source]#
self_is_computerroom() bool[source]#
classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type['Group'][source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

add_umc_policy(policy_dn: str, lo: LoType) None[source]#
class Meta[source]#

Bases: object

udm_module = 'groups/group'#
name_is_unique = True#
logger = <Proxy at 0x7f8f131d0540 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.BasicGroup(name: str = None, school: str = None, **kwargs: Any)[source]#

Bases: Group

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school: str = None#
container: str = <ucsschool.lib.models.attributes.Attribute object>#
create_without_hooks(lo: LoType, validate: bool) bool[source]#
create_groups_container(lo: LoType) None[source]#
get_own_container() str[source]#
container_exists(lo: LoType) bool[source]#
classmethod get_container(school: str | None = None) str[source]#

raises NotImplementedError by default. Needs to be overridden!

update_ucsschool_roles(lo: LoType) None[source]#

Run by py:meth:modify_without_hooks() before py:meth:validate().

Add ucsschool_roles entries of context_type=school to object, if it got new/additional school(s) and object has no role(s) in those yet.

Delete ucsschool_roles entries of context_type=school of object, if it was removed from school(s).

validate_roles(lo: LoType) None[source]#
logger = <Proxy at 0x7f8f131d0500 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.BasicSchoolGroup(name: str = None, school: str = None, **kwargs: Any)[source]#

Bases: BasicGroup

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school: str = <ucsschool.lib.models.attributes.SchoolAttribute object>#
logger = <Proxy at 0x7f8f131d1440 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.SchoolGroup(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: Group, _MayHaveSchoolSuffix

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

logger = <Proxy at 0x7f8f131d16c0 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.SchoolClass(name: str | None = None, school: str | None = None, create_share: bool | None = True, **kwargs: Any)[source]#

Bases: Group, _MayHaveSchoolPrefix

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.SchoolClassName object>#
default_roles: List[str] = ['school_class']#
ShareClass#

alias of ClassShare

create_without_hooks(lo: LoType, validate: bool) bool[source]#
create_share(lo: LoType) bool[source]#
modify_without_hooks(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None) bool[source]#
remove_without_hooks(lo: LoType) bool[source]#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

to_dict() Dict[str, Any][source]#

Returns a dictionary somewhat representing this instance. This dictionary is usually used when sending the instance to a browser as JSON. By default the attributes are present as well as the dn and the udm_module.

classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type[SchoolClass] | None[source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

classmethod hook_init(hook: PYHOOKS_BASE_CLASS) None[source]#

Add method get_share() to SchoolClass hooks, to make the associated share easily accessible in hooks.

Parameters:

hook – instance of a subclass of ucsschool.lib.model.hook.Hook

Returns:

None

Return type:

None

validate(lo: LoType, validate_unlikely_changes: bool | None = False) None[source]#
logger = <Proxy at 0x7f8f131d1b00 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.WorkGroup(name: str | None = None, school: str | None = None, create_share: bool | None = True, **kwargs: Any)[source]#

Bases: EmailAttributesMixin, SchoolClass, _MayHaveSchoolPrefix

default_roles: List[str] = ['workgroup']#
ShareClass#

alias of WorkGroupShare

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type[WorkGroup] | None[source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

exists(lo: LoType) bool[source]#

Check if the work group exists avoiding collisions with other groups.

logger = <Proxy at 0x7f8f131d1ec0 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.group.ComputerRoom(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: Group, _MayHaveSchoolPrefix

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

hosts: List[str] = <ucsschool.lib.models.attributes.Hosts object>#
users: List[str] = None#
default_roles: List[str] = ['computer_room']#
create_without_hooks_roles(lo)[source]#

Run by py:meth:create_without_hooks() before py:meth:validate() (and thus before py:meth:do_create()).

to_dict() Dict[str, Any][source]#

Returns a dictionary somewhat representing this instance. This dictionary is usually used when sending the instance to a browser as JSON. By default the attributes are present as well as the dn and the udm_module.

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

property veyon_backend: bool#

True if the computerroom is configured to use the new veyon backend.

get_computers(ldap_connection: LoType) Generator['SchoolComputer'][source]#
get_schools_from_udm_obj(udm_obj: UdmObject) str[source]#
logger = <Proxy at 0x7f8f131d2180 wrapping <Logger ucsschool.lib.models.group (DEBUG)> at 0x7f8f07f7abd0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#

ucsschool.lib.models.hook module#

Base class for all Python based hooks for ucsschool.lib.model classes derived from UCSSchoolHelperAbstractClass.

class ucsschool.lib.models.hook.Hook(lo: LoType, *args: Any, **kwargs: Any)[source]#

Bases: PyHook

Base class for all (1) Python based hooks for ucsschool.lib.model classes derived from UCSSchoolHelperAbstractClass.

The model attribute must be set to the class object the hook is intended for.

Examples are provided in /usr/share/doc/ucs-school-lib-common/hook_example*.py

The following attributes are available:

  • self.lo # LDAP connection object

  • self.logger # Python logging instance

  • self.ucr # UCR instance

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

(1) While it also works for ucsschool.importer.models.import_user.ImportUser, it is strongly recommended to use the dedicated hook class ucsschool.importer.utils.user_pyhook.UserPyHook for it. It adds attributes that are useful in the user import context.

model: Type[UCSSchoolHelperAbstractClassTV] = None#
priority: Dict[str, int | None] = {'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(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code before creating an object.

  • The object does not exist in LDAP, yet.

  • obj.dn is the future DN of the obj, if objname and school does not change.

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

post_create(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code after creating an object.

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

  • Do not run obj.modify(), it will create a recursion. If

    you must modify the object use obj.modify_without_hooks().

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

pre_modify(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code before modifying an object.

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

post_modify(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code after modifying an object.

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

  • Do not run obj.modify(), it will create a recursion. If

    you must modify the object use obj.modify_without_hooks().

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

pre_move(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code before changing an objects position in the LDAP tree. This usually happens when modifying the primary school (obj.school).

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

post_move(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code before changing an objects position in the LDAP tree. This usually happens when modifying the primary school (obj.school).

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

  • Do not run obj.modify(), it will create a recursion. If

    you must modify the object use obj.modify_without_hooks().

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

pre_remove(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code before deleting an object.

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

post_remove(obj: UCSSchoolHelperAbstractClassTV) None[source]#

Run code after deleting an object.

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

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

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

Parameters:

obj (base.UCSSchoolHelperAbstractClass) – ucsschool.lib.model object

Returns:

None

ucsschool.lib.models.meta module#

class ucsschool.lib.models.meta.UCSSchoolHelperOptions(klass, meta=None)[source]#

Bases: object

set_from_meta_object(meta, name, default)[source]#
class ucsschool.lib.models.meta.UCSSchoolHelperMetaClass(cls_name, bases, attrs)[source]#

Bases: type

ucsschool.lib.models.misc module#

class ucsschool.lib.models.misc.MailDomain(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school: str = None#
classmethod get_container(school=None)[source]#

raises NotImplementedError by default. Needs to be overridden!

class Meta[source]#

Bases: object

udm_module = 'mail/domain'#
logger = <Proxy at 0x7f8f132e3a80 wrapping <Logger ucsschool.lib.models.misc (DEBUG)> at 0x7f8f08125e90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.misc.OU(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

create_without_hooks(lo: LoType, validate: bool | None = True) bool[source]#
modify(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None) bool[source]#

Modifies an existing UDM instance. Calls pre-hooks. If the object does not exist, returns False. If the object exists, modifies it, returns True and calls post-hooks.

remove(lo: LoType) bool[source]#

Removes an existing UDM instance. Calls pre-hooks. If the object does not exist, returns False. If the object exists, removes it, returns True and calls post-hooks.

classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

class Meta[source]#

Bases: object

udm_module = 'container/ou'#
logger = <Proxy at 0x7f8f132e2640 wrapping <Logger ucsschool.lib.models.misc (DEBUG)> at 0x7f8f08125e90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.misc.Container(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: OU

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

user_path = <ucsschool.lib.models.attributes.ContainerPath object>#
computer_path = <ucsschool.lib.models.attributes.ContainerPath object>#
network_path = <ucsschool.lib.models.attributes.ContainerPath object>#
group_path = <ucsschool.lib.models.attributes.ContainerPath object>#
dhcp_path = <ucsschool.lib.models.attributes.ContainerPath object>#
policy_path = <ucsschool.lib.models.attributes.ContainerPath object>#
share_path = <ucsschool.lib.models.attributes.ContainerPath object>#
printer_path = <ucsschool.lib.models.attributes.ContainerPath object>#
class Meta[source]#

Bases: object

udm_module = 'container/cn'#
logger = <Proxy at 0x7f8f131f4f00 wrapping <Logger ucsschool.lib.models.misc (DEBUG)> at 0x7f8f08125e90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#

ucsschool.lib.models.network module#

class ucsschool.lib.models.network.Network(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

netmask = <ucsschool.lib.models.attributes.Netmask object>#
network = <ucsschool.lib.models.attributes.NetworkAttribute object>#
broadcast = <ucsschool.lib.models.attributes.NetworkBroadcastAddress object>#
classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

get_subnet()[source]#
create_without_hooks(lo, validate)[source]#
do_create(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

classmethod invalidate_cache()[source]#
classmethod get_netmask(dn, school, lo)[source]#
class Meta[source]#

Bases: object

udm_module = 'networks/network'#
logger = <Proxy at 0x7f8f131d2600 wrapping <Logger ucsschool.lib.models.network (DEBUG)> at 0x7f8f079ed990 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.network.DNSReverseZone(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.SubnetName object>#
school: str = None#
classmethod get_container(school=None)[source]#

raises NotImplementedError by default. Needs to be overridden!

do_create(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

class Meta[source]#

Bases: object

udm_module = 'dns/reverse_zone'#
logger = <Proxy at 0x7f8f131d2880 wrapping <Logger ucsschool.lib.models.network (DEBUG)> at 0x7f8f079ed990 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#

ucsschool.lib.models.policy module#

class ucsschool.lib.models.policy.Policy(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

attach(obj, lo)[source]#
logger = <Proxy at 0x7f8f131f5500 wrapping <Logger ucsschool.lib.models.policy (DEBUG)> at 0x7f8f079665d0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.policy.UMCPolicy(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: Policy

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

class Meta[source]#

Bases: object

udm_module = 'policies/umc'#
logger = <Proxy at 0x7f8f131f58c0 wrapping <Logger ucsschool.lib.models.policy (DEBUG)> at 0x7f8f079665d0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.policy.DHCPDNSPolicy(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: Policy

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

empty_attributes = <ucsschool.lib.models.attributes.EmptyAttributes object>#
class Meta[source]#

Bases: object

udm_module = 'policies/dhcp_dns'#
logger = <Proxy at 0x7f8f131f5c40 wrapping <Logger ucsschool.lib.models.policy (DEBUG)> at 0x7f8f079665d0 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#

ucsschool.lib.models.school module#

class ucsschool.lib.models.school.School(name=None, school=None, alter_dhcpd_base=None, **kwargs)[source]#

Bases: RoleSupportMixin, UCSSchoolHelperAbstractClass

name: str = <ucsschool.lib.models.attributes.SchoolName object>#
dc_name: str = <ucsschool.lib.models.attributes.DCName object>#
dc_name_administrative: str = <ucsschool.lib.models.attributes.DCName object>#
class_share_file_server: str = <ucsschool.lib.models.attributes.ShareFileServer object>#
home_share_file_server: str = <ucsschool.lib.models.attributes.ShareFileServer object>#
school: str = None#
educational_servers: List[str] = <ucsschool.lib.models.attributes.Attribute object>#
administrative_servers: List[str] = <ucsschool.lib.models.attributes.Attribute object>#
default_roles: List[str] = ['school']#
display_name: str = <ucsschool.lib.models.attributes.DisplayName object>#
validate(lo, validate_unlikely_changes=False)[source]#
get_district()[source]#
get_own_container()[source]#
classmethod get_container(school=None)[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod cn_name(name, default)[source]#
create_default_containers(lo)[source]#
group_name(prefix_var, default_prefix)[source]#
get_umc_policy_dn(name)[source]#
create_default_groups(lo)[source]#
get_dc_name_fallback(administrative=False)[source]#
get_dc_name(administrative=False)[source]#
get_share_fileserver_dn(set_by_self, lo)[source]#
get_class_share_file_server(lo)[source]#
get_home_share_file_server(lo)[source]#
get_administrative_group_name(group_type, domain_controller=True, ou_specific=False, as_dn=False)[source]#
get_administrative_server_names(lo: LoType) List[str][source]#
get_educational_server_names(lo: LoType) List[str][source]#
add_host_to_dc_group(lo)[source]#
shall_create_administrative_objects()[source]#
create_dc_slave(lo, name, administrative=False)[source]#
add_domain_controllers(lo)[source]#
get_dhcp_service(hostname=None)[source]#
create_without_hooks(lo, validate)[source]#
remove_without_hooks(lo)[source]#
get_schools()[source]#
classmethod from_binddn(lo)[source]#
classmethod from_udm_obj(udm_obj, school, lo)[source]#

Creates a new instance with attributes of the udm_obj. Uses get_class_for_udm_obj()

classmethod get_all(lo, filter_str=None, easy_filter=False, respect_local_oulist=True)[source]#

Returns a list of all objects that can be found in cls.get_container() with the correct udm_module If filter_str is given, all udm properties with include_in_default_search are queried for that string (so that it should be the value)

classmethod invalidate_cache()[source]#
set_ucsschool_role_for_dc(lo: LoType) None[source]#

Set the ucsschool role for the computer on which the school is replicated. formerly in shell hook 40dhcp_dns_marktplatz_ucsschoolrole

create_market_place_share(lo: LoType) None[source]#

Create a share object with the name Marktplatz for the school. formerly in shell hook 40dhcp_dns_marktplatz_ucsschoolrole

create_dhcp_search_base(lo: LoType) None[source]#

Create the policies/registry ou-default-ucr-policy for the school, add the dhcp-ou-dn to it an link to the school.

formerly in shell hook 40dhcp_dns_marktplatz_ucsschoolrole

create_dhcp_dns_policy(lo: LoType) None[source]#

Add a DHCPDNSPolicy for the school, append it to the respective container/cn object and add domain_name and domain_name_servers in single server environments. formerly in shell hook 40dhcp_dns_marktplatz_ucsschoolrole

create_import_group(lo: LoType) None[source]#

Create the OU-import-all group, which enables user to run an import, add the UMC policy schoolimport-all to it and set roles and options which are used in the import. formerly in shell hook 53importgroup_create

create_exam_group(lo: LoType) None[source]#

Creates the exam users container cn=examusers and the OU-specific group, e.g. DEMOSCHOOL-Klassenarbeit for the school. formerly in shell hook 60schoolexam-master.

class Meta[source]#

Bases: object

udm_module = 'container/ou'#
udm_filter = 'objectClass=ucsschoolOrganizationalUnit'#
logger = <Proxy at 0x7f8f13220dc0 wrapping <Logger ucsschool.lib.models.school (DEBUG)> at 0x7f8f077f0750 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#

ucsschool.lib.models.share module#

exception ucsschool.lib.models.share.NoSID[source]#

Bases: Exception

exception ucsschool.lib.models.share.NoSchoolGroup[source]#

Bases: Exception

class ucsschool.lib.models.share.SetNTACLsMixin[source]#

Bases: object

Mixin for setting NTACLs of UCS@school Share (sub)classes. For example to to prevent students from changing the permissions in a share (Bug #42182).

D ~ deny, OI/ OBJECT_INHERIT_ACE ~ Object inheritance, CI/ CONTAINER_INHERIT_ACE ~ container inheritance RC/ READ_CONTROL ~ display security attributes WO/ WRITE_OWNER ~ take ownership WD/ WRITE_DAC ~ write security permissions To make sure, students can edit folders&files in subfolders, they need to inherit edit or full control, since they are denied first. For a complete overview of all options, see https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings

get_nt_acls(lo: LoType) List[str][source]#
static get_groups_samba_sid(lo: LoType, dn: str) str[source]#
get_ou_admin_full_control(lo: LoType) List[str][source]#
get_aces_deny_students_change_permissions(lo: LoType) List[str][source]#

Get the schueler-ou sid to deny all students the permissions to modify permissions and take ownership. Derived classes may add more NTACLS.

Sets NT ACLs to disallow students to deny students to change the permission of folders, subfolder and files or to take ownership of them as well as displaying them (RC).

get_aces_work_group(lo: LoType) List[str][source]#

ACE: deny schueler to change permissions & take ownership ACE: allow workgroup-members to read/write/modify ACE: allow ou-admins full control

get_aces_market_place(lo: LoType) List[str][source]#

ACE: deny schueler to change permissions & take ownership ACE: allow Domain Users to read/write/modify ACE: allow ou-admins full control

get_aces_class_group(lo: LoType) List[str][source]#

ACE: deny schueler to change permissions & take ownership ACE: allow class-members to read/write/modify ACE: allow ou-admins full control

set_nt_acls(udm_obj: UdmObject, lo: LoType) None[source]#
class ucsschool.lib.models.share.Share(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: UCSSchoolHelperAbstractClass

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

name: str = <ucsschool.lib.models.attributes.ShareName object>#
create_defaults = {'directorymode': '0770', 'group': '0', 'owner': '0', 'sambaBrowseable': '1', 'sambaCreateMode': '0770', 'sambaDirectoryMode': '0770', 'sambaForceGroup': '+{name}', 'sambaWriteable': '1', 'writeable': '1'}#
paths = {'no_roleshare': '/home/groups/{name}', 'roleshare': '/home/{ou}/groups/{name}'}#
classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

do_create(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

get_gid_number(lo)[source]#
get_share_path(school=None)[source]#
do_modify(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_modify(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_modify(udm_obj, lo)

get_server_fqdn(lo)[source]#
class Meta[source]#

Bases: object

udm_module = 'shares/share'#
logger = <Proxy at 0x7f8f131f6680 wrapping <Logger ucsschool.lib.models.share (DEBUG)> at 0x7f8f07d51d90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.share.GroupShare(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: SetNTACLsMixin, Share

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school_group = <ucsschool.lib.models.attributes.SchoolClassAttribute object>#
classmethod from_school_group(school_group)[source]#
classmethod from_school_class(school_group)#
get_gid_number(lo)[source]#
get_share_path(school=None)[source]#
do_create(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

logger = <Proxy at 0x7f8f131c1c40 wrapping <Logger ucsschool.lib.models.share (DEBUG)> at 0x7f8f07d51d90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.share.WorkGroupShare(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, GroupShare

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school_group = <ucsschool.lib.models.attributes.WorkgroupAttribute object>#
default_roles: List[str] = ['workgroup_share']#
classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_all(lo, school, filter_str=None, easy_filter=False, superordinate=None)[source]#

This method was overwritten to identify WorkGroupShares and distinct them from other shares of the school. If at some point a lookup is implemented that uses the role attribute which is reliable this code can be removed. Bug #48428

get_nt_acls(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f131c2680 wrapping <Logger ucsschool.lib.models.share (DEBUG)> at 0x7f8f07d51d90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.share.ClassShare(name: str | None = None, school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, GroupShare

Initializes a new instance with kwargs. Not every kwarg is accepted, though: The name must be defined as a attribute at class level (or by a base class). All attributes are initialized at least with None Sets self.old_dn to self.dn, i.e. the name in __init__ will determine the old_dn, changing it after __init__ will result in trying to move the object!

school_group = <ucsschool.lib.models.attributes.SchoolClassAttribute object>#
default_roles: List[str] = ['school_class_share']#
paths = {'no_roleshare': '/home/groups/klassen/{name}', 'roleshare': '/home/{ou}/groups/klassen/{name}'}#
classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_group_class()[source]#
get_nt_acls(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f131c2e40 wrapping <Logger ucsschool.lib.models.share (DEBUG)> at 0x7f8f07d51d90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.share.MarketplaceShare(name: str | None = 'Marktplatz', school: str | None = None, **kwargs: Any)[source]#

Bases: RoleSupportMixin, SetNTACLsMixin, Share

default_roles: List[str] = ['marketplace_share']#
classmethod get_container(school)[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_all(lo, school, filter_str=None, easy_filter=False, superordinate=None)[source]#

Returns a list of all objects that can be found in cls.get_container() with the correct udm_module If filter_str is given, all udm properties with include_in_default_search are queried for that string (so that it should be the value)

get_gid_number(lo)[source]#
get_share_path(school=None)[source]#
do_create(udm_obj, lo)[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

get_nt_acls(lo: LoType) List[str][source]#
class Meta[source]#

Bases: Meta

udm_filter = '(&(univentionObjectType=shares/share)(cn=Marktplatz))'#
logger = <Proxy at 0x7f8f131c3400 wrapping <Logger ucsschool.lib.models.share (DEBUG)> at 0x7f8f07d51d90 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#

ucsschool.lib.models.user module#

class ucsschool.lib.models.user.User(*args, **kwargs)[source]#

Bases: RoleSupportMixin, UCSSchoolHelperAbstractClass

name: str = <ucsschool.lib.models.attributes.Username object>#
schools: List[str] = <ucsschool.lib.models.attributes.Schools object>#
firstname: str = <ucsschool.lib.models.attributes.Firstname object>#
lastname: str = <ucsschool.lib.models.attributes.Lastname object>#
birthday: str = <ucsschool.lib.models.attributes.Birthday object>#
expiration_date: str = <ucsschool.lib.models.attributes.UserExpirationDate object>#
email: str = <ucsschool.lib.models.attributes.Email object>#
password: str | None = <ucsschool.lib.models.attributes.Password object>#
disabled: bool = <ucsschool.lib.models.attributes.Disabled object>#
workgroups: Dict[str, List[str]] = <ucsschool.lib.models.attributes.WorkgroupsAttribute object>#
type_name: str = None#
type_filter = '(|(objectClass=ucsschoolTeacher)(objectClass=ucsschoolStaff)(objectClass=ucsschoolStudent))'#
roles: List[str] = []#
default_roles: List[str] = []#
default_options: Tuple[str] = ()#
school_classes: Dict[str, List[str]] = <ucsschool.lib.models.attributes.SchoolClassesAttribute object>#
classmethod shall_create_mail_domain() bool[source]#
get_roleshare_home_subdir() str[source]#
get_samba_home_drive() str[source]#
get_samba_netlogon_script_path() str[source]#
get_samba_home_path(lo: LoType) str[source]#
get_profile_path(lo: LoType) str[source]#
is_student(lo: LoType) bool[source]#
is_exam_student(lo: LoType) bool[source]#
is_teacher(lo: LoType) bool[source]#
is_staff(lo: LoType) bool[source]#
is_administrator(lo: LoType) bool[source]#
classmethod get_class_for_udm_obj(udm_obj: UdmObject, school: str) Type['User'][source]#

Returns cls by default.

Can be overridden for base classes: class User(UCSSchoolHelperAbstractClass):

@classmethod def get_class_for_udm_obj(cls, udm_obj, school)

if something:

return SpecialUser

return cls

class SpecialUser(User):

pass

Now, User.get_all() will return a list of User and SpecialUser objects If this function returns None for a udm_obj, that obj will not yield a new instance in get_all() and from_udm_obj() will return None for that udm_obj

classmethod from_udm_obj(udm_obj: UdmObject, school: str, lo: LoType) User[source]#

Creates a new instance with attributes of the udm_obj. Uses get_class_for_udm_obj()

create(lo: LoType, validate: bool | None = True, check_password_policies: bool | None = False) bool[source]#

Creates a new UDM instance. Calls pre-hooks. If the object already exists, returns False. If the object does not yet exist, creates it, returns True and calls post-hooks.

do_create(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_create(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_create(udm_obj, lo)

modify(lo: LoType, validate: bool | None = True, move_if_necessary: bool | None = None, check_password_policies: bool | None = False) bool[source]#

Modifies an existing UDM instance. Calls pre-hooks. If the object does not exist, returns False. If the object exists, modifies it, returns True and calls post-hooks.

do_modify(udm_obj: UdmObject, lo: LoType) None[source]#

Actual udm_obj manipulation. Override this if you want to further change values of udm_obj, e.g. def do_modify(self, udm_obj, lo):

udm_obj[‘used_in_ucs_school’] = ‘1’ super(MyModel, self).do_modify(udm_obj, lo)

do_school_change(udm_obj: UdmObject, lo: LoType, old_school: str) None[source]#
get_mail_domain() MailDomain[source]#
create_mail_domain(lo: LoType) None[source]#
set_default_options(udm_obj: UdmObject) None[source]#
classmethod get_default_options() Set[str][source]#
get_specific_groups(lo: LoType) List[str][source]#
validate()[source]#
remove_from_school(school: str, lo: LoType) bool[source]#
remove_from_groups_of_school(school: str, lo: LoType) None[source]#
get_group_dn(group_name: str, school: str) str[source]#
get_class_dn(class_name: str, school: str, lo: LoType) str[source]#
get_workgroup_dn(workgroup_name: str, school: str, lo: LoType) str[source]#
primary_group_dn(lo: LoType) str[source]#
get_domain_users_groups(schools: List[str] | None = None) List[str][source]#
get_students_groups(schools: List[str] | None = None) List[str][source]#
get_teachers_groups(schools: List[str] | None = None) List[str][source]#
get_staff_groups(schools: List[str] | None = None) List[str][source]#
get_school_admin_groups(schools: List[str] | None = None) List[str][source]#
groups_used(lo: LoType) List[str][source]#
classmethod get_or_create_group_udm_object(group_dn: str, lo: LoType, fresh: bool | None = False) Group[source]#

In the case of work groups, this function assumes that they already exists.

Raises:

RuntimeError – if a work group does not exist.

is_active() bool[source]#
to_dict() Dict[str, Any][source]#

Returns a dictionary somewhat representing this instance. This dictionary is usually used when sending the instance to a browser as JSON. By default the attributes are present as well as the dn and the udm_module.

get_school_class_objs() List[SchoolClass][source]#
get_workgroup_objs() List[WorkGroup][source]#
classmethod get_school_classes(udm_obj: UdmObject, obj: User) Dict[str, List[str]][source]#
classmethod get_workgroups(udm_obj: UdmObject, obj: User) Dict[str, List[str]][source]#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod lookup(lo: LoType, school: str, filter_s: UldapFilter | None = '', superordinate: SuperOrdinateType | None = None) List[UdmObject][source]#
class Meta[source]#

Bases: object

udm_module = 'users/user'#
name_is_unique = True#
allow_school_change = False#
logger = <Proxy at 0x7f8f132214c0 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.user.Student(*args, **kwargs)[source]#

Bases: User

type_name: str = 'Student'#
type_filter = '(&(objectClass=ucsschoolStudent)(!(objectClass=ucsschoolExam)))'#
roles: List[str] = ['pupil']#
default_options: Tuple[str] = ('ucsschoolStudent',)#
default_roles: List[str] = ['student']#
do_school_change(udm_obj: UdmObject, lo: LoType, old_school: str) None[source]#
classmethod get_container(school: str) UdmObject[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod get_exam_container(school: str) str[source]#
get_specific_groups(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f13221900 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.user.Teacher(*args, **kwargs)[source]#

Bases: User

type_name: str = 'Teacher'#
type_filter = '(&(objectClass=ucsschoolTeacher)(!(objectClass=ucsschoolStaff)))'#
roles: List[str] = ['teacher']#
default_roles: List[str] = ['teacher']#
default_options: Tuple[str] = ('ucsschoolTeacher',)#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_specific_groups(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f13221b40 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.user.SchoolAdmin(*args, **kwargs)[source]#

Bases: User

type_name: str = 'School Administrator'#
type_filter = '(objectClass=ucsschoolAdministrator)'#
roles: List[str] = ['school_admin']#
default_roles: List[str] = ['school_admin']#
default_options: Tuple[str] = ('ucsschoolAdministrator',)#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_specific_groups(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f13221d80 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#
class ucsschool.lib.models.user.Staff(*args, **kwargs)[source]#

Bases: User

school_classes: Dict[str, List[str]] = None#
type_name: str = 'Staff'#
roles: List[str] = ['staff']#
default_roles: List[str] = ['staff']#
type_filter = '(&(!(objectClass=ucsschoolTeacher))(objectClass=ucsschoolStaff))'#
default_options: Tuple[str] = ('ucsschoolStaff',)#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_samba_home_path(lo: LoType) None[source]#

Do not set sambaHomePath for staff users.

get_samba_home_drive() None[source]#

Do not set sambaHomeDrive for staff users.

get_samba_netlogon_script_path() None[source]#

Do not set sambaLogonScript for staff users.

get_profile_path(lo: LoType) None[source]#

Do not set sambaProfilePath for staff users.

get_school_class_objs() List[SchoolClass][source]#
classmethod get_school_classes(udm_obj: UdmObject, obj: Staff) Dict[str, List[str]][source]#
get_specific_groups(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f13221f40 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.user.TeachersAndStaff(*args, **kwargs)[source]#

Bases: Teacher

type_name: str = 'Teacher and Staff'#
type_filter = '(&(objectClass=ucsschoolStaff)(objectClass=ucsschoolTeacher))'#
roles: List[str] = ['teacher', 'staff']#
default_roles: List[str] = ['teacher', 'staff']#
default_options: Tuple[str] = ('ucsschoolStaff',)#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

get_specific_groups(lo: LoType) List[str][source]#
logger = <Proxy at 0x7f8f13222100 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
class ucsschool.lib.models.user.ExamStudent(*args, **kwargs)[source]#

Bases: Student

type_name: str = 'Exam student'#
type_filter = '(&(objectClass=ucsschoolStudent)(objectClass=ucsschoolExam))'#
default_roles: List[str] = ['exam_user']#
default_options: Tuple[str] = ('ucsschoolExam',)#
classmethod get_container(school: str) str[source]#

raises NotImplementedError by default. Needs to be overridden!

classmethod from_student_dn(lo: LoType, school: str, dn: str) ExamStudent[source]#
logger = <Proxy at 0x7f8f13222300 wrapping <Logger ucsschool.lib.models.user (DEBUG)> at 0x7f8f0b864d50 with factory <function UCSSchoolHelperMetaClass.__new__.<locals>.<lambda>>>#
old_dn: str#
errors: Dict[str, List[str]]#
warnings: Dict[str, List[str]]#

ucsschool.lib.models.utils module#

exception ucsschool.lib.models.utils.NotInstalled[source]#

Bases: Exception

Raised by get_package_version() when the requested package is not installed.

exception ucsschool.lib.models.utils.UnknownPackage[source]#

Bases: Exception

Raised by get_package_version() when the requested package is not known in the Debian package cache.

class ucsschool.lib.models.utils.ValidationDataFilter(name='')[source]#

Bases: Filter

Initialize a filter.

Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event.

filter(record)[source]#

Determine if the specified record is to be logged.

Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place.

ucsschool.lib.models.utils.mkdir_p(dir_name: str, user: str | int, group: str | int, mode: int) None[source]#

Recursively create directories (like “mkdir -p”).

Parameters:
  • dir_name (str) – path to create

  • user (str) – username of owner of new directories

  • group (str) – group name for ownership of new directories

  • mode (octal) – permission bits to set for new directories

Returns:

None

Return type:

None

class ucsschool.lib.models.utils.UniFileHandler(filename: str, when: str | None = 'h', interval: int | None = 1, backupCount: int | None = 0, encoding: str | None = None, delay: bool | None = False, utc: bool | None = False, fuid: int | None = None, fgid: int | None = None, fmode: int | None = None)[source]#

Bases: TimedRotatingFileHandler

TimedRotatingFileHandler that can set file permissions and removes password entries from from dicts in args.

Use the specified filename for streamed logging

emit(record)[source]#

remove password from from dicts in args

class ucsschool.lib.models.utils.UniStreamHandler(stream: IO = None, fuid: int | None = None, fgid: int | None = None, fmode: int | None = None)[source]#

Bases: StreamHandler

Colorizing console stream handler that removes password entries from from dicts in args.

fuid, fgid and fmode are here only for similarity of interface to UniFileHandler and are ignored.

emit(record)[source]#

remove password from from dicts in args

class ucsschool.lib.models.utils.ModuleHandler(level: int | None = 0, udebug_facility: int | None = 8)[source]#

Bases: Handler

Adapter: use Python logging but emit through univention debug

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]#

log to univention debug, remove password from dicts in args

class ucsschool.lib.models.utils.UCSTTYColoredFormatter(fmt: str | None = None, datefmt: str | None = None, style: Literal['%', '{', '$'] = '%', log_colors: Mapping[str, str] | None = None, reset: bool = True, secondary_log_colors: Mapping[str, Mapping[str, str]] | None = None, validate: bool = True, stream: IO | None = None, no_color: bool = False, force_color: bool = False, defaults: Mapping[str, Any] | None = None)[source]#

Bases: ColoredFormatter

Subclass of colorlog.TTYColoredFormatter that will force colorization on, in case UCSSCHOOL_FORCE_COLOR_TERM is found in env.

Set the format and colors the ColoredFormatter will use.

The fmt, datefmt, style, and default args are passed on to the logging.Formatter constructor.

The secondary_log_colors argument can be used to create additional log_color attributes. Each key in the dictionary will set {key}_log_color, using the value to select from a different log_colors set.

Parameters:

  • fmt (str): The format string to use.

  • datefmt (str): A format string for the date.

  • log_colors (dict):

    A mapping of log level names to color names.

  • reset (bool):

    Implicitly append a color reset to all records unless False.

  • style (‘%’ or ‘{’ or ‘$’):

    The format style to use.

  • secondary_log_colors (dict):

    Map secondary log_color attributes. (New in version 2.6.)

  • validate (bool)

    Validate the format string.

  • stream (typing.IO)

    The stream formatted messages will be printed to. Used to toggle colour on non-TTY outputs. Optional.

  • no_color (bool):

    Disable color output.

  • force_color (bool):

    Enable color output. Takes precedence over no_color.

color(log_colors, level_name)[source]#
ucsschool.lib.models.utils.add_stream_logger_to_schoollib(level: str | None = 'DEBUG', stream: ~typing.IO | None = <colorama.ansitowin32.StreamWrapper object>, log_format: str | None = None, name: str | None = None) Logger[source]#

Outputs all log messages of the models code to a stream (default: “stderr”):

from ucsschool.lib.models.utils import add_stream_logger_to_schoollib
add_stream_logger_to_schoollib()
# or:
add_stream_logger_to_schoollib(level='ERROR', stream=sys.stdout,
    log_format='ERROR (or worse): %(message)s')
ucsschool.lib.models.utils.add_module_logger_to_schoollib() None[source]#
ucsschool.lib.models.utils.create_passwd(length: int | None = 8, dn: str | None = None, specials: str | None = '$%&*-+=:.?') str[source]#

pseudorandom!

ucsschool.lib.models.utils.flatten(list_of_lists: List[List[Any]]) List[Any][source]#
ucsschool.lib.models.utils.loglevel_int2str(level: int | str) str[source]#

Convert numeric loglevel to string name.

ucsschool.lib.models.utils.nearest_known_loglevel(level)[source]#

Get loglevel nearest to those known in CMDLINE_LOG_FORMATS and FILE_LOG_FORMATS.

ucsschool.lib.models.utils.get_stream_handler(level: int | str, stream: IO | None = None, fmt: str | None = None, datefmt: str | None = None, fmt_cls: type | None = None) Handler[source]#

Create a colored stream handler, usually for the console.

Parameters:
  • level (int or str) – log level

  • stream (file) – opened file to write to (/dev/stdout if None)

  • fmt (str) – log message format (will be passt to a Formatter instance)

  • datefmt (str) – date format (will be passt to a Formatter instance)

  • fmt_cls (type) – Formatter class to use, defaults to UCSTTYColoredFormatter

Returns:

a handler

Return type:

logging.Handler

ucsschool.lib.models.utils.get_file_handler(level: int | str, filename: str, fmt: str | None = None, datefmt: str | None = None, uid: int | None = None, gid: int | None = None, mode: int | None = None, backupCount: int | None = 10000, when: str | None = 'D') Handler[source]#

Create a UniFileHandler (TimedRotatingFileHandler) for logging to a file.

Parameters:
  • level (int or str) – log level

  • filename (str) – path of file to write to

  • fmt (str) – log message format (will be passt to a Formatter instance)

  • datefmt (str) – date format (will be passt to a Formatter instance)

  • uid (int) – user that the file should belong to (current user if None)

  • gid (int) – group that the file should belong to (current users primary group if None)

  • mode (int) – permissions of the file

  • backupCount (int) – If backupCount is nonzero, at most backupCount files will be kept. When rollover occurs, the oldest one is deleted.

  • when (str) – time when log is rotated.

Returns:

a handler

Return type:

logging.Handler

ucsschool.lib.models.utils.get_logger(name: str, level: str | None = 'INFO', target: ~typing.IO | None = <colorama.ansitowin32.StreamWrapper object>, handler_kwargs: ~typing.Dict[str, ~typing.Any] | None = None, formatter_kwargs: ~typing.Dict[str, ~typing.Any] | None = None) Logger[source]#

Get a logger object below the ucsschool root logger.

Deprecated since version 4.4: v2 Use logging.getLogger(__name__) and get_stream_handler(), get_file_handler().

  • The logger will use UniStreamHandler(StreamHandler) for streams (sys.stdout etc) and 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.

  • 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: will be appended to “ucsschool.” as name of the logger

  • level – str: loglevel (DEBUG, INFO etc)

  • target – stream (open file) or a 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 logging.Formatter.

Returns:

a python logging object

ucsschool.lib.models.utils.exec_cmd(cmd: Sequence[str], log: bool | None = False, raise_exc: bool | None = False, **kwargs: Any) Tuple[int, str, str][source]#

Execute command.

Parameters:
  • cmd (list(str)) – command line as list of strings

  • log (bool) – log text returned in stdout (with level INFO) and text returned in stderr (with level ERROR)

  • raise_exc (bool) – raise RunTime

  • kwargs (dict) – arguments to pass to subprocess.Popen() call

Returns:

3-tuple: returncode (int), stdout (str), stderr (str)

Return type:

tuple(int, str, str)

Raises:
ucsschool.lib.models.utils.stopped_notifier(strict: bool | None = True) None[source]#

Stops univention-directory-notifier while in a block and starts it in the end. Service if stopped/started by systemctl.

Will not start if ucr get notifier/autostart=no – but will stop!

with stopped_notifier():
    ...
Parameters:

strict (bool) – raise RuntimeError if stopping fails

Raises:

RuntimeError – if stopping failed and strict=True

ucsschool.lib.models.utils.get_package_version(package_name: str) str[source]#

Retrieve the version of the Debian package package_name from the Debian package cache.

Parameters:

package_name (str) – name of Debian package

Returns:

version of Debian package, if installed

Return type:

str

Raises:
ucsschool.lib.models.utils.add_or_remove_ucrv_value(ucrv, action, value, delimiter)[source]#

Adds or removes a value to a ucrv. Delimiter splits the value of the existing ucr.

This code was refactored from ucs-school-lib/modify_ucr_list, so that it could also be used in the school_creation listener. Bcause the method is also called from a cli script it returns 0.

ucsschool.lib.models.validator module#

ucsschool.lib.models.validator.get_private_data_logger()[source]#
ucsschool.lib.models.validator.get_position_from(dn: str) str | None[source]#
ucsschool.lib.models.validator.obj_to_dict(obj: UdmObject) Dict[str, Any][source]#
ucsschool.lib.models.validator.obj_to_dict_conversion(obj: UdmObject | Dict[str, Any]) Dict[str, Any][source]#
ucsschool.lib.models.validator.is_student_role(role: str) bool[source]#
class ucsschool.lib.models.validator.SchoolValidator[source]#

Bases: object

position_regex = None#
attributes = []#
roles = []#
classmethod validate(obj: Dict[str, Any]) List[str][source]#
classmethod required_attributes(props: Dict[str, Any]) str | None[source]#
classmethod position(position: str) str | None[source]#
classmethod required_roles(roles: List[str], expected_roles: List[str]) str | None[source]#
classmethod roles_at_school(schools: List[str]) List[str][source]#

Get all roles for all schools which the object is expected to have.

classmethod expected_roles(obj: Dict[str, Any]) List[str][source]#
classmethod get_search_base(school: str) SchoolSearchBase[source]#
class ucsschool.lib.models.validator.UserValidator[source]#

Bases: SchoolValidator

is_student = False#
is_exam_user = False#
is_teacher = False#
is_staff = False#
is_school_admin = False#
attributes = ['username', 'ucsschoolRole', 'school', 'firstname', 'lastname']#
classmethod validate(obj: Dict[str, Any]) List[str][source]#
classmethod expected_roles(obj: Dict[str, Any]) List[str][source]#
classmethod expected_groups(obj: Dict[str, Any]) List[str][source]#

Collect expected groups of user. Overwrite for special cases in subclasses.

classmethod validate_required_groups(groups: List[str], expected_groups: List[Any]) str | None[source]#

Object should be in all groups/ containers. E.g.: Students must have at least one group in cn=klassen,cn=schueler,cn=groups,ou=ou, which is true if the string ends with the classes position. For groups like cn=schueler-ou endwith is the same as equal.

classmethod validate_part_of_school(roles: List[Tuple[str]], schools: List[str]) str | None[source]#

Users should not have roles with schools which they don’t have.

classmethod validate_student_roles(roles: List[Tuple[str]]) str | None[source]#

Students should not have teacher, staff or school_admin role.

classmethod domain_users_group(schools: List[str]) List[str][source]#

Users should be inside the Domain Users OU of their schools.

classmethod role_groups(schools: List[str]) List[str][source]#

Users with cls.role should be in the corresponding group at each school they are part of. Implemented in subclasses.

classmethod validate_group_membership(groups: List[str]) List[str][source]#

Validate group membership, e.g. students should not be in teachers group.

class ucsschool.lib.models.validator.StudentValidator[source]#

Bases: UserValidator

position_regex = re.compile('cn=schueler,cn=users,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_student = True#
roles = ['student']#
classmethod expected_groups(obj: Dict[str, Any]) List[str][source]#

Students have at least one class at every school.

classmethod role_groups(schools: List[str]) List[str][source]#

Users with cls.role should be in the corresponding group at each school they are part of. Implemented in subclasses.

class ucsschool.lib.models.validator.TeacherValidator[source]#

Bases: UserValidator

position_regex = re.compile('cn=lehrer,cn=users,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_teacher = True#
roles = ['teacher']#
classmethod role_groups(schools: List[str]) List[str][source]#

Users with cls.role should be in the corresponding group at each school they are part of. Implemented in subclasses.

class ucsschool.lib.models.validator.ExamStudentValidator[source]#

Bases: StudentValidator

position_regex = re.compile('cn=examusers,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_exam_user = True#
is_student = True#
roles = ['exam_user']#
classmethod validate(obj: Dict[str, Any]) List[str][source]#
classmethod validate_exam_contexts(roles: List[Tuple[str]]) str[source]#

ExamUsers should have a role with context exam, e.g exam_user:exam:demo-exam-DEMOSCHOOL.

classmethod role_groups(schools: List[str]) List[str][source]#

ExamUsers should be inside a corresponding group in each of their schools. SchoolSearchBase.examGroup has no school.lower()

class ucsschool.lib.models.validator.StaffValidator[source]#

Bases: UserValidator

position_regex = re.compile('cn=mitarbeiter,cn=users,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_staff = True#
roles = ['staff']#
classmethod role_groups(schools: List[str]) List[str][source]#

Users with cls.role should be in the corresponding group at each school they are part of. Implemented in subclasses.

class ucsschool.lib.models.validator.TeachersAndStaffValidator[source]#

Bases: UserValidator

position_regex = re.compile('cn=lehrer und mitarbeiter,cn=users,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_teacher = True#
is_staff = True#
roles = ['teacher', 'staff']#
classmethod role_groups(schools: List[str]) List[str][source]#

TeachersAndStaff Users should be inside teachers and staff groups in all of their schools.

class ucsschool.lib.models.validator.SchoolAdminValidator[source]#

Bases: UserValidator

position_regex = re.compile('cn=admins,cn=users,ou=[^,]+,dc=example,dc=org', re.IGNORECASE)#
is_school_admin = True#
roles = ['school_admin']#
classmethod role_groups(schools: List[str]) List[str][source]#

Users with cls.role should be in the corresponding group at each school they are part of. Implemented in subclasses.

class ucsschool.lib.models.validator.GroupAndShareValidator[source]#

Bases: SchoolValidator

attributes = ['name', 'ucsschoolRole']#
classmethod validate(obj: Dict[str, Any]) List[str][source]#
classmethod expected_roles(obj: Dict[str, Any]) List[str][source]#
classmethod school_prefix(name: str, school: str) str | None[source]#

Groups and Shares should have a school prefix in their name, like DEMOSCHOOL-Democlass

class ucsschool.lib.models.validator.SchoolClassValidator[source]#

Bases: GroupAndShareValidator

roles = ['school_class']#
position_regex = re.compile('cn=klassen,cn=schueler,cn=groups,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
class ucsschool.lib.models.validator.WorkGroupValidator[source]#

Bases: GroupAndShareValidator

roles = ['workgroup']#
position_regex = re.compile('cn=schueler,cn=groups,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
class ucsschool.lib.models.validator.ComputerroomValidator[source]#

Bases: GroupAndShareValidator

roles = ['computer_room']#
position_regex = re.compile('cn=raeume,cn=groups,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
class ucsschool.lib.models.validator.WorkGroupShareValidator[source]#

Bases: GroupAndShareValidator

roles = ['workgroup_share']#
position_regex = re.compile('cn=shares,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
class ucsschool.lib.models.validator.ClassShareValidator[source]#

Bases: GroupAndShareValidator

roles = ['school_class_share']#
position_regex = re.compile('cn=klassen,cn=shares,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
class ucsschool.lib.models.validator.MarketplaceShareValidator[source]#

Bases: GroupAndShareValidator

roles = ['marketplace_share']#
position_regex = re.compile('cn=shares,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
dn_regex = re.compile('cn=Marktplatz,cn=shares,ou=[^,]+?,dc=example,dc=org', re.IGNORECASE)#
ucsschool.lib.models.validator.get_class(obj: Dict[str, Any]) Type[SchoolValidator] | None[source]#
ucsschool.lib.models.validator.validate(obj: Dict[str, Any], logger: Logger = None) None[source]#

Objects are validated as dicts and errors are logged to the passed logger. Sensitive data is only logged to /var/log/univention/ucs-school-validation.log