server_side_calls.v1

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[ActiveCheckConfig[Any]] | type[SpecialAgentConfig[Any]], str]

Example:

>>> for plugin_type, prefix in entry_point_prefixes().items():
...     print(f'{prefix}... = {plugin_type.__name__}(...)')
active_check_... = ActiveCheckConfig(...)
special_agent_... = SpecialAgentConfig(...)
class ActiveCheckConfig(*, name, parameter_parser, commands_function)

Bases: Generic[_ParsedParameters]

Defines an active check

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

One ActiveCheckConfig can create multiple Checkmk services. The executable will be searched for in the following three folders, in order of preference:

  • ../../libexec, relative to the file where the corresponding instance of ActiveCheckConfig is discovered from (see example below)

  • local/lib/nagios/plugins in the sites home directory

  • lib/nagios/plugins in the sites home directory

Parameters:
  • name (str) – Active check name. Has to match active check executable name without the prefix check_.

  • parameter_parser (Callable[[Mapping[str, object]], TypeVar(_ParsedParameters)]) – Translates the raw configured parameters into a validated data structure. The result of the function will be passed as an argument to the command_function. If you don’t want to parse your parameters, use the noop_parser.

  • commands_function (Callable[[TypeVar(_ParsedParameters), HostConfig], Iterable[ActiveCheckCommand]]) – Computes the active check commands from the configured parameters

Example

>>> from cmk.server_side_calls.v1 import noop_parser
>>> def generate_example_commands(
...     params: Mapping[str, object],
...     host_config: HostConfig,
... ) -> Iterable[ActiveCheckCommand]:
...     args = ["--service", str(params["service"])]
...     yield ActiveCheckCommand(
...         service_description="Example description",
...         command_arguments=args
...         )
>>> active_check_example = ActiveCheckConfig(
...     name="norris",
...     parameter_parser=noop_parser,
...     commands_function=generate_example_commands,
... )

If the above code belongs to the family “my_integration” and is put in the file local/lib/python3/cmk_addons/plugins/my_integration/server_side_calls/example.py, the following executables will be searched for:

  • local/lib/python3/cmk_addons/plugins/my_integration/libexec/check_norris

  • local/lib/nagios/plugins/check_norris

  • lib/nagios/plugins/check_norris

The first existing file will be used.

class ActiveCheckCommand(*, service_description, command_arguments)

Bases: object

Defines an active check command

One ActiveCheckCommand results in one Checkmk service.

Command arguments will be shell-escaped during constructing the command line. That means that any string can be safely passed as a command argument.

Parameters:
  • service_description (str) – Description of the created service

  • command_arguments (Sequence[str | Secret]) – Arguments that are passed to the active checks command-line interface

Example

>>> from cmk.server_side_calls.v1 import Secret
>>> ActiveCheckCommand(
...     service_description="Example description",
...     command_arguments=[
...         "--user",
...         "example-user",
...         "--password",
...         Secret(0)
...     ]
... )
ActiveCheckCommand(service_description='Example description', command_arguments=['--user', 'example-user', '--password', Secret(id=0, format='%s', pass_safely=True)])
class EnvProxy(type: Literal['env_proxy'] = 'env_proxy')

Bases: NamedTuple

Surrogate for a HTTP proxy defined in the process environment

Example

>>> proxy = EnvProxy()  # don't create it, it's passed by the backend
>>> if isinstance(proxy, EnvProxy):
...     argv = ["--use-environment-proxy"]
type: Literal['env_proxy']

Alias for field number 0

class HostConfig(*, name, alias='', ipv4_config=None, ipv6_config=None, primary_family=IPAddressFamily.IPV4, macros=None)

Bases: object

Defines a host configuration

This object encapsulates configuration parameters of the Checkmk host the active check or special agent is associated with. It will be created by the backend and passed to the commands_function.

Address config holds the data collected from the host setup configuration. Resolved address can be the same as ipv4_address or ipv6_address from the address config, resolved from the host name or host name if dynamic DNS is configured.

