3.9. How-to for OX App Suite#
This section provides a how-to for building a packaged integration for OX App Suite as an example. After reading this section, you will know how to use the different plugins described in Packaged integrations to create a packaged integration to connect OX App Suite to Nubus for Kubernetes. The packaged integration for OX App Suite is an example for a rather complex one, because it uses all available plugin types. For a less complex packaged integration that covers only a few plugin types, see How-to for Nextcloud.
This section focuses on the following objectives:
The Portal Service provides a tile that links to the OX App Suite instance.
OX App Suite uses Nubus for Kubernetes as its identity management source. Identity administrators can use Nubus to decide which user accounts or user groups may use OX App Suite.
Provide management capability in the Management UI for the following OX App Suite capabilities:
- Access Profile
OX App Suite provides access profiles to limit access to available modules in OX on a per context or per-user basis. For more information, see the links to the OX documentation later.
- Functional Account
Functional accounts in OX App Suite are secondary mailboxes for roles or teams, such as
info@example.com
orsupport@example.com
. A functional account has user accounts assigned that have access to it. For more information, see the links to the OX documentation later.- OX Context
OX App Suite uses contexts to collect users, groups, and resources for collaboration in a virtual space. Data from one context isn’t visible to other contexts. For more information, see the links to the OX documentation later.
- OX Resources
They’re for management of resources such as rooms or equipment that users can book for appointments. For more information, see the links to the OX documentation later.
The Management UI has additional modules to administer contexts, functional mailboxes, and resources in OX App Suite.
This how-to addresses software developers and describes the steps to create the packaged integration:
Validate that you meet the Prerequisites.
Create the Packaged integration directory structure.
Bundle the plugins in a container image as packaged integration.
Hint
This how-to refers to numerous files that you need to download for the packaged integration. To keep the content of this how-to and files consistent, the links point to a Git repository and the files’ distinct commits.
The last review of this content and the files was on 6. March 2025.
Hint
This how-to shows content of files that you add to the packaged integration, where suitable and where the file content length is suitable for presentation. However, to not exceed the space for presentation, in most cases the listing provide excerpts or sections don’t show the file content at all, when it’s too long.
See also
Here you find links to resource in the documentation of Open-Xchange about OX App Suite that the text mentioned before:
- Open-Xchange module access
for information about available values and their meaning.
- Secondary Mail Accounts
for information about secondary mail accounts, also known as functional accounts in the Nubus context.
- Context management - Open-Xchange
for information about contexts in OX App Suite.
- Resource management - Open-Xchange
for information about resource management in OX App Suite.
3.9.1. Prerequisites#
To go through this how-to a computer is necessary where you can create a directory structure and files. You need the knowledge listed in Audience and required knowledge.
3.9.2. Packaged integration directory structure#
Before you begin, make sure that you meet the prerequisites listed in Prerequisites.
To begin with this how-to, you need to create the directory structure shown in Listing 3.25 on your local computer. During this how-to, you add files to subdirectories in each step. At the end, the structure contains all the files required for the packaged integration.
You can use a different top-level directory name.
However, keep the names of the
docker
and plugins
directories and their subdirectories
for consistency reasons and to keep the bundle step pragmatic.
You can place the directory structure under a version control system to track all the changes over time.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
├── syntax.d
├── udm-data-loader
├── umc-icons
└── umc-modules
Tip
To better get along, you find a description of the expected directory structure after each step in the boxes marked with . Open it to see the updated directory structure.
3.9.3. Prepare the plugins#
Before you continue, make sure that you have completed the steps in Packaged integration directory structure.
The packaged integration for OX App Suite comprises various plugins for Nubus for Kubernetes. This section describes how you create and add these plugins to the directory structure.
Add LDAP schemas for additional data structures in the Directory Service.
Add extended attributes for directory objects related to OX App Suite.
Add LDAP search user so that OX App Suite can access the Directory Service.
Add default OX context and containers for the OX context and containers containing the directory objects.
Add UMC policies for OX App Suite UMC module.
Add tile for Portal Service that points users to OX App Suite.
Add UDM syntax to add syntax definitions for validating user input.
Add UDM hooks to add business logic for user input validation.
Add UDM handlers to define UDM modules with business logic and presentation layout.
Add UMC module to present the UDM modules for OX App Suite in the Management UI.
3.9.3.1. Add LDAP schemas#
An LDAP schema defines the data model in the Directory Service. This plugin type allows extending the data model to store additional information with an object, and even add object classes. For more information, see LDAP schema.
Identity administrators can control which user or user group may access OX App Suite. Operators can then configure OX App Suite to evaluate these attributes. Therefore, the OX App Suite packaged integration provides an LDAP schema to add application specific attributes and object classes to achieve these use cases, and to support the management of the OX App Suite capabilities access profiles, functional accounts, OX context, and OX resources.
Important
The packaged integration for OX App Suite with Nubus relies on this exact LDAP schema to work properly. Don’t modify it.
To add the LDAP schema,
download, and add the following files to the plugins/ldap-schema/
directory
in your packaged integration:
ox.schema: Defines 146 attributes and 15 object classes.
ox-extra.schema: Defines 3 attributes
The ox.schema
LDAP schema is almost 1000 lines long,
making it unsuitable for presentation in this section.
For details, take a look at the previously linked file.
Directory structure with added LDAP schema files
After adding the LDAP schema files, your packaged integration directory structure looks like Listing 3.26.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
├── udm-data-loader
├── umc-icons
└── umc-modules
3.9.3.2. Add extended attributes#
Extended attributes are a feature of UDM that provides a mapping between an input widget and a UDM attribute. You can use the UDM HTTP REST API to configure extended attributes. The UDM data loader plugin automates the process of configuring extended attributes for the OX App Suite packaged integration. For more information about the UDM data loader, see UDM data loader.
The packaged integration for OX App Suite uses extended attributes to store per-user configuration attributes. OX App Suite evaluates and uses these attributes in LDAP search filters, or for mapping them to its properties. When an operator configures OX App Suite to use the directory service in Nubus, they have to provide the search filter strings, as well as names of the attributes that store certain properties. This section mentions attribute names for illustration and to match the default configuration of OX App Suite.
To add the extended attributes,
download, and add the
30-ox-connector.yaml
file to the plugins/udm-data-loader/
directory
in your packaged integration.
The YAML file contains the definition for 78 extended attributes.
Each extended attribute defines a short and a long description
that give you an impression of their purpose.
For all extended attributes,
notice the template variable {{ ldapBaseDn }}
in the position field of each YAML directive.
Nubus for Kubernetes automatically replaces the variable with its respective value
during the installation of the packaged integration.
Tip
The UDM data loader provides a template mechanism and uses Jinja2. You can use the template mechanism to make values for the data loader configurable, for example passwords and other environment specific data. Template variables allow the operator to choose their own values. For more information, see Template variables in the data loader.
Listing all extended attributes here would exceed the scope of this how-to. However, it’s worth to describe the following attributes in detail:
isOxUser
The attribute stores whether a user has access to OX App Suite. Its
default
property has the valueOK
. See Listing 3.27. It means that UDM automatically allows newly created user accounts to access OX App Suite, ifisOxUser
wasn’t set explicitly during user account creation.Note
User accounts that existed before the operator installs the packaged integration, have an undefined value for
isOxUser
. Users with these user accounts don’t have access to OX App Suite until the identity administrator changes the property value explicitly.--- action: create module: settings/extended_attribute position: cn=open-xchange,cn=custom attributes,cn=univention,{{ ldapBaseDn }} properties: name: "isOxUser" default: OK module: [users/user] ldapMapping: isOxUser objectClass: oxUserObject shortDescription: Activate User in OX (unchecking will delete!) longDescription: Activate User in OX (unchecking will delete!) translationShortDescription: de_DE: In Open-Xchange aktivieren (Deaktivieren löscht!) translationLongDescription: de_DE: In Open-Xchange aktivieren (Deaktivieren löscht!) tabName: OX App Suite overwriteTab: valueRequired: false CLIName: isOxUser syntax: OkOrNot tabAdvanced: mayChange: true multivalue: false deleteObjectClass: true tabPosition: 1 overwritePosition: doNotSearch: false hook: oxUserDefaults groupName: Open-Xchange groupPosition: 1
oxContextUser
The attribute stores the OX context where the user account is part of. By default, Nubus places all users inside the same OX context. The default OX context comes from the
{{ oxDefaultContext }}
template variable. It also defines the custom syntaxoxContextSelect
. See Listing 3.28.--- action: create module: settings/extended_attribute position: cn=open-xchange,cn=custom attributes,cn=univention,{{ ldapBaseDn }} properties: name: oxContextUser default: "{{ oxDefaultContext }}" module: [users/user] ldapMapping: oxContextIDNum objectClass: oxUserObject shortDescription: OX context longDescription: OX context, the user will be created in translationShortDescription: de_DE: OX-Kontext translationLongDescription: de_DE: OX-Kontext, in dem der Benutzer angelegt wird tabName: OX App Suite translationTabName: de_DE: OX App Suite overwriteTab: valueRequired: false CLIName: oxContext syntax: oxContextSelect tabAdvanced: mayChange: true multivalue: false deleteObjectClass: false tabPosition: 2 overwritePosition: doNotSearch: true hook: oxContextRW groupName: Open-Xchange groupPosition: 1 disableUDMWeb: false
oxContextResource
The attribute sets the OX context for an OX resource. See Listing 3.29.
Notice the template variable
{{ oxDefaultContext }}
. Note that template variable for announcement to operators.--- action: create module: settings/extended_attribute position: cn=open-xchange,cn=custom attributes,cn=univention,{{ ldapBaseDn }} properties: name: oxContextResource default: "{{ oxDefaultContext }}" module: [oxresources/oxresources] ldapMapping: oxContextIDNum objectClass: oxResourceObject shortDescription: OX context longDescription: OX context, the resource will be created in translationShortDescription: de_DE: OX-Kontext translationLongDescription: de_DE: OX-Kontext, in dem die Resource angelegt wird tabName: OX App Suite translationTabName: de_DE: OX App Suite overwriteTab: valueRequired: false CLIName: oxContext syntax: oxContextSelect tabAdvanced: mayChange: true multivalue: false deleteObjectClass: false tabPosition: 1 overwritePosition: doNotSearch: false hook: oxContextRW disableUDMWeb: false notEditable: false
The extended attributes use various syntax.
Among them are default UDM syntax,
such as emailAddress
, OkOrNot
, and string
.
Furthermore, some extended attributes
use the following custom UDM syntax specific to OX App Suite.
oxaccess
oxContextSelect
oxlanguage
oxtimezone
For more about added custom syntax information, see Add UDM syntax.
Directory structure with added extended attributes
After adding the UDM data loader file that contains the extended attributes, your packaged integration directory structure looks like Listing 3.30.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
├── udm-data-loader
│ └── 30-ox-connector.yaml
├── umc-icons
└── umc-modules
3.9.3.3. Add LDAP search user#
Applications like OX App Suite read the list of user accounts from the Directory Service. OpenLDAP is the Directory Service in Nubus. To access the Directory Service and read directory objects, it’s best practice to use a separate user account for each application. Therefore, the documentation usually refers to this user account with the term LDAP search user.
You need to use the UDM data loader plugin to add the LDAP search user to Nubus. The UDM data loader uses the UDM HTTP REST API to create the directory objects through UDM. For more information about the UDM data loader, see UDM data loader.
To add the LDAP search user,
download, and add the
80-ox-configuration.yaml
file in the plugins/udm-data-loader/
directory.
The UDM data loader creates the LDAP search user in the users/ldap
UDM module.
Unlike the users/user
UDM module
which represents user accounts of people manageable by identity administrators,
the users/ldap
UDM module hides the LDAP search user
from the user account and user group management in the Management UI.
Listing 3.31
shows the relevant excerpt for the LDAP search user.
Notice the template variable oxSystemUserPassword
.
Remember to inform operators about the need to set a value for this variable.
Caution
Don’t hard code the user password for the LDAP search user. The UDM data loader provides a template mechanism and uses Jinja2. Using a template variable allows the operator to choose their own password when installing the packaged integration.
Tip
You can use the template mechanism to also make other values configurable. For more information, see Template variables in the data loader.
# Create system user
action: create
module: users/ldap
position: cn=users,{{ ldapBaseDn }}
properties:
username: "oxSystemUser"
lastname: "LDAP-system-User"
password: {{ oxSystemUserPassword }}
overridePWHistory: true
overridePWLength: true
Directory structure with added LDAP search user
After you added the UDM data loader that contains the LDAP search user, your packaged integration directory structure looks like Listing 3.32.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
└── umc-modules
See also
- Identity Store and Directory Service
in Univention Nubus for Kubernetes - Architecture Manual [1] for information about the architecture of the Identity Store and Directory Service in Nubus for Kubernetes.
3.9.3.4. Add default OX context and containers#
Besides adding extended attributes,
you also need to add the default OX context
and various containers for directory objects
that relate to OX App Suite.
The packaged integration provides its own dedicated UDM modules
for managing these objects,
such as oxmail/oxcontext
.
For additional UDM modules in this packaged integration,
see Add UDM handlers.
The 30-ox-connector.yaml
file,
which you’ve already added to your packaged integration in
Add extended attributes,
adds the necessary directory objects.
Listing 3.33
shows the definition of the default OX context
and uses the {{ oxDefaultContext }}
template variable.
---
# Create default context
action: create
module: oxmail/oxcontext
position: cn=open-xchange,{{ ldapBaseDn }}
properties:
contextid: {{ oxDefaultContext }}
name: "{{ oxDefaultContext }}"
See also
- Context management - Open-Xchange
for information about contexts in OX App Suite.
3.9.3.5. Add access profiles#
OX App Suite uses access profiles to configure permissions
and determine which user account has access to functionality in OX App Suite.
The packaged integration also contains the oxmail/accessprofile
UDM module
for managing such objects.
For additional UDM modules in this packaged integration,
see Add UDM handlers.
The 30-ox-connector.yaml
file defines various access profiles for OX App Suite
which you’ve already added to your packaged integration in
Add extended attributes.
Listing 3.34
shows the Webmail profile as example.
---
action: create
module: oxmail/accessprofile
position: cn=accessprofiles,cn=open-xchange,{{ ldapBaseDn }}
properties:
name: "webmail"
displayName: "Webmail"
contacts: true
webmail: true
collectemailaddresses: true
multiplemailaccounts: true
subscription: true
See also
- Open-Xchange module access
for information about available values and their meaning.
3.9.3.6. Add UMC policies#
Policies describe administrative settings in the directory service. The packaged integration for OX App Suite adds operations for the Management UI. To enable users to use these operations, the packaged integration adds the respective policies.
To properly use the UMC module in the Management UI,
you need to add UMC policies.
You define them as data for the UDM data loader in the YAML format.
download, and add the
33-umc-policies-default-ox.yaml
file
to the plugins/udm-data-loader/
directory.
See the content in
Listing 3.35.
# SPDX-License-Identifier: AGPL-3.0-only
# SPDX-FileCopyrightText: 2023-2025 Univention GmbH
---
action: create
module: policies/umc
position: cn=UMC,cn=policies,{{ ldapBaseDn }}
properties:
name: default-umc-all
allow:
- cn=ox-functional-accounts,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
- cn=ox-resources,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
- cn=ox-context,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
---
action: ensure_list_contains
module: policies/umc
position: cn=default-umc-all,cn=UMC,cn=policies,{{ ldapBaseDn }}
properties:
allow:
- cn=ox-functional-accounts,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
- cn=ox-resources,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
- cn=ox-context,cn=operations,cn=UMC,cn=univention,{{ ldapBaseDn }}
---
action: ensure_list_contains
module: groups/group
position: cn=Domain Admins,cn=groups,{{ ldapBaseDn }}
policies:
policies/umc:
- cn=default-umc-all,cn=UMC,cn=policies,{{ ldapBaseDn }}
Directory structure with added UMC policies
After adding the UDM data loader file that contains the UMC policies, your packaged integration directory structure looks like Listing 3.36.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ ├── 33-umc-policies-default-ox.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
└── umc-modules
3.9.3.7. Add tile for Portal Service#
A portal tile adds a link to OX App Suite on the Portal Service enabling end users to navigate directly to OX App Suite. Adding a portal tile comprises the following actions:
Create a portal tile, define its appearance, behavior, and visibility.
Add the portal tile to a portal category where the Portal Service shows it.
Important
The Portal Service only shows portal tiles that have a reference entry in the portal category.
A portal tile is also a directory object.
To add the portal tile,
you need to use the UDM data loader plugin.
The 80-ox-configuration.yaml
file in the plugins/udm-data-loader/
directory
that you added in
Add LDAP search user,
contains the relevant data for the portal tile.
Listing 3.37
shows an excerpt for such a portal tile definition.
Notice the template variables portalOxLinkBase
and ldapBaseDn
.
Similar to the password for the LDAP Search user in
Add LDAP search user,
the operator must set the value for portalOxLinkBase
upon the installation of the packaged integration.
Remember to inform operators about the template variables.
Nubus for Kubernetes provides the value for ldapBaseDn
by default
so that the operator doesn’t have to set the value for it.
For more information about the template mechanism, see
Template variables in the data loader.
properties.icon
contains the Base64-encoded data of the OX App Suite icon
for the portal tile in SVG format.
---
# Create Ox portal tile for Domain Users
action: create_or_modify
module: portals/entry
position: cn=entry,cn=portals,cn=univention,{{ ldapBaseDn }}
properties:
name: "ox_mail"
icon: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkViZW5lXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNi4xIDI4LjMiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDM2LjEgMjguMzsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiMyODRENzM7fQoJLnN0MXtmaWxsOiMzQzNDM0I7fQoJLnN0MntmaWxsOiNGRkZGRkY7fQoJLnN0M3tmaWxsOiM4Nzg3ODc7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMzMuNSwyNS4xVjkuN2MtMC40LDAuNS0wLjksMC45LTEuNCwxLjNjLTMuNiwyLjgtNi41LDUtOC42LDYuOGMtMC43LDAuNi0xLjIsMS0xLjcsMS4zcy0xLDAuNi0xLjcsMQoJYy0wLjcsMC4zLTEuNCwwLjUtMi4xLDAuNWgwYy0wLjYsMC0xLjMtMC4yLTIuMS0wLjVzLTEuMy0wLjctMS43LTFzLTEtMC44LTEuNy0xLjNjLTIuMS0xLjgtNS00LTguNi02LjhjLTAuNS0wLjQtMS0wLjgtMS40LTEuMwoJdjE1LjVjMCwwLjIsMC4xLDAuMywwLjIsMC41YzAuMSwwLjEsMC4zLDAuMiwwLjUsMC4yaDI5LjZjMC4yLDAsMC4zLTAuMSwwLjUtMC4yQzMzLjQsMjUuNSwzMy41LDI1LjMsMzMuNSwyNS4xeiBNMzMuNSw0VjMuNWwwLTAuMwoJTDMzLjQsM2wtMC4xLTAuMmwtMC4yLTAuMmwtMC4zLTAuMUgzLjJDMywyLjYsMi45LDIuNiwyLjgsMi44UzIuNiwzLDIuNiwzLjJjMCwyLjMsMSw0LjIsMyw1LjdjMi42LDIsNS4zLDQuMiw4LjEsNi40CgljMC4xLDAuMSwwLjMsMC4zLDAuNywwLjZjMC40LDAuMywwLjcsMC42LDAuOSwwLjhjMC4yLDAuMiwwLjUsMC40LDAuOSwwLjZjMC40LDAuMiwwLjcsMC40LDEsMC42UzE3LjgsMTgsMTgsMThoMAoJYzAuMywwLDAuNi0wLjEsMC45LTAuMnMwLjYtMC4zLDEtMC42YzAuNC0wLjIsMC43LTAuNSwwLjktMC42YzAuMi0wLjIsMC41LTAuNCwwLjktMC44czAuNi0wLjUsMC43LTAuNmMyLjgtMi4yLDUuNS00LjMsOC4xLTYuNAoJYzAuNy0wLjYsMS40LTEuNCwyLTIuM0MzMy4yLDUuNiwzMy41LDQuOCwzMy41LDR6IE0zNi4xLDMuMnYyMS45YzAsMC45LTAuMywxLjYtMC45LDIuM3MtMS40LDAuOS0yLjMsMC45SDMuMgoJYy0wLjksMC0xLjYtMC4zLTIuMy0wLjlTMCwyNiwwLDI1LjFWMy4yYzAtMC45LDAuMy0xLjYsMC45LTIuM1MyLjMsMCwzLjIsMGgyOS42YzAuOSwwLDEuNiwwLjMsMi4zLDAuOVMzNi4xLDIuMywzNi4xLDMuMnoiLz4KPC9zdmc+Cg=="
link:
- - en_US
- {{ portalOxLinkBase }}/appsuite/#app=io.ox/mail
allowedGroups:
- 'cn=Domain Users,cn=groups,{{ ldapBaseDn }}'
linkTarget: newwindow
description:
de_DE: E-Mails senden und empfangen
en_US: Send and receive emails
displayName:
de_DE: Open-Xchange
en_US: Open-Xchange
3.9.3.8. Add UDM syntax#
UDM syntax defines rules to verify user input for plausibility and validity. For more information about the UDM syntax, see UDM syntax.
The UDM syntax in this packaged integration defines user input types, for example, to select OX contexts based on available OX contexts in the environment, to select supported languages, and available time zones.
To add the UDM syntax,
download, and add the 50_ox.py
file to the plugins/syntax.d
directory in your packaged integration.
Directory structure with added UDM syntax
After adding the UDM syntax file, your packaged integration directory structure looks like Listing 3.38.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
│ └── 50_ox.py
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ ├── 33-umc-policies-default-ox.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
└── umc-modules
3.9.3.9. Add UDM hooks#
UDM hooks extend existing UDM modules with additional attributes and logic. For more information about the UDM handlers, see UDM hooks.
The packaged integration for OX App Suite uses UDM hooks to validate user input and to make sure that directory objects related to OX App Suite are consistent and plausible. This packaged integration defines the following UDM hooks:
oxAccess
This hook validates that user accounts with permission to use OX App Suite have the needed properties in the correct format, such as email address and anniversary date. If the input values for the user object aren’t valid, it makes sure that the identity administrator receives a proper error message.
oxGroupHook
This UDM hook makes sure that a user group for OX App Suite has an email address that matches any of the configured email domains in Nubus.
oxUserDefaults
This UDM hook sets default values for user accounts that haven’t gone through the OX App Suite user template upon their creation. It uses the default values from the extended attributes for language and timezone, and only sets the default values if the user object already hasn’t the property.
To add the UDM hooks,
download, and add the following files
to the plugins/hooks.d
directory in your packaged integration.
Note
When you look at the repository,
you find the hook oxContextRW.py
.
You don’t need to add it,
because it only works on the command-line for UDM
that’s not available in Nubus for Kubernetes.
Directory structure with added UDM hooks
After adding the UDM hooks files, your packaged integration directory structure looks like Listing 3.39.
ox-packaged-integration
├── docker
└── plugins
├── handlers
├── hooks.d
│ ├── oxAccess.py
│ ├── oxGroupHook.py
│ └── oxUserDefaults.py
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
│ └── 50_ox.py
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ ├── 33-umc-policies-default-ox.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
└── umc-modules
3.9.3.10. Add UDM handlers#
UDM handlers define a custom UDM object as a representation of a directory object. They define the process or business logic, create a mapping to create a UDM object from a directory object, and they control the presentation layout for the Management UI. For more information about the UDM handlers, see UDM handlers.
The packaged integration for OX App Suite adds several LDAP objects through the LDAP schema extension, see Add LDAP schemas. These LDAP objects need a representation and business logic in UDM. The UDM handlers provide the business logic, the mapping, and the presentation layout. The packaged integration includes the following UDM handlers to add management capabilities for the respective OX App Suite entities. For information about the entities, see the introduction to this how-to.
Access Profile
Functional Account
OX Context
OX Resources
To add the UDM handlers,
download, and add the following files in their subdirectories
to the plugins/handlers
directory in your packaged integration:
oxmail
oxresources
Directory structure with added UDM handlers
After adding the UDM handlers files, your packaged integration directory structure looks like Listing 3.40.
ox-packaged-integration
├── docker
└── plugins
├── handlers
│ ├── oxmail
│ │ ├── __init__.py
│ │ ├── accessprofile.py
│ │ ├── functional_account.py
│ │ └── oxcontext.py
│ └── oxresources
│ ├── __init__.py
│ └── oxresources.py
├── hooks.d
│ ├── oxAccess.py
│ ├── oxGroupHook.py
│ └── oxUserDefaults.py
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
│ └── 50_ox.py
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ ├── 33-umc-policies-default-ox.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
└── umc-modules
3.9.3.11. Add UMC module#
So far, the plugins in this packaged integration add a lot of additional data structures and directory objects to the Directory Service. The additional data structures extend existing UDM modules and even add UDM modules. To manage the additional data structures, Nubus for Kubernetes provides the capability to enhance the Management UI through so-called UMC modules. For more information about the UMC module plugin type, see UMC plugins.
This section shows how to add UMC modules to manage the following entities in OX App Suite. For information about the entities, see the introduction to this how-to.
OX Functional Accounts
OX Contexts
OX Resources
To add the UMC module, use the following steps:
Download, and add the following icons to the
plugins/umc-icons/scalable
directory. They provide icons for the UMC modules for the overview page in the Management UI.Download, and add the ox-common.xml file to the
plugins/umc-modules
directory. Listing 3.41 shows the definition of the previously mentioned UMC modules.A
<flavor>
is a property of the UMC module for UDM and references the respective UDM module. For each flavor, the Management UI presents a separate module. Furthermore, it references an icon that the Management UI shows on its overview page.Finally, it provides a name and a description for each module. The Management UI shows the UMC modules on its overview page, grouped along with other modules, in the category
domain
.<umc version="2.0"> <module id="udm" icon="udm/module" version="1.0" translationId="ox-common"> <name></name> <description></description> <flavor icon="udm-mail" id="oxmail/oxcontext"> <name>OX Contexts</name> <description>Managing OX contexts</description> </flavor> <flavor icon="udm-oxmail-functional_account" id="oxmail/functional_account"> <name>OX Functional Accounts</name> <description>Managing OX functional accounts</description> </flavor> <flavor icon="udm-oxresources-oxresources" id="oxresources/oxresources"> <name>OX Resources</name> <description>Managing OX resources</description> </flavor> <categories> <category name="domain"/> </categories> </module> </umc>
Hint
If you don’t see the UMC module on the overview page of the Management UI,
a UCR setting may be responsible for hiding it.
Nubus for Kubernetes version 1.7.0 removes the variable
global.configUcr.umc.module.udm.oxmail.oxcontext.disabled
.
To validate your deployment configuration for such UCR variables,
use the command in Listing 3.42.
For the environment variable values, see
Install Univention Nubus on a Kubernetes cluster
in Univention Nubus for Kubernetes - Operation Manual [2].
$ kubectl describe configmap \
--namespace "$NAMESPACE_FOR_NUBUS" \
"$RELEASE"-stack-data-ums-ucr \
| grep "oxmail"
Directory structure with added UMC modules
After adding the UMC module file that contains the UMC modules definitions, your packaged integration directory structure looks like Listing 3.43.
ox-packaged-integration
├── docker
└── plugins
├── handlers
│ ├── oxmail
│ │ ├── __init__.py
│ │ ├── accessprofile.py
│ │ ├── functional_account.py
│ │ └── oxcontext.py
│ └── oxresources
│ ├── __init__.py
│ └── oxresources.py
├── hooks.d
│ ├── oxAccess.py
│ ├── oxGroupHook.py
│ └── oxUserDefaults.py
├── ldap-schema
│ ├── ox-extra.schema
│ └── ox.schema
├── syntax.d
│ └── 50_ox.py
├── udm-data-loader
│ ├── 30-ox-connector.yaml
│ ├── 33-umc-policies-default-ox.yaml
│ └── 80-ox-configuration.yaml
├── umc-icons
│ ├── udm-oxmail-functional-account.svg
│ └── udm-oxresources-oxresources.svg
└── umc-modules
└── ox-common.xml
3.9.4. Build container image#
After you prepared the plugins for the packaged integration, it’s time to bundle them in a container image. This section follows the steps outlined in Bundle packaged integrations and applies them to the OX App Suite packaged integration.
To bundle the packaged integration, use the following steps:
Create the
Dockerfile
in thedocker/
directory with the content in Listing 3.44.# SPDX-License-Identifier: AGPL-3.0-only # SPDX-FileCopyrightText: 2024 - 2025 Univention GmbH ARG BASE_IMAGE_TAG=3.20 ARG BASE_IMAGE=docker.io/alpine FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG} WORKDIR / # Copy plugins of the packaged integration to the Docker image COPY plugins /plugins # Copy the plugin loader to the Docker image COPY docker/loader.sh /bin/loader # Create system group and system user RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser CMD ["/bin/loader"]
Create the
loader.sh
file for the loader script in thedocker/
directory with the content in Listing 3.45. For information about the loader, see Packaged integration loader.#!/bin/sh # SPDX-License-Identifier: AGPL-3.0-only # SPDX-FileCopyrightText: 2024 - 2025 Univention GmbH set -eu echo "Copying the Nubus plugins into the /target volume" for source in /plugins/*; do plugin_type=$(basename "${source}") target="/target/${plugin_type}" if [ -d "${target}" ]; then echo "COPY - Plugin type ${plugin_type} in /target, copying files." cp -av "${source}" /target else echo "SKIP - Plugin type ${plugin_type} not in /target, skipping." fi done
Directory structure with added UMC modules
Finally, your directory structure looks like Listing 3.46.
ox-packaged-integration ├── docker │ ├── Dockerfile │ └── loader.sh └── plugins ├── handlers │ ├── oxmail │ │ ├── __init__.py │ │ ├── accessprofile.py │ │ ├── functional_account.py │ │ └── oxcontext.py │ └── oxresources │ ├── __init__.py │ └── oxresources.py ├── hooks.d │ ├── oxAccess.py │ ├── oxGroupHook.py │ └── oxUserDefaults.py ├── ldap-schema │ ├── ox-extra.schema │ └── ox.schema ├── syntax.d │ └── 50_ox.py ├── udm-data-loader │ ├── 30-ox-connector.yaml │ ├── 33-umc-policies-default-ox.yaml │ └── 80-ox-configuration.yaml ├── umc-icons │ ├── udm-oxmail-functional-account.svg │ └── udm-oxresources-oxresources.svg └── umc-modules └── ox-common.xml
To build the container image, run the commands shown in Listing 3.47.
$ export IMAGE_NAME="ox" $ cd ox-packaged-integration $ docker build -t "$IMAGE_NAME" -f docker/Dockerfile .
3.9.5. Publish packaged integration#
To make the packaged integration for Nubus for Kubernetes available to operators, you need to publish the container image to a container registry where your intended audience has access to.
To publish your container image, use the commands from the example in Listing 3.48.
$ export REGISTRY="artificts.software-univention.de"
$ export REPOSITORY="nubus/images/ox-packaged-integration"
$ export IMAGE_NAME="ox"
$ export IMAGE_TAG="0.1.0"
$ docker image tag "$IMAGE_NAME" "$REGISTRY"/"$REPOSITORY"/"$IMAGE_NAME":"$IMAGE_TAG"
$ docker image push "$REGISTRY"/"$REPOSITORY"/"$IMAGE_NAME":"$IMAGE_TAG"
The environment variables used in Listing 3.48 need to reflect the host and folder structure of your container registry. An operator later uses them in their Helm values when referring to the container image of the packaged integration. Table 3.3 shows the mapping.
Environment variable |
Description |
Helm Chart key |
---|---|---|
|
FQDN and optional port of your container registry |
|
|
Path to the image on the registry without trailing slash |
|
|
The name of the container image |
|
|
Your version tag or |
|
3.9.6. Announce packaged integration#
You need to tell operators that want to install your packaged integration where they can find the container image, what each template variable is for, and which values each variable accepts. Provide an example. This how-to defines the following template variables that you need to announce:
oxDefaultContext
The operator must define the name for the first and default context in OX App Suite.
oxSystemUserUserPassword
The operator must define a dedicated password for the LDAP search user. They must use the same password in the OX App Suite LDAP configuration for the search user.
portalOxLinkBase
The operator must set the base URL to their OX App Suite instance, for example
https://ox.example.com
.
Tip
You don’t need to announce the ldapBaseDn
template variable,
because Nubus for Kubernetes automatically fills in the value during installation.
For more information, see
Template variables in the data loader.