Bakery

The Bakery API is available for writing custom bakery plugins, that can be then used to include functionalities to the agent packages at the Agent Bakery.

In most cases, these are plugins in the form of additional scripts to be executed by the checkmk agent (agent plugin), and their configuration files. However, functionalities can also be implemented that relate to the structure of the package itself, as long as this can be mapped by including files, executing package scriplets (RPM/DEB/Solaris PKG) or specifying Windows agent-specific configuration entries (yaml).

The Bakery API is intended to allow all artifacts to be described using a uniform syntax. It is designed based on the Agent based API.

Not covered by the Bakery API are

  • Definition of the config belonging to the plugin

  • Writing agent plugins or other additional files that are required for the plugin

Quick Guide

We are working on a more thorough documentation for the bakery API, that will soon be available at our official guide. Until then, you can refer to this Quick Guide for a brief introduction.

Bakery plugins are created in the form of a file that is imported as a Python module. Below is a description of how a Bakery plug-in is structured.

Registration

The registration is a function that is called when importing the Bakery Plugin as a module.

The individual components of the Bakery Plugin are passed to the function as arguments. These are the name and appropriate functions, that themselves yield artifacts each of one category.

The following arguments are available:

  • name

  • files_function

  • scriptlets_function

  • windows_config_function

Name

The name of a Bakery plug-in corresponds in meaning to the name of the plug-in that is to be distributed in the Agent Bakery. It must be identical to the name of the corresponding agent ruleset to provide the appropriate config.

Artifacts

The actual components of a plug-in are described using appropriate classes. These can be divided into the following categories:

  • Files: Each file to be deployed with the checkmk agent is described with an object. The file type (e.g. plug-in file, system binary, plug-in configuration file) is described by the class. A separate object must be defined for each operating system on which the file is to be deployed. Files are described completely by their properties and contents (as init arguments). For example, there is no need to specify a full source or destination path, as this is an implementation detail. The current agent configuration is available for the specification of each file.

  • Scriptlets: Represent a scriptlet to be executed by a package manager (RPM/DEB) at a given transaction step. They are described per packaging system (RPM/DEB) and per step (e.g. preinstall, postremove). In addition to the agent configuration, the current agent hash is also available for the specification

  • Windows configurations: Configuration entries (yaml-Config) for the Windows agent are also described using suitable classes.

Functions

As described above, the artifacts are each described inside of functions that correspond to their category. These are generator functions that yield the individual specified artifacts. The order is not important. The individual functions are passed to the registration function with the arguments files_function, scriptlets_function, and windows_config_function

Input Parameters

The functions described above receive one or two parameters as arguments, which can be evaluated to construct and determine the returned artifacts/objects. If the respective parameter is required, it is specified accordingly in the argument list. The following names are available:

  • conf: contains the specific config for this plugin. Available for all three functions.

  • aghash: Contains the hash from the current agent configuration and plug-in files. Since this is only formed from the files to be packaged, it is only available for scriptlets_function and windows_config_function

Example bakery plugin

Let’s consider the following scenario

  • An agent plug-in my_example_plugin is to be deployed with the agent.

  • It is available in 3 versions for Linux, Solaris and Windows, and is to be packaged in the agent packages for these three operating systems as well. (The content of the agent plugins are not subject to the Bakery API - we assume ready-made files in the following). The files are available as my_example_plugin.linux.py, my_example_plugin.solaris.sh and my_example_plugin.vbs. (Python, shell and VB script are only examples of possible files. An agent plug-in can be any file executable on the target system).

  • It should be configurable that the output of the plug-in is cached. That is, it will not be executed again by the agent until the configured time has elapsed.

  • The plug-in can be configured with the variables user and content. The two Unix plugins read this configuration via a configuration file my_example_plugin.conf, the Windows plugin reads the entries my_example_plugin.user and my_example_plugin.content of the Windows Agent Config-yaml. (The access to these resources are to be implemented in the agent plugin itself and are not subject of the Bakery API).

  • For Linux and Solaris there is also a program that we want to deliver - E.g., a small shell-script, with which we can also start our plug-in via command independently from the Checkmk agent: my_example

  • On Linux and Solaris we want to write in the syslog after installing the agent that we have installed my_example as well as write in the syslog after uninstalling the agent that my_example has been uninstalled. (This is not modern and may not make sense, but provides a simple example).