If the IP family is configured as IPv4/IPv6 dual-stack in address config, resolved IP family will be resolved using the Primary IP address family of dual-stack hosts rule.

Resolved address can be None in case No IP has been configured as host’s IP address family or if resolution wasn’t successful.

Parameters:
  • name (str) – Host name

  • alias (str) – Host alias

  • ipv4_config (IPv4Config | None) – The IPv4 network configuration of the host.

  • ipv6_config (IPv6Config | None) – The IPv6 network configuration of the host.

  • primary_family (IPAddressFamily) – Primary IP address family

  • macros (Mapping[str, str] | None) – Macro mapping that are being replaced for the host

Example

>>> from collections.abc import Iterable, Mapping
>>> from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand
>>> def generate_example_commands(
...     params: Mapping[str, object],
...     host_config: HostConfig,
... ) -> Iterable[SpecialAgentCommand]:
...     args = ["--hostname", host_config.name, "--address", host_config.address]
...     yield SpecialAgentCommand(command_arguments=args)
property primary_ip_config: IPConfig

Points to the primary address config

class IPAddressFamily(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

Defines an IP address family

class IPv4Config(*, address, additional_addresses=())

Bases: IPConfig

Defines an IPv4 configuration of the host

class IPv6Config(*, address, additional_addresses=())

Bases: IPConfig

Defines an IPv6 configuration of the host

noop_parser(params)

Parameter parser that doesn’t perform a transformation

Use it if you don’t require parameter transformation in ActiveCheckConfig or SpecialAgentConfig.

Parameters:

params (Mapping[str, object]) – Parameters from the configuration file

Return type:

Mapping[str, object]

Example

>>> from collections.abc import Iterable
>>> from cmk.server_side_calls.v1 import (
...     noop_parser,
...     SpecialAgentCommand,
...     SpecialAgentConfig
... )
>>> def generate_example_commands(
...     params: Mapping[str, object],
...     host_config: HostConfig,
... ) -> Iterable[SpecialAgentCommand]:
...     args = ["--service", str(params["service"])]
...     yield SpecialAgentCommand(command_arguments=args)
>>> special_agent_example = SpecialAgentConfig(
...     name="example",
...     parameter_parser=noop_parser,
...     commands_function=generate_example_commands,
... )
class NoProxy(type: Literal['no_proxy'] = 'no_proxy')

Bases: NamedTuple

Surrogate for a connection without proxy

Example

>>> proxy = NoProxy()  # don't create it, it's passed by the backend
>>> if isinstance(proxy, NoProxy):
...     argv = ["--no-proxy"]
type: Literal['no_proxy']

Alias for field number 0

replace_macros(value, macros)

Replaces host macros in a string

Parameters:
  • value (str) – String in which macros are replaced

  • macros (Mapping[str, str]) – Mapping of host macros names and values. In the plug-ins, host macros are provided through the host_config.macros attribute.

Return type:

str

Example:

>>> ["--hostname", replace_macros("$HOST_NAME$", {"$HOST_NAME$": "Test Host"})]
['--hostname', 'Test Host']
class Secret(id: int, format: str = '%s', pass_safely: bool = True)

Bases: NamedTuple

Surrogate for a secret defined by the user

This is a surrogate for a secret defined in the setup. You, the developer of the plug-in, can use it to define

  • where in the argv list the password will be

  • how it might have to be formatted

  • whether to pass the secret itself, or preferable, only the name of the secret in the password store

If you pass the name of the secret to the special agents / active check, it needs to look up the corresponding secret from the password store using cmk.utils.password_store.lookup(). There is no API for the password store (yet) that provides the desirable stability, so the above might change location and name in the future.

Neither the passord itself nor the name of the password is contained in this object.

Example

>>> my_secret = Secret(42)  # don't create it, it is passed by the backend
>>> # ideally, you just pass the reference for the password store
>>> argv = ["--secret-from-store",  my_secret]
>>> # plug-ins might not support the password store, and have special formatting needs:
>>> argv = ["--basicauth", my_secret.unsafe("user:%s")]
id: int

Alias for field number 0

format: str

Alias for field number 1

pass_safely: bool

Alias for field number 2

unsafe(template='%s')

Returns a new Secret that will be passed along as plain text.

Parameters:

template (str) – The new formatting template

Return type:

Self

Example

If include the the secret like this in the command line:

>>> my_secret = Secret(42)  # don't create it, it is passed by the backend
>>> args = ["--basicauth", my_secret.unsafe("user:%s")]

What the plug-in will receive as argv is [’–basicauth’, ‘user:myS3cret!123’]``

class SpecialAgentCommand(*, command_arguments, stdin=None)

Bases: object

Defines a special agent command

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

One SpecialAgentCommand results in one call of the special agent.

Command arguments will be shell-escaped during constructing the command line. That means that any string can be safely passed as a command argument.

Parameters:
  • command_arguments (Sequence[str | Secret]) – Arguments that are passed to the special agent command-line interface

  • stdin (str | None) – String given to the special agent script’s standard input. This should be used only in case the agent requires input bigger than the max command-line size, otherwise pass the input as a command argument.

Example

>>> SpecialAgentCommand(
...     command_arguments=["--services", "logs", "errors", "stats"]
... )
SpecialAgentCommand(command_arguments=['--services', 'logs', 'errors', 'stats'], stdin=None)
class SpecialAgentConfig(*, name, parameter_parser, commands_function)

Bases: Generic[_ParsedParameters]

Defines a special agent

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

One SpecialAgentConfig can result in multiple calls of the special agent. The executable will be searched for in the following three folders, in order of preference:

  • ../../libexec, relative to the file where the corresponding instance of SpecialAgentConfig is discovered from (see example below)

  • local/share/check_mk/agents/special in the sites home directory

  • share/check_mk/agents/special in the sites home directory

Parameters:
  • name (str) – Special agent name. Has to match special agent executable name without the prefix agent_.

  • parameter_parser (Callable[[Mapping[str, object]], TypeVar(_ParsedParameters)]) – Translates the raw configured parameters into a validated data structure. The result of the function will be passed as an argument to the command_function. If you don’t want to parse your parameters, use the noop_parser.

  • commands_function (Callable[[TypeVar(_ParsedParameters), HostConfig], Iterable[SpecialAgentCommand]]) – Computes the special agent commands from the configured parameters

Example

>>> from pydantic import BaseModel
>>> class ExampleParams(BaseModel):
...     protocol: str
>>> def generate_example_commands(
...     params: ExampleParams,
...     host_config: HostConfig,
... ) -> Iterable[SpecialAgentCommand]:
...     args = ["--protocol", params.protocol, "--services", "logs", "errors", "stats"]
...     yield SpecialAgentCommand(command_arguments=args)
>>> special_agent_example = SpecialAgentConfig(
...     name="smith",
...     parameter_parser=ExampleParams.model_validate,
...     commands_function=generate_example_commands,
... )

If the above code belongs to the family “my_integration” and is put in the file local/lib/python3/cmk_addons/plugins/my_integration/server_side_calls/example.py, the following executables will be searched for:

  • local/lib/python3/cmk_addons/plugins/my_integration/libexec/agent_smith

  • local/share/check_mk/agents/special/agent_smith

  • share/check_mk/agents/special/agent_smith

The first existing file will be used.

class URLProxy(type: Literal['url_proxy'] = 'url_proxy', url: str = '')

Bases: NamedTuple

Surrogate for a HTTP proxy defined by the user

This is a surrogate for a HTTP proxy defined globally or explicitly in the setup.

Example

>>> proxy = URLProxy('proxy.com')  # don't create it, it's passed by the backend
>>> if isinstance(proxy, URLProxy):
...     argv = ["--proxy", proxy.url]
type: Literal['url_proxy']

Alias for field number 0

url: str

Alias for field number 1