Creating a new server extension

Inmanta server extensions are separate Python packages with their own release cycle that can add additional server slices and Inmanta environment settings to the orchestrator. Server slices are components in the service orchestrator. A slice can be responsible for API endpoints or provide internal services to other slices. The core server extension provides all slices of the core service orchestrator.

The package layout of a server extension

Each Inmanta server extension is defined as a subpackage of the inmanta_ext package. inmanta_ext is a namespace package used by the service orchestrator to discover new extensions. The following directory structure is required for a new extension called new_extension.

inmanta_ext
|
|__ new_extension
|    |__ __init__.py
|    |__ extension.py
  • The __init__.py file can be left empty. This file is only required to indicate that new_extension is a python package.

  • The extension.py file must contain a setup function that registers the necessary server slices to the application context. An example extension.py file is shown below. The parameter <server-slice-instance> should be replaced with an instance of the server slice that belongs to the extension. Multiple server slices can be registered.

  • The extension.py file can contain an optional register_environment_settings function that allows an extension to register extension-specific settings that can be used to customize an Inmanta environment.

# File: extension.py
from inmanta.server.extensions import ApplicationContext
from inmanta import data

def setup(application: ApplicationContext) -> None:
    application.register_slice(<server-slice-instance>)

def register_environment_settings(application: ApplicationContext) -> None:
    application.register_environment_setting(
        data.Setting(
            name="my_environment_setting",
            default=False,
            typ="bool",
            validator=data.convert_boolean,
            doc="Explain what the setting does.",
        )
    )

Tip

Indicate which version of the Inmanta core is compatible with the developed extension by constraining the version of the Inmanta core package to a valid range in the setup.py file of the extension.

Adding server slices to the extension

A server slice is defined by creating a class that extends from inmanta.server.protocol.ServerSlice.

class inmanta.server.protocol.ServerSlice(name: str)[source]

Base class for server extensions offering zero or more api endpoints

Extensions developers should override the lifecycle methods:

To register endpoints that server static content, either use :func:’add_static_handler’ or :func:’add_static_content’ To create endpoints, use the annotation based mechanism

To schedule recurring tasks, use schedule() or self._sched To schedule background tasks, use add_background_task()

get_depended_by() list[str][source]

List of names of slices that must be started after this one.

get_dependencies() list[str][source]

List of names of slices that must be started before this one.

async prestart(server: Server) None[source]

Called by the RestServer host prior to start, can be used to collect references to other server slices Dependencies are not up yet.

async prestop() None[source]

Always called before stop

Stop producing new work: - stop timers - stop listeners - notify shutdown to systems depending on us (like agents)

sets is_stopping to true

But remain functional

All dependencies are up (if present)

async start() None[source]

Start the server slice.

This method blocks until the slice is ready to receive calls

Dependencies are up (if present) prior to invocation of this call

async stop() None[source]

Go down

All dependencies are up (if present)

This method blocks until the slice is down

  • The constructor of the ServerSlice class expects the name of the slice as an argument. This name should have the format "<extension-name>.<server-slice-name>". <extension-name> is the name of the package that contains the extension.py file. <server-slice-name> can be chosen by the developer.

  • The prestart(), start(), prestop(), stop(), get_dependencies() and get_depended_by() methods can be overridden when required.

Enable the extension

By default, no extensions are enabled on the Inmanta server. Extensions can be enabled by specifying them in the server.enabled-extensions option of the Inmanta configuration file. This option accepts a comma-separated list of extensions that should be enabled.

# File: /etc/inmanta/inmanta.d/0-extensions.cfg
[server]
enabled_extensions=new_extension

The Inmanta extension template

A new Inmanta extension can be created via the Inmanta extension template. This is a cookiecutter template to generate the initial Python project for a new Inmanta extension. The documentation regarding this template is available on https://github.com/inmanta/inmanta-extension-template.