Files

The following files have to be deployed to the Checkmk site in order to realize the above scenario:

  • ~/local/share/check_mk/agents/plugins/my_example_plugin.linux.py: Linux agent plugin

  • ~/local/share/check_mk/agents/plugins/my_example_plugin.solaris.sh: Solaris agent plugin

  • ~/local/share/check_mk/agents/windows/plugins/my_example_plugin.vbs: Windows agent plugin

  • ~/local/share/check_mk/agents/my_example: Linux program/shell script

  • ~/local/share/check_mk/web/plugins/wato/my_example.py: agent ruleset

  • ~/local/lib/python3/cmk/base/cee/plugins/bakery/my_example_plugin.py: bakery plugin

The bakery plugin

The following code is a possible implementation of the bakery plugin, using the bakery API:

#!/usr/bin/env python3

import json
from collections.abc import Iterble
from pathlib import Path
from typing import TypedDict

from .bakery_api.v1 import (
   OS,
   Plugin,
   PluginConfig,
   Scriptlet,
   WindowsConfigEntry,
   DebStep,
   RpmStep,
   SolStep,
   SystemBinary,
   register,
   quote_shell_string,
   FileGenerator,
   ScriptletGenerator,
   WindowsConfigGenerator,
)


class MyExampleConfig(TypedDict, total=False):
   interval: int
   user: str
   content: str


def get_my_example_plugin_files(conf: MyExampleConfig) -> FileGenerator:
   interval = conf.get('interval')

   yield Plugin(
      base_os=OS.LINUX,
      source=Path('my_example_plugin.linux.py'),
      target=Path('my_example_plugin'),
      interval=interval,
   )
   yield Plugin(
      base_os=OS.SOLARIS,
      source=Path('my_example_plugin.solaris.sh'),
      target=Path('my_example_plugin'),
      interval=interval,
   )
   yield Plugin(
      base_os=OS.WINDOWS,
      source=Path('my_example_plugin.vbs'),  # target=source
      interval=interval,
   )

   yield PluginConfig(base_os=OS.LINUX,
                     lines=_get_linux_cfg_lines(conf['user'], conf['content']),
                     target=Path('my_example_plugin.cfg'),
                     include_header=True)
   yield PluginConfig(base_os=OS.SOLARIS,
                     lines=_get_solaris_cfg_lines(conf['user'], conf['content']),
                     target=Path('my_example_plugin.cfg'),
                     include_header=True)

   for base_os in [OS.LINUX, OS.SOLARIS]:
      yield SystemBinary(
            base_os=base_os,
            source=Path('my_example'),
      )


def _get_linux_cfg_lines(user: str, content: str) -> list[str]:
   # Let's assume that our Linux example plug-in uses json as a config format
   config = json.dumps({'user': user, 'content': content})
   return config.split('\n')


def _get_solaris_cfg_lines(user: str, content: str) -> list[str]:
   # To be loaded with 'source' in Solaris shell script
   return [
      f'USER={quote_shell_string(user)}',
      f'CONTENT={quote_shell_string(content)}',
   ]


def get_my_example_scriptlets(conf: MyExampleConfig) -> ScriptletGenerator:
   installed_lines = ['logger -p Checkmk_Agent "Installed my_example"']
   uninstalled_lines = ['logger -p Checkmk_Agent "Uninstalled my_example"']

   yield Scriptlet(step=DebStep.POSTINST, lines=installed_lines)
   yield Scriptlet(step=DebStep.POSTRM, lines=uninstalled_lines)
   yield Scriptlet(step=RpmStep.POST, lines=installed_lines)
   yield Scriptlet(step=RpmStep.POSTUN, lines=uninstalled_lines)
   yield Scriptlet(step=SolStep.POSTINSTALL, lines=installed_lines)
   yield Scriptlet(step=SolStep.POSTREMOVE, lines=uninstalled_lines)


def get_my_example_windows_config(conf: MyExampleConfig) -> WindowsConfigGenerator:
   yield WindowsConfigEntry(path=["my_example_plugin", "user"], content=conf["user"])
   yield WindowsConfigEntry(path=["my_example_plugin", "content"], content=conf["content"])


register.bakery_plugin(
   name="my_example_plugin",
   files_function=get_my_example_plugin_files,
   scriptlets_function=get_my_example_scriptlets,
   windows_config_function=get_my_example_windows_config,
)

Version 1: cmk.base.plugins.bakery.bakery_api.v1

bakery_api.v1

class OS(*values)

Bases: Enum

Describes an operating system in the context of the Bakery API.

LINUX = 'linux'

Describes a Linux target system

SOLARIS = 'solaris'

Describes a Solaris target system

AIX = 'aix'

Describes an AIX target system

WINDOWS = 'windows'

Describes a Windows target system

class DebStep(*values)

Bases: StrEnum

Describes a step in the processing of a DEB package.

PREINST = 'preinst'

Describes a maintainer script, that will be executed before package installation

POSTINST = 'postinst'

Describes a maintainer script, that will be executed right after package installation

PRERM = 'prerm'

Describes a maintainer script, that will be executed right before package uninstallation

POSTRM = 'postrm'

Describes a maintainer script, that will be executed after package uninstallation

class RpmStep(*values)

Bases: StrEnum

Describes a step in the processing of a RPM package.

PRE = 'pre'

Describes a scriptlet, that will be executed before package installation

POST = 'post'

Describes a scriptlet, that will be executed right after package installation

PREUN = 'preun'

Describes a scriptlet, that will be executed right before package uninstallation

POSTUN = 'postun'

Describes a scriptlet, that will be executed right after package uninstallation

PRETRANS = 'pretrans'

Describes a scriptlet, that will be executed before a complete package transaction

POSTTRANS = 'posttrans'

Describes a scriptlet, that will be executed after a complete package transaction

class SolStep(*values)

Bases: StrEnum

Describes a step in the processing of a Solaris PKG package.

PREINSTALL = 'preinstall'

Describes an installation script, that will be executed before package installation

POSTINSTALL = 'postinstall'

Describes an installation script, that will be executed right after package installation

PREREMOVE = 'preremove'

Describes an installation script, that will be executed right before package uninstallation

POSTREMOVE = 'postremove'

Describes an installation script, that will be executed after package uninstallation

class Plugin(*, base_os, source, target=None, interval=None, asynchronous=None, timeout=None, retry_count=None)

Bases: object

File artifact that represents a Checkmk agent plugin

The specified plug-in file will be deployed to the Checkmk agent’s plug-in directory as a callable plugin.

Parameters:
  • base_os (OS) – The target operating system.

  • source (Path) – Path of the plug-in file, relative to the plug-in source directory on the Checkmk site. This usually consists only of the filename.

  • target (Path | None) – Target path, relative to the plug-in directory within the agent’s file tree on the target system. If omitted, the plug-in will be deployed under it’s relative source path/filename.

  • interval (int | None) – Caching interval in seconds. The plug-in will only be executed by the agent after the caching interval is elapsed.

  • asynchronous (bool | None) – Relevant for Windows Agent. Don’t wait for termination of the plugin’s process if True. An existent interval will always result in asynchronous execution.

  • timeout (int | None) – Relevant for Windows Agent. Maximum waiting time for a plug-in to terminate.

  • retry_count (int | None) – Relevant for Windows Agent. Maximum number of retried executions after a failed plug-in execution.

class PluginConfig(*, base_os, lines, target, include_header=False)

Bases: object

File artifact that represents a generated config file for a plugin.

The resulting configuration file will be placed to the agent’s config directory (by default, ‘/etc/check_mk’, configurable in WATO) and is meant to be read by the corresponding plugin. It’s content is unrestricted (apart from the fact that it must be passed as a list of ‘str’s), so it’s up to the consuming plug-in to process it correctly.

Parameters:
  • base_os (OS) – The target operating system.

  • lines (Iterable[str]) – Lines of text that will be printed to the resulting file.

  • target (Path) – Path of the resulting configuration file, relative to the agent’s config directory. This usually consists only of the filename.

  • include_header (bool) –

    If True, the following header will be prepended at the start of the resulting configuration file:

    # Created by Check_MK Agent Bakery.

    # This file is managed via WATO, do not edit manually or you

    # lose your changes next time when you update the agent.

class SystemConfig(*, base_os, lines, target, include_header=False)

Bases: object

File artifact that represents a generated configuration file for the target system.

This is only relevant for UNIX systems.

The resulting configuration file will be placed under ‘/etc’ on the target system. This can be used, for example, to deploy a systemd service or to deploy a config file to a service’s <service>.d directory.

Parameters:
  • base_os (OS) – The target operating system.

  • lines (list[str]) – Lines of text that will be printed to the resulting file.

  • target (Path) – Path of the resulting configuration file, relative to ‘/etc’.

  • include_header (bool) –

    If True, the following header will be prepended at the start of the resulting configuration file:

    # Created by Check_MK Agent Bakery.

    # This file is managed via WATO, do not edit manually or you

    # lose your changes next time when you update the agent.

class SystemBinary(*, base_os, source, target=None)

Bases: object

File artifact that represents a script/program that should be deployed on the hosts.

Under UNIX, the file will be deployed to the binary directory (by default, ‘/usr/bin’, configurable in WATO).

Under Windows, the file will be deployed to the ‘bin’-folder at the agent’s installation directory.

Parameters:
  • base_os (OS) – The target operating system.

  • source (Path) – Path of the file, relative to the agent source directory on the Checkmk site.

  • target (Path | None) – Target path, relative to the binart directory on the target system. If omitted, the plug-in will be deployed under it’s relative source path/filename.

class Scriptlet(*, step, lines)

Bases: object

Represents a ‘Scriptlet’ (RPM), ‘Maintainer script’ (DEB) or ‘Installation script’ (Solaris PKG)

Describes a shell script that should be executed at a specific time during a package transition, i.e. package installation, update, or uninstallation. For a detailed explanation of the meaning and the execution time of the steps/scripts, please refer to the documentation of the three packaging systems.

Parameters:
  • step (DebStep | RpmStep | SolStep) – Takes any Enum of the types ‘RpmStep’, ‘DebStep’, ‘SolStep’, e.g. RpmStep.POST for a scriptlet that should be executed right after package installation.

  • lines (list[str]) – Lines of text that the scriptlet consists of. Don’t add a shebang line - The executing shell depends on the packaging system. Usually, this will be the Bourne shell (sh), so the scriptlets should be compatible to that.

class WindowsConfigEntry(*, path, content)

Bases: object

Config Entry for the Windows Agent yaml file (check_mk.install.yml)

It’s up to the consuming plug-in to read the config entry correctly from the yaml file. However, unlike the approach via PluginConfig, config entries described here will be accessible consistently via the python yaml module.

The logical structure of the yaml tree has up to two levels. It is divided into sections, that are again divided into subsections.

A config entry can be inserted to a section or a subsection.

Parameters:
  • path (list[str]) – The path to the entry consists either of [‘section’, ‘subsection’, ‘name’] or [‘section’, ‘name’], i.e. the resulting list must contain 2 or 3 entries. If the path already exists in the yaml structure, it will be overwritten.

  • content (int | str | bool | dict | list) – The actual content of the config entry. Allowed types are int, str, bool, dict, list. Must not contain any complex data types or custom classes. (Must be serializable with yaml.safe_dump)

class WindowsConfigItems(*, path, content)

Bases: object

List of entries for the Windows Agent yaml file (check_mk.install.yml)

This artifact describes a list of entries that is identified by a path (section,[ subsection,] name). In contrast to a WindowsConfigEntry, the given list will be merged to an already existing list.

Parameters:
  • path (list[str]) – The path to the entry consists either of [‘section’, ‘subsection’, ‘name’] or [‘section’, ‘name’], i.e. the resulting list must contain 2 or 3 entries. If the path already exists in the yaml structure, it will be overwritten.

  • content (list[int | str | bool | dict | list]) – The list that should be added or merged to the given path. Allowed list entries are the same as for WindowsConfigEntry content.

class WindowsGlobalConfigEntry(*, name, content)

Bases: object

Shortcut for WindowsConfigEntry(path=[‘global’, name], content=content)

For details about the ‘global’ section and it’s meaning, please refer to the Windows Agent documentation.

Parameters:
  • name (str) – The name part of the [‘global’,name] path

  • content (int | str | bool | dict | list) – The content, according to the WindowsConfigEntry requirements.

class WindowsSystemConfigEntry(*, name, content)

Bases: object

Shortcut for WindowsConfigEntry(path=[‘system’, name], content=content)

