Important news regarding Development APIs

Note: Condensed this post to be more like a status page referring to the right resources

Dear Checkmk community, especially the coding fans among you,

Checkmk 2.3.0 introduced New APIs for plugin development

The API documentation can be found within your Checkmk 2.3.0 site under Help → Plugin API references.

You can find implementation examples here:

All plugins and the corresponding rulesets and checks are one place now: cmk/plugins
This is also where you can find all plug-ins which we already migrated, if you are looking for examples.

Enablement:

Timeline:

  • Before 2.0.0: No (properly) documented APIs
  • 2.0.0: Introduction Agent-based API v1, Bakery API v1 and Dynamic configuration connector plug-in API v1
  • 2.3.0: Introduction of Rulesets API v1, Graphing API v1, Server side calls API v1, Agent-based API v2
  • 2.4.0: Migration of remaining active checks/special agents and graphing
11 Likes

You mean it’s now possible to pip install cmk and start the development ? :upside_down_face: :face_with_peeking_eye: :wink:

1 Like

That is what is intended in the end, if i understood our meeting at the PartnerDay correctly.
If it could be done with pip directly from pypi or from a file is another topic i think.

The idea is that you only need the packages cmk-graphing , cmk-rulesets , cmk-server-side-calls and cmk-agent-based in the future for developing monitoring plug-ins.
However, we can not promise yet that this will work.

2 Likes

The API development is coming to a finish soon.
Please check out the location of migrated plugins to see how stuff now looks like.

1 Like

A post was split to a new topic: Issues with apcaccess

The werk describing the changes has now been released:

We are planning a community call / developer hour as well to ask questions during the 2.3 beta phase. More details will follow.

7 Likes

I added where to find the API documentation incl. some screenshots in the original post

1 Like

Will this all also apply to notification plugins? At the top it states ‘Maybe’ so this is unclear to me

Hi Tom,
There is no comparable API for the development of notification plugins themselves, but you can use the ruleset API to create NotificationParameters, i.e. the ruleset to configure them.

2 Likes

Hi,

I was playing with new CheckParameters-API.

When adding a discovered Parameter (

yield Service(parameters={"x":..}

) to the plugins I got an error in the “Parameters of this service”-view because
of the additional/unknown parameter “x”.

Later I found out if I add an element “x” with DictElement.render_only=true
to my CheckParameter-ruleset, the error vanished.

I wonder if this is the intended/correct way to handle things in the future?

Thanks + Best regards
Micha

1 Like

Hi Micha!

DL;DR: Yes, exactly.

This has been a problem “forever”. The rulespec is not only used to render the values configured by the user, but also to render the “effective parameters for this service” (which may include discovered parameters) and the discovered parameters themselves (during discovery).

If some of the discovered parameters are not known to the rulespec, the error you described will occur.
Often plugin developers don’t enable the “Parameters for this service”-view, and so this problem goes by unnoticed.

In the past there where only two solutions to this problem: Either just add the key to “ignored_keys” or implement it as “regular” part of the rulespec. In the former case you don’t get nice rendering, in the latter you make the value user configurable, which might not make sense (but keep the enforced service rule in mind!).

This is one of the intended use-cases of the render_only attribute.

Thanks for your feedback! (We’re also looking into some other issues you’ve raised.)

1 Like

Hi Moritz,

thanks for the clarification.
So is using the ignored_keys (which ist now called ignored_fields) also still a valid option to handle this?

Thanks,
Micha

ignored_elements? Yes, that is another option. But I (personally) would prefer “render only”. It’s more transparent.

Hi Moritz,

yes, I also like the “render_only” more.
(also couldn’t get the “ignored_elements” to work, I will file a bug :-))

Best regards,
Micha

Wait for b6! Could be this.
EDIT: You where quicker … :slight_smile:

1 Like

While you can now find quite a lot of migrated things already in checkmk/cmk/plugins at master · Checkmk/checkmk · GitHub - you can not find there anything regarding agent bakery stuff as this is part of our Checkmk Enterprise code base.

For agent plugin configs, please find thus here an example:

.../rulesets/_agent_plugin_config.py

# Copyright (C) 2019 Checkmk GmbH - License: Checkmk Enterprise License
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.


from collections.abc import Mapping

from cmk.rulesets.v1 import Help, Title
from cmk.rulesets.v1.form_specs import (
    CascadingSingleChoice,
    CascadingSingleChoiceElement,
    DefaultValue,
    DictElement,
    Dictionary,
    FixedValue,
    Password,
    String,
    TimeMagnitude,
    TimeSpan,
    validators,
)
from cmk.rulesets.v1.rule_specs import AgentConfig, Topic


def _migrate(value: object) -> Mapping[str, object]:
    if isinstance(value, dict) and "user" in value:
        iv = value.get("interval")
        return {
            "deployment": ("cached", None) if not iv else ("sync", float(iv - iv % 60.0)),
            "auth": {
                "user": value["user"],
                "password": ("cmk_postprocesed", "explicit_password", value["password"]),
            },
        }

    match value:
        case None:
            return {"deployment": ("do_not_deploy", 0.0)}
        case dict():
            return value
    raise ValueError(value)


def _agent_config_mk_tsm() -> Dictionary:
    return Dictionary(
        help_text=Help(
            "This will deploy the agent plug-in <tt>mk_tsm</tt>. "
            "It will provide several checks concerning TSM."
        ),
        elements={
            "deployment": DictElement(
                parameter_form=CascadingSingleChoice(
                    title=Title("Deployment type"),
                    elements=(
                        CascadingSingleChoiceElement(
                            name="sync",
                            title=Title("Deploy the TSM plug-in and run it synchronously"),
                            parameter_form=FixedValue(value=None),
                        ),
                        CascadingSingleChoiceElement(
                            name="cached",
                            title=Title("Deploy the TSM plug-in and run it asynchronously"),
                            parameter_form=TimeSpan(
                                displayed_magnitudes=(
                                    TimeMagnitude.HOUR,
                                    TimeMagnitude.MINUTE,
                                )
                            ),
                        ),
                        CascadingSingleChoiceElement(
                            name="do_not_deploy",
                            title=Title("Do not deploy the TSM plug-in"),
                            parameter_form=FixedValue(value=None),
                        ),
                    ),
                    prefill=DefaultValue("sync"),
                ),
            ),
            "auth": DictElement(
                parameter_form=Dictionary(
                    title=Title("Authentication"),
                    elements={
                        "user": DictElement(
                            parameter_form=String(
                                title=Title("Username for login"),
                                custom_validate=(validators.LengthInRange(min_value=1),),
                            ),
                            required=True,
                        ),
                        "password": DictElement(
                            parameter_form=Password(title=Title("Password for login")),
                            required=True,
                        ),
                    },
                ),
            ),
        },
        migrate=_migrate,
    )


rule_spec_tsm_bakelet = AgentConfig(
    name="mk_tsm",
    title=Title("TSM - IBM Tivoli Storage Manager (Linux, Unix)"),
    topic=Topic.STORAGE,
    parameter_form=_agent_config_mk_tsm,
)

1 Like

@martin.hirschvogel That’s a nice example, thanks. What about the other parts of the bakery, the rules for deploying the files (stuff in local/lib/python3/cmk/base/cee/plugins/bakery)? Any examples for those new APIs? And where exactly should the files to distribute be located (the ones currently located in local/share/check_mk/agents/plugins, referenced by the rules in local/lib/python3/cmk/base/cee/plugins/bakery)?

I’ve tried looking through the files in 2.3.0p1.cee, but either I’m too blind to find them or there simply aren’t any fully-converted bakery plugins yet.