7.2. UDM syntax#
Every UDM property has a syntax, which is used to check the value for
correctness. Univention Corporate Server already provides several syntax types, which are defined
in the Python file
/usr/lib/python3/dist-packages/univention/admin/syntax.py
. The following
syntax list is not complete. For a complete overview, consult the file directly.
string
;string64
;OneThirdString
;HalfString
;TwoThirdsString
;FourThirdsString
;OneAndAHalfString
;FiveThirdsString
;TextArea
Different string classes, which are mapped in Univention Management Console to text input widgets with different widths and heights.
string_numbers_letters_dots
;string_numbers_letters_dots_spaces
;IA5string
; …Different string classes with restrictions on the allowed character set.
Upload
;Base64Upload
;jpegPhoto
Binary data.
integer
Positive integers.
boolean
;booleanNone
;TrueFalse
;TrueFalseUpper
;TrueFalseUp
Different boolean types which map to
yes
andno
ortrue
andfalse
.hostName
;DNS_Name
;windowsHostName
;ipv4Address
;ipAddress
;hostOrIP
;v4netmask
;netmask
;IPv4_AddressRange
;IP_AddressRange
; …Different classes for host names or addresses.
unixTime
;TimeString
;iso8601Date
;date
Date and time.
GroupDN
;UserDN
;UserID
;HostDN
;DomainController
;Windows_Server
;UCS_Server
; …Dynamic classes, which do an LDAP search to provide a list of selectable values like users, groups and hosts.
LDAP_Search
,UDM_Objects
,UDM_Attribute
These syntaxes do an LDAP search and display the result as a list. They are further described in UDM LDAP search.
Additional syntax classes can be added by placing a Python file in
/usr/lib/python2.7/dist-packages/univention/admin/syntax.d/
and
/usr/lib/python3/dist-packages/univention/admin/syntax.d/
. They’re
automatically imported by UDM.
7.2.1. UDM syntax override#
Sometimes the predefined syntax is inappropriate in some scenarios. This can be because of performance problems with LDAP searches or the need for more restrictive or lenient value checking. The latter case might require a change to the LDAP schema, since slapd also checks the provided values for correctness.
The syntax of UDM properties can be overwritten by using Univention Configuration Registry Variables. For each
module and each property the variable
directory/manager/web/modules/module/properties/property/syntax
can be set to the name of a syntax class. For example
directory/manager/web/modules/users/user/properties/username/syntax=uid
would restrict the name of users to not contain umlauts.
Since UCR variables only affect the local system, the variables must be set on
all systems were UDM is used. This can be either done through a Univention Configuration Registry policy
or by setting the variable in the .postinst
script of some package,
which is installed on all hosts.
7.2.2. UDM LDAP search#
It is often required to present a list of entries to the user, from which they
can select one or — in case of a multi-valued property — more entries. Several
syntax classes derived from select
provide a fixed list of choices. If the
set of values is known and fixed, it’s best to derive an own class from
select
and provide the Python file in
/usr/lib/python3/dist-packages/univention/admin/syntax.d/
.
If on the other hand the list is dynamic and is stored in LDAP, UDM provides three methods to retrieve the values.
- class UDM_Attribute#
This class does a UDM search. For each object found all values of a multi-valued property are returned.
For a derived class the following class variables can be used to customize the search:
- udm_module#
The name of the UDM module, which does the LDAP search and retrieves the properties.
- udm_filter#
An LDAP search filter which is used by the UDM module to filter the search. The special value
dn
skips the search and directly returns the property of the UDM object specified bydepends
.
- attribute#
The name of a multi-valued UDM property which stores the values to be returned.
- is_complex; key_index; label_index
Some UDM properties consist of multiple parts, so called complex properties. These variables are used to define, which part is displayed as the label and which part is used to reference the entry.
- label_format#
A Python format string, which is used to format the UDM properties to a label string presented to the user.
%(property-name)s
should be used to reference properties. The special property name$attribute$
is replaced by the value of variableattribute
declared above.
- regex#
This defines an optional regular expression, which is used in the front end to check the value for validity.
- static_values#
A list of two-tuples
(value, display-string)
, which are added as additional selection options.
- empty_value#
If set to
True
, the empty value is inserted before all other static and dynamic entries.
- depends#
This variable may contain the name of another property, which this property depends on. This can be used to link two properties. For example, one property can be used to select a server, while the second dependent property then only lists the services provided by that selected host. For the dependent syntax
attribute
must be set todn
.
- error_message#
This error message is shown when the user enters a value which is not in the set of allowed values.
The following example syntax would provide a list of all users with their telephone numbers:
class DelegateTelephonedNumber(UDM_Attribute): udm_module = 'users/user' attribute = 'phone' label_format = '%(displayName)s: %($attribute$)s'
- class UDM_Objects#
This class performs a UDM search returning each object found.
For a derived class the following class variables can be used to customize the search:
- udm_modules#
A List of one or more UDM modules, which do the LDAP search and retrieve the properties.
- key#
A Python format string generating the key value used to identify the selected object. The default is
dn
, which uses the distinguished name of the object.
- label#
A Python format string generating the display label to represent the selected object. The default is
None
, which uses the UDM specificdescription
.dn
can be used to use the distinguished name.
- regex#
This defines an optional regular expression, which is used in the frontend to check the value for validity. By default only valid distinguished names are accepted.
- simple#
By default a widget for selecting multiple entries is used. Setting this variable to
True
changes the widget to a combo-box widget, which only allows to select a single value. This should be in-sync with themultivalue
property of UDM properties.
- use_objects#
By default UDM opens each LDAP object through a UDM module implemented in Python. This can be a performance problem if many entries are returned. Setting this to
False
disables the Python code and directly uses the attributes returned by the LDAP search. Several properties can then no longer be used as key or label, as those are not explicitly stored in LDAP but are only calculated by the UDM module. For example, to get the fully qualified domain name of a host%(name)s.%(domain)s
must be used instead of the calculated property%(fqdn)s
.
- udm_filter; static_values; empty_value; depends; error_message
Same as above with
UDM_Attribute
.
The following example syntax would provide a list of all servers providing a required service:
class MyServers(UDM_Objects): udm_modules = ( 'computers/domaincontroller_master', 'computers/domaincontroller_backup', 'computers/domaincontroller_slave', 'computers/memberserver', ) label = '%(fqdn)s' udm_filter = 'service=MyService'
- class LDAP_Search#
This is the old implementation, which should only be used, if
UDM_Attribute
andUDM_Objects
are not sufficient. In addition to ease of use it has the drawback that Univention Management Console can not do as much caching, which can lead to severe performance problems.LDAP search syntaxes can be declared in two equivalent ways:
- Python API
By implementing a Python class derived from
LDAP_Search
and providing that implementation in/usr/lib/python3/dist-packages/univention/admin/syntax.d/
.- UDM API
By creating a UDM object in LDAP using the module
settings/syntax
.
- class Python_API(LDAP_Search)#
The Python API uses the following variables:
- syntax_name#
This variable stores the common name of the LDAP object, which is used to define the syntax. It is only used internally and should never be needed when creating syntaxes programmatically.
- filter#
An LDAP filter to find the LDAP objects providing the list of choices.
- attribute#
A list of UDM module property definitions like “
shares/share: dn
”. They are used as the human readable label for each element of the choices.
- value#
The UDM module attribute that will be stored to identify the selected element. The value is specified like
shares/share: dn
- viewonly#
If set to
True
the values can not be changed.
- addEmptyValue#
If set to
True
the empty value is add to the list of choices.
- appendEmptyValue#
Same as
addEmptyValue
but added at the end. Used to automatically choose an existing entry in the frontend.
class MyServers(LDAP_Search): def __init__(self): LDAP_Search.__init__(self, filter=('(&(univentionService=MyService)' '(univentionServerRole=member))'), attribute=( 'computers/memberserver: fqdn', ), value='computers/memberserver: dn' ) self.name = 'LDAP_Search' # required workaround
- class LDAP_Search.UDM_API#
The UDM API uses the following properties:
- name#
(required)
The name for the syntax.
- description#
(optional)
Some descriptive text.
- filter#
(required)
An LDAP filter, which is used to find the objects.
- base#
(optional)
The LDAP base, where the search starts.
- attribute#
(optional, multi-valued)
The name of UDM properties, which are display as a label to the user. Alternatively LDAP attribute names may be used directly.
- value#
(optional);
The name of the UDM property, which is used to reference the object. Alternatively an LDAP attribute name may be used directly.
- viewonly#
(optional)
If set to
True
the values can not be changed.
- addEmptyValue#
(optional)
If set to
True
the empty value is add to the list of choices.
$ eval "$(ucr shell)" $ udm settings/syntax create "$@" --ignore_exists \ --position "cn=custom attributes,cn=univention,$ldap_base" \ --set name="MyServers" \ --set filter='(&(univentionService=MyService)(univentionServerRole=member))' \ --set attribute='computers/memberserver: fqdn' \ --set value='computers/memberserver: dn'