For details about the ‘system’ section and it’s meaning, please refer to the Windows Agent documentation.

Parameters:
  • name (str) – The name part of the [‘global’,name] path

  • content (int | str | bool | dict | list) – The content, according to the WindowsConfigEntry requirements.

quote_shell_string(s)

Quote a string for use in a shell command.

This function is deprecated and is just an alias for shlex.quote. It will remain available in bakery API v1, but may be removed in a future version of the API. It is recommended to use shlex.quote instead.

Return type:

str

bakery_api.v1.register

bakery_plugin(*, name, files_function=None, scriptlets_function=None, windows_config_function=None)

Register a Bakery Plugin (Bakelet) to Checkmk

This registration function accepts a plug-in name (mandatory) and up to three generator functions that may yield different types of artifacts. The generator functions will be called with keyword-arguments ‘conf’ and/or ‘aghash’ while processing the bakery plug-in (Callbacks), thus the specific call depends on the argument names of the provided functions. For keyword-arg ‘conf’, the corresponding WATO configuration will be provided. For keyword-arg ‘aghash’, the configuration hash of the resulting agent package will be provided. Unused arguments can be omitted in the function’s signatures.

Parameters:
  • name (str) – The name of the agent plug-in to be processed. It must be unique, and match the name of the corresponding WATO rule. It may only contain ascii letters (A-Z, a-z), digits (0-9), and underscores (_).

  • files_function (Callable[..., Iterator[Plugin | SystemBinary | PluginConfig | SystemConfig]] | None) – Generator function that yields file artifacts. Allowed function argument is ‘conf’. Yielded artifacts must must be of types ‘Plugin’, ‘PluginConfig’, ‘SystemConfig’, or ‘SystemBinary’.

  • scriptlets_function (Callable[..., Iterator[Scriptlet]] | None) – Generator function that yields scriptlet artifacts. Allowed function arguments are ‘conf’ and ‘aghash’. Yielded artifacts must be of type ‘Scriptlet’.

  • windows_config_function (Callable[..., Iterator[WindowsConfigEntry | WindowsConfigItems | WindowsGlobalConfigEntry | WindowsSystemConfigEntry]] | None) – generator function that yields windows config artifacts. Allowed function arguments are ‘conf’ and ‘aghash’. Yielded artifacts must be of types ‘WindowsConfigEntry’, ‘WindowsGlobalConigEntry’, ‘WindowsSystemConfigEntry’, ‘WindowsConfigItems’, or ‘WindowsPluginConfig’.

Return type:

None

Version 2 (UNSTABLE): cmk.bakery.v2_unstable

Warning

This version of the bakery API is work in progress and not yet stable. It might not even work at all. It is not recommended to use this version in production systems.

However: we do intend to stabilize this API version in the future and release it, so you are encouraged to experiment and give us feedback.

New in this version

This section lists the most important changes you have to be aware of when migrating your plug-in to this API version.

Note that changes are expressed in relation to the API version 1.

Registration is replaced by a discovery approach

This is the main reason for the introduction of this new API version. Plugins are no longer registered during import, but only created and picked up later by the backend. To realize this, we introduced a new class:

BakeryPlugin replacing register.bakery_plugin()

The arguments of these have barely changed (see next paragraph), resulting in easy to automate changes.

To be picked up by the backend, plugins need to be put in the right folder. This is described in the section Plugin location and loading.

Example:

We register the bakery plugin for our ceph integration from the file ~/lib/python3/cmk/plugins/ceph/bakery/ceph.py:

#!/usr/bin/env/python3
...
bakery_plugin_ceph = BakeryPlugin(
    name="ceph",
    parameter_parser=CephConfig.model_validate,
    files_function=get_ceph_files,
)

Changed arguments and validation for bakery plug-ins

We slightly adopted the arguments to the above-mentioned BakeryPlugin class compared to the former registry function. We now favor type annotations over runtime validation. To get slightly easier type annotations, we introduced the parameter_parser argument. It is strongly recommended to use this argument – but if you insist to not use it (maybe for easier migration), you can use the no_op_parser() function.

Changed Plugin and SystemBinary classes

We slightly adopted the arguments to these two artifact types to be slightly more permissive. We allow floats for the number arguments, as this plays more nicely with the values the rulesets provide.

