2.3. Provisioning API#
Deployment — Kubernetes
This page refers to the Nubus for Kubernetes deployment.
This page describes how you, as a software developer, can use the Provisioning API in your consumer to react to changes to directory objects and add custom processing. You find information about authentication, the API schema, available requests and examples. This page addresses software developers who want to receive and process messages from the Provisioning Service in Nubus for Kubernetes to react to them in a consumer component for their software.
The Provisioning API is an HTTP REST API and part of the Provisioning Service in Nubus for Kubernetes. In the Nubus for Kubernetes architecture, you can find it under the term Events and Consumer API. The Provisioning Service notifies interested services about updates to directory objects. It calls these interested services Consumers. It stores the updates as events in queues for each consumer. Before consumers receive notifications from the Provisioning Service, they must register and configure the type of data that they want to retrieve. The consumer decides how to handle the messages and what to do with the data.
The idea behind the Provisioning API is to provide your application with notifications about changes in the Nubus Directory Service. You can provide a Consumer to react to the notifications and process the provided data in the way your application needs.
See also
- Provisioning Service
in Univention Nubus for Kubernetes - Architecture Manual [1] for information about the architecture of the Provisioning Service including the Events and Consumer API with the Consumer Messages HTTP REST API and the Consumer Registration HTTP REST API.
2.3.1. Consumer lifecycle#
This section outlines the common steps of building and deploying any kind of Consumer. It assumes that there is a Nubus installation and a Consumer. A software developer has created the Consumer. An operator runs a Nubus for Kubernetes installation.
- Software developer
The software developer creates the Consumer and delivers an artifact. The software developer uses the programming language and technology stack they prefer. It needs to make HTTP requests and process JSON data. In detail, they use the following steps:
For the development environment, Obtain administrative credentials and Create subscription.
Implement a consumer that follows the Consumer workflow.
The software developer documents the settings that the consumer expects. Such settings include
realm
,topic
, and whether the consumer requires initial pre-population with data through prefill.
- Operator
The operator reads the consumer documentation to learn about the expected settings.
The operator creates a subscription for the consumer in their Nubus for Kubernetes installation. In the subscription, they configure the
realm
,topic
, and initial prefill. The initial prefill provides the consumer with information about directory objects that already exist in the directory at the time when the operator creates the subscription. And they set a password for the consumer.The operator passes the subscription endpoint and the password as the configuration to run the consumer.
After the consumer registration, the Provisioning Service starts serving data to the consumer.
To understand the following content on this page, it’s important to separate the roles of the software developer and the operator:
- Software developer
The software developer builds and documents the consumer, and delivers the consumer artifact. They’re responsible for the behavior of the consumer, which interacts with the Provisioning API to observe changes in a Nubus for Kubernetes installation.
- Operator
The operator of a Nubus for Kubernetes installation installs the consumer. They need to create the subscription for the consumer. They define which data the Provisioning Service sends to the consumer.
This means that the consumer doesn’t create its own subscription. Instead, the developer needs to tell the operator what kind of subscription the consumer needs.
The Provisioning Service intends this separation of roles to ensure that operators retain control of their data, and remain aware of what data is visible to which consumer.
See also
In Univention Nubus for Kubernetes - Architecture Manual [1]:
- Prefill Service
for more information about the Prefill Service.
- Event objects
for more information about the Event objects.
- Event objects flow
for more information about the data flow of Event objects.
2.3.2. Access to Provisioning API endpoint#
Warning
Nubus for Kubernetes doesn’t expose the Provisioning API to the outside of the Kubernetes cluster. The API doesn’t apply any protections such as rate limiting or brute force attack protection.
Don’t expose the API to the public without applying additional protections in front of the ingress, or restricting access to a limited set of remote networks.
Important
If you run consumers outside the cluster, you need to create an ingress that properly maps to the Kubernetes service of the Provisioning API. Documenting such an ingress is beyond the scope of this section.
To make the API temporarily reachable for development purposes on your machine,
you can use kubectl to set up a port forwarding.
Listing 2.29
shows the commands
to set up a port forwarding of the Provisioning API to http://localhost:7777
.
To set the environment variables NAMESPACE_FOR_NUBUS
and RELEASE_NAME
for the command,
use the commands in the listing
Set environment variables for Univention Nubus deployment
in Univention Nubus for Kubernetes - Operation Manual [2].
$ export LOCAL_PORT=7777
$ kubectl \
--namespace "$NAMESPACE_FOR_NUBUS" \
port-forward \
services/"$RELEASE_NAME"-provisioning-api \
$LOCAL_PORT:80
2.3.3. OpenAPI schema#
The Events and Consumer API provides an OpenAPI schema.
- Interactive OpenAPI schema
To open the interactive OpenAPI schema in the web browser, use the endpoint
/docs
.- Example
With the port forwarding setup from Access to Provisioning API endpoint, you can open the interactive OpenAPI schema at
http://localhost:7777/docs
.
- OpenAPI schema definition
To download the OpenAPI schema definition, use the endpoint
/openapi.json
.- Example
With the port forwarding setup from Access to Provisioning API endpoint, you can open the interactive OpenAPI schema at
http://localhost:7777/openapi.json
.
The OpenAPI schema lists the following endpoints. For details, see the referenced sections, or the interactive OpenAPI schema.
POST /v1/messages
The Provisioning Service has the UDM Transformer component. It’s responsible for creating messages with UDM objects that the Provisioning Service transforms to Event objects.
GET /v1/subscriptions
Retrieve a list of created subscriptions. The request needs the administrator credentials. See Obtain administrative credentials.
POST /v1/subscriptions
See Create subscription.
GET /v1/subscriptions/{name}
Retrieve the configuration for the subscription with the name
name
. The request needs the subscription name and subscription password as credentials.DELETE /v1/subscriptions/{name}
Delete the subscription with the name
name
. The request needs the administrator credentials. See Obtain administrative credentials.PATCH /v1/subscriptions/{name}/prefill
The Provisioning Service has the Prefill Service component. It’s responsible for creating the initialization data in form of Event objects for your consumer. The Prefill Service uses this endpoint to update the status for the data initialization.
A software developer needs to interact with the following endpoints in their consumer:
GET /v1/subscriptions/{name}/messages/next
See Query Event object.
PATCH /v1/subscriptions/{name}/messages/next
See Confirm Event object.
See also
In Univention Nubus for Kubernetes - Architecture Manual [1]:
- UDM Transformer
for information about the UDM Transformer.
- Prefill Service
for information about the Prefill Service.
2.3.4. Obtain administrative credentials#
Before operators can interact with the Provisioning API, for example, to manage the subscriptions of their consumers, they have to obtain administrative authentication credentials. Software developers need the credentials during software development of their Consumer. They need these credentials to create a subscription in the Provisioning Service.
This section describes how different roles can retrieve username and password for the administrator user of the Provisioning API.
To retrieve the credentials use the commands in Listing 2.30 and Listing 2.31. To set the environment variables for the commands, use the commands in the listing Set environment variables for Univention Nubus deployment in Univention Nubus for Kubernetes - Operation Manual [2].
$ kubectl \
--namespace "$NAMESPACE_FOR_NUBUS" \
get secret \
nubus-provisioning-api-credentials \
-o json \
| jq -r ".data.ADMIN_USERNAME" \
| base64 -d
$ kubectl \
--namespace "$NAMESPACE_FOR_NUBUS" \
get secret \
nubus-provisioning-api-credentials \
-o json \
| jq -r ".data.ADMIN_PASSWORD" \
| base64 -d
2.3.5. Create subscription#
Before a Consumer of the Provisioning Service can access messages through the API,
an operator must create a subscription to configure realm
, topic
, password
and whether the consumer requires prefill data.
Also, before developing the consumer,
you first have to create a subscription for your consumer.
A subscription creates a queue in the Provisioning Service for an instance of a consumer. The subscription name and the password are the credentials to interact with the subscription through the API. After the Provisioning Service has created the queue, it begins to fill it with event objects. If the request for prefill is true, the Provisioning Service fills the queue with initialization data for the consumer.
To create a subscription, use the following steps:
Ensure that you can reach the Provisioning API from your local client. For more information, see Access to Provisioning API endpoint.
Retrieve the authentication credentials for the administrative user. See Obtain administrative credentials.
Create a text file in JSON format with the configuration of the subscription. For this example, save it with the filename
provisioning-api.json
.Listing 2.32 shows an example for a subscription configuration.
{ "name": "example-consumer", "realms_topics": [ { "realm": "udm", "topic": "users/user" } ], "request_prefill": true, "password": "SoM3-reA1ly_sEc4eT_Pa33morD" }
Submit the subscription configuration to the API, using the command in Listing 2.33.
This API endpoint requires administrator credentials: Set the variable
USERNAME
to the result from Listing 2.30. The curl command asks you to type in the password. Use the result from Listing 2.31.This step creates the subscription ready for use by the consumer.
$ export BASE_URL="http://localhost:7777" $ export USERNAME="admin" $ curl \ -u "$USERNAME" \ --request POST \ "$BASE_URL"/v1/subscriptions \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ --data @provisioning-api.json
The subscription requires the following parameters:
name
A name for the subscription that you can choose freely. However, only use alphanumeric characters, dashes (
-
) and underscores (_
). The consumer uses this name for authentication. The Provisioning Service creates a queue with that name. And subsequent requests to the Provisioning API contain the subscription name in the endpoint URL.Tip
While a consumer can certainly run outside of the Kubernetes cluster, it’s good practice to follow the naming conventions for object names and IDs in Kubernetes.
- Object Names and IDs | Kubernetes
in Kubernetes Documentation [3].
realm
The default realm for the Provisioning Service is
udm
.topic
The topic within the
udm
realm. This can be the name of any UDM module.The example uses the
users/user
module in UDM.password
The password for the subscription. The consumer authenticates using this password.
2.3.6. Consumer workflow#
Before diving into the details of Event objects and the related API endpoints, take a look at the inner mechanism of a typical consumer. It assumes that a subscription exists, giving the consumer access to its queue. This queue contains Event objects in consecutive order. Then, during execution, a Consumer needs to continuously loop over the following steps.
The consumer queries the next Event object with a request to its subscription.
If the queue contains an event, the Provisioning Service responds with the first Event object and metadata.
In case of an empty queue, the request blocks for a predefined time. The Provisioning Service immediately sends any Event object to the consumer that arrives during this time. If no Event object arrives during this time, the Provisioning Service closes the connection, and the consumer is free to reconnect immediately.
The consumer processes the Event object.
The consumer confirms the successful processing of the Event object with a request to its subscription.
If the consumer doesn’t confirm the Event object, for example because it wasn’t able to process it at the time, the Provisioning Service delivers the Event object the next time, when the consumer runs step 1.
The consumer repeats the loop with step 1.
The responses to the request for the next Event object contain the following numbers:
sequence_number
is the sequence of the event object in the queue. Event objects have a consecutive number for each subscription.
num_delivered
is a counter about how often the Provisioning Service delivered the same event object. For each next request, the Provisioning Service increments the counter.
The responses contain the payload in the body
object:
body
The response contains a
body
object. For the realmudm
, thebody
contains the state of the UDM object before and after a change in the keysold
andnew
, respectively. The consumer decides how to process the Event object. Providing both versions of the object gives the consumer most flexibility for how to handle the data.
See also
In Univention Nubus for Kubernetes - Architecture Manual [1]:
- Event objects
for information about Event objects.
- Event objects flow
for information about the data flow of Event objects.
2.3.7. Query Event object#
Before you query an event, make sure that you read Consumer workflow.
- Endpoint:
/v1/subscriptions/{name}/messages/next
- Method:
GET
- Required parameters:
- name:
Name of the subscription
- Optional parameters:
- timeout:
A number for the timeout of the response. Default value is
5
.- pop:
A boolean that controls whether to pop the Event object from the subscription. Default value is
false
.
- Authentication:
- username:
Name of the subscription
- password:
Password of the subscription
The operator configures the credentials when creating the subscription. See Create subscription.
- Successful response:
A successful response looks like the example in Listing 2.34.
{ "publisher_name": "udm-listener", "ts": "2025-03-28T20:16:44.211Z", "realm": "string", "topic": "string", "body": { "old": {}, "new": {} }, "sequence_number": 0, "num_delivered": 0 }
Example for a query of an Event object with curl
To query the next event, use the following steps:
Set the request parameters with environment variables. Run the commands in Listing 2.35. The value for the
BASE_URL
is an example and comes from a port forwarding, see Access to Provisioning API endpoint.$ export BASE_URL="http://localhost:7777" $ export SUBSCRIPTION_NAME="Name of the subscription for your consumer" $ export SUBSCRIPTION_PASSWORD="Password for the subscription"
Query the next Event object with the command in Listing 2.36.
$ curl \ "$BASE_URL"/v1/subscriptions/"$SUBSCRIPTION_NAME"/messages/next \ --user "$SUBSCRIPTION_NAME":"$SUBSCRIPTION_PASSWORD" \ --request GET \ -H "Accept: application/json"
The Provisioning Service responses with data similar to the structure in Listing 2.37. To abbreviate the listing, the
old
andnew
objects in thebody
object don’t contain data.{ "publisher_name": "udm-pre-fill", "ts": "2025-02-26T16:15:22.995242", "realm": "udm", "topic": "users/user", "body": { "old": {}, "new": {} }, "sequence_number": 1, "num_delivered": 1 }
2.3.8. Confirm Event object#
Before you confirm an Event object, make sure that you read Consumer workflow. Confirming an Event object informs the Provisioning Service that the consumer has successfully processed the Event. In turn, the Provisioning Service removes the Event object from the queue and allows the consumer to process the next Event object.
- Endpoint:
/v1/subscriptions/{name}/messages/{seq_num}/status
- Method:
PATCH
- Required parameters:
- name:
The name of the subscription
- seq_num:
The sequence number of the Event object to be confirmed.
- Request body:
Example in Listing 2.38.
{ "status": "ok" }
- Authentication:
- username:
Name of the subscription
- password:
Password of the subscription
The operator configures the credentials when creating the subscription. See Create subscription.
- Successful response:
A successful response looks like the example in Listing 2.39.
"string"
Example for a confirmation of an Event object with curl
To confirm an Event object use the following steps:
Set the request parameters with environment variables. Run the commands in Listing 2.40. The value for the
BASE_URL
is an example and comes from a port forwarding, see Access to Provisioning API endpoint.$ export BASE_URL="http://localhost:7777" $ export SUBSCRIPTION_NAME="Name of the subscription for your consumer" $ export SUBSCRIPTION_PASSWORD="Password for the subscription" $ export EVENT_SEQUENCE_NUMBER="The event's sequence number"
Confirm the even with the command in Listing 2.41.
$ curl \ "$BASE_URL"/v1/subscriptions/"$SUBSCRIPTION_NAME"/messages/"$SEQUENCE_NUMBER"/status \ --user "$SUBSCRIPTION_NAME":"$SUBSCRIPTION_PASSWORD" \ --request PATCH \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"status": "ok"}'
In case of success, the Provisioning Service responses with
null
.
2.3.9. Bundle the consumer as artifact#
How to bundle the consumer as artifact depends on the used programming language, the ecosystem, and the technology. Therefore, a documentation for this step is out of scope of this page.
The recommendation is to bundle the consumer as a container image that receives the necessary configuration for the base URL of the Provisioning API, subscription name, and subscription password as environment variables.
Operators can then choose to run the consumer in a Kubernetes cluster or just as a container somewhere else.