We here also now favor type annotations over runtime validation. Not following the type annotations will result in unspecified behavior.

NOTE: The source argument is now always relative to the plugin families cmk.plugins.<FAMILY>.agent or cmk_addons.plugins.<FAMILY>.agent directory on the Checkmk site. This is a change compared to version 1, where it was relative to the agent source directory.

Removed password_store

We no longer expose the password_store and its (currently not stable) API to the bakery plug-ins. Instead, consumers of a Password form spec element will be passed an instance of a dedicated API class: Secret. Using this, plug-ins can access the secret directly.

class BakeryPlugin(name, parameter_parser, files_function=<function _nothing>, scriptlets_function=<function _nothing>, windows_config_function=<function _nothing>)

Bases: Generic

Defines a bakery plugin

Instances of this class will only be picked up by Checkmk if their names start with bakery_plugin_.

Parameters:
  • name (str) – Bakery plugin name. A valid plugin name must be a non-empty string consisting only of letters A-z, digits and the underscore.

  • parameter_parser (Callable[[Mapping[str, object]], TypeVar(ConfigType)]) – Function that parses the plugin parameters. It will be passed the preprocessed plugin parameters and can return any python object. The parser parameters will be passed to the other functions.

  • files_function (Callable[[TypeVar(ConfigType)], Iterable[Plugin | PluginConfig | SystemBinary | SystemConfig]]) – Function that creates file artifacts. It will be passed the plugins configuration as parsed by the parameters_parser and must create artifacts of types Plugin, PluginConfig, SystemConfig, or SystemBinary.

  • scriptlets_function (Callable[[TypeVar(ConfigType)], Iterable[Scriptlet]]) – Function that creates scriptlet artifacts. It will be passed the plugins configuration as parsed by the parameter_parser and must create artifacts of type Scriptlet.

  • windows_config_function (Callable[[TypeVar(ConfigType)], Iterable[WindowsConfigEntry | WindowsGlobalConfigEntry | WindowsSystemConfigEntry | WindowsConfigItems]]) – Function that creates windows config artifacts. It will be passed the plugins configuration as parsed by the parameter_parser and must create artifacts of types WindowsConfigEntry, WindowsGlobalConfigEntry, WindowsSystemConfigEntry, WindowsConfigItems, or WindowsPluginConfig.

class Secret(revealed: str, source: str, id: str)

Bases: NamedTuple

Represents a configured secret to the bakery plugin

This class aims to reduce the chances of accidentally exposing the secret in crash reports and log messages. However, a bakery plug-in produces configuration files that are deployed to the target system. Therefor the plugin needs access to the actual secret. As a result, we cannot guarantee that bakery plugins will not expose the secret in any way:

Example

This is passed by the backend to the bakery plugin

>>> s = Secret("s3cr3t", "", "")
>>> print(f"This is the secret as string: {s}")
This is the secret as string: 4e738ca5563c06cfd0018299933d58db1dd8bf97f6973dc99bf6cdc64b5550bd
>>> print(f"But we can see the actual value: {s.revealed!r}")
But we can see the actual value: 's3cr3t'

Deviating from what we’d ususally expect from repr, this deliberately does not show the actual value:

>>> s.revealed in repr(s)
False
id: str

Alias for field number 2

revealed: str

Alias for field number 0

source: str

Alias for field number 1

no_op_parser(parameters)

A no-op parser that does nothing and passes the parameters through.

Use this if you insist on not using a parser at all.

Return type:

Mapping[str, object]

class Plugin(*, base_os, source, target=None, interval=None, asynchronous=None, timeout=None, retry_count=None)

Bases: object

File artifact that represents a Checkmk agent plugin

The specified plug-in file will be deployed to the Checkmk agent’s plug-in directory as a callable plugin.

Parameters:
  • base_os (OS) – The target operating system.

  • source (Path) – Path of the plug-in file, relative to the plug-in families cmk.plugins.<FAMILY>.agent or cmk_addons.plugins.<FAMILY>.agent directory on the Checkmk site. This usually consists only of the filename.

  • target (Path | None) – Target path, relative to the plug-in directory within the agent’s file tree on the target system. If omitted, the plug-in will be deployed under it’s relative source path/filename.

  • interval (float | None) – Caching interval in seconds. The plug-in will only be executed by the agent after the caching interval is elapsed.

  • asynchronous (bool | None) – Relevant for Windows Agent. Don’t wait for termination of the plugin’s process if True. An existent interval will always result in asynchronous execution.

  • timeout (float | None) – Relevant for Windows Agent. Maximum waiting time for a plug-in to terminate.

  • retry_count (float | None) – Relevant for Windows Agent. Maximum number of retried executions after a failed plug-in execution.

class SystemBinary(*, base_os, source, target=None)

Bases: object

File artifact that represents a script/program that should be deployed on the hosts.

Under UNIX, the file will be deployed to the binary directory (by default, ‘/usr/bin’, configurable in WATO).

Under Windows, the file will be deployed to the ‘bin’-folder at the agent’s installation directory.

Parameters:
  • base_os (OS) – The target operating system.

  • source (Path) – Path of the file, relative to the plugin families cmk.plugins.<FAMILY>.agent or cmk_addons.plugins.<FAMILY>.agent directory on the Checkmk site.

  • target (Path | None) – Target path, relative to the binary directory on the target system. If omitted, the plug-in will be deployed under it’s relative source path/filename.

class PluginConfig(*, base_os, lines, target, include_header=False)

Bases: object

File artifact that represents a generated config file for a plugin.

The resulting configuration file will be placed to the agent’s config directory (by default, ‘/etc/check_mk’, configurable in WATO) and is meant to be read by the corresponding plugin. It’s content is unrestricted (apart from the fact that it must be passed as a list of ‘str’s), so it’s up to the consuming plug-in to process it correctly.

Parameters:
  • base_os (OS) – The target operating system.

  • lines (Iterable[str]) – Lines of text that will be printed to the resulting file.

  • target (Path) – Path of the resulting configuration file, relative to the agent’s config directory. This usually consists only of the filename.

  • include_header (bool) –

    If True, the following header will be prepended at the start of the resulting configuration file:

    # Created by Check_MK Agent Bakery.

    # This file is managed via WATO, do not edit manually or you

    # lose your changes next time when you update the agent.

class SystemConfig(*, base_os, lines, target, include_header=False)

Bases: object

File artifact that represents a generated configuration file for the target system.

This is only relevant for UNIX systems.

The resulting configuration file will be placed under ‘/etc’ on the target system. This can be used, for example, to deploy a systemd service or to deploy a config file to a service’s <service>.d directory.

Parameters:
  • base_os (OS) – The target operating system.

  • lines (list[str]) – Lines of text that will be printed to the resulting file.

  • target (Path) – Path of the resulting configuration file, relative to ‘/etc’.

  • include_header (bool) –

    If True, the following header will be prepended at the start of the resulting configuration file:

    # Created by Check_MK Agent Bakery.

    # This file is managed via WATO, do not edit manually or you

    # lose your changes next time when you update the agent.

class OS(*values)

Bases: Enum

Describes an operating system in the context of the Bakery API.

LINUX = 'linux'

Describes a Linux target system

SOLARIS = 'solaris'

Describes a Solaris target system

AIX = 'aix'

Describes an AIX target system

WINDOWS = 'windows'

Describes a Windows target system

class DebStep(*values)

Bases: StrEnum

Describes a step in the processing of a DEB package.

PREINST = 'preinst'

Describes a maintainer script, that will be executed before package installation

POSTINST = 'postinst'

Describes a maintainer script, that will be executed right after package installation

PRERM = 'prerm'

Describes a maintainer script, that will be executed right before package uninstallation

POSTRM = 'postrm'

Describes a maintainer script, that will be executed after package uninstallation

class RpmStep(*values)

Bases: StrEnum

Describes a step in the processing of a RPM package.

PRE = 'pre'

Describes a scriptlet, that will be executed before package installation

POST = 'post'

Describes a scriptlet, that will be executed right after package installation

PREUN = 'preun'

Describes a scriptlet, that will be executed right before package uninstallation

POSTUN = 'postun'

Describes a scriptlet, that will be executed right after package uninstallation

PRETRANS = 'pretrans'

Describes a scriptlet, that will be executed before a complete package transaction

POSTTRANS = 'posttrans'

Describes a scriptlet, that will be executed after a complete package transaction

class SolStep(*values)

Bases: StrEnum

Describes a step in the processing of a Solaris PKG package.

PREINSTALL = 'preinstall'

Describes an installation script, that will be executed before package installation

POSTINSTALL = 'postinstall'

Describes an installation script, that will be executed right after package installation

PREREMOVE = 'preremove'

Describes an installation script, that will be executed right before package uninstallation

POSTREMOVE = 'postremove'

Describes an installation script, that will be executed after package uninstallation

class Scriptlet(*, step, lines)

Bases: object

Represents a ‘Scriptlet’ (RPM), ‘Maintainer script’ (DEB) or ‘Installation script’ (Solaris PKG)

Describes a shell script that should be executed at a specific time during a package transition, i.e. package installation, update, or uninstallation. For a detailed explanation of the meaning and the execution time of the steps/scripts, please refer to the documentation of the three packaging systems.

Parameters:
  • step (DebStep | RpmStep | SolStep) – Takes any Enum of the types ‘RpmStep’, ‘DebStep’, ‘SolStep’, e.g. RpmStep.POST for a scriptlet that should be executed right after package installation.

  • lines (list[str]) – Lines of text that the scriptlet consists of. Don’t add a shebang line - The executing shell depends on the packaging system. Usually, this will be the Bourne shell (sh), so the scriptlets should be compatible to that.

class WindowsConfigEntry(*, path, content)

Bases: object

Config Entry for the Windows Agent yaml file (check_mk.install.yml)

It’s up to the consuming plug-in to read the config entry correctly from the yaml file. However, unlike the approach via PluginConfig, config entries described here will be accessible consistently via the python yaml module.

The logical structure of the yaml tree has up to two levels. It is divided into sections, that are again divided into subsections.

A config entry can be inserted to a section or a subsection.

Parameters:
  • path (list[str]) – The path to the entry consists either of [‘section’, ‘subsection’, ‘name’] or [‘section’, ‘name’], i.e. the resulting list must contain 2 or 3 entries. If the path already exists in the yaml structure, it will be overwritten.

  • content (int | str | bool | dict | list) – The actual content of the config entry. Allowed types are int, str, bool, dict, list. Must not contain any complex data types or custom classes. (Must be serializable with yaml.safe_dump)

class WindowsConfigItems(*, path, content)

Bases: object

List of entries for the Windows Agent yaml file (check_mk.install.yml)

This artifact describes a list of entries that is identified by a path (section,[ subsection,] name). In contrast to a WindowsConfigEntry, the given list will be merged to an already existing list.

Parameters:
  • path (list[str]) – The path to the entry consists either of [‘section’, ‘subsection’, ‘name’] or [‘section’, ‘name’], i.e. the resulting list must contain 2 or 3 entries. If the path already exists in the yaml structure, it will be overwritten.

  • content (list[int | str | bool | dict | list]) – The list that should be added or merged to the given path. Allowed list entries are the same as for WindowsConfigEntry content.

class WindowsGlobalConfigEntry(*, name, content)

Bases: object

Shortcut for WindowsConfigEntry(path=[‘global’, name], content=content)

For details about the ‘global’ section and it’s meaning, please refer to the Windows Agent documentation.

Parameters:
  • name (str) – The name part of the [‘global’,name] path

  • content (int | str | bool | dict | list) – The content, according to the WindowsConfigEntry requirements.

class WindowsSystemConfigEntry(*, name, content)

Bases: object

Shortcut for WindowsConfigEntry(path=[‘system’, name], content=content)

For details about the ‘system’ section and it’s meaning, please refer to the Windows Agent documentation.

Parameters:
  • name (str) – The name part of the [‘global’,name] path

  • content (int | str | bool | dict | list) – The content, according to the WindowsConfigEntry requirements.

entry_point_prefixes()

Return the types of plug-ins and their respective prefixes that can be discovered by Checkmk.

These types can be used to create plug-ins that can be discovered by Checkmk. To be discovered, the plug-in must be of one of the types returned by this function and its name must start with the corresponding prefix.

Return type:

Mapping[type[BakeryPlugin], str]

Example:

>>> for plugin_type, prefix in entry_point_prefixes().items():
...     print(f'{prefix}... = {plugin_type.__name__}(...)')
bakery_plugin_... = BakeryPlugin(...)