Notification parameter spec with v2 API (checkmk 2.3)

Hi all

I am currently wrapping my head around the new plugin APIs that got introduced with Checkmk 2.3. So far I have been able to migrate normal check plugins and rulesets without major issues.
Currently, I am trying to migrate a notification plugin - or rather its UI spec - to the new API. Here I am struggling to get Checkmk to detect the UI spec in the notification configuration. I am able to find it in the Service monitoring rules, though.

I currently have:

  • the plugin inside the folder local/share/check_mk/notifications - let us call it notifyme
  • a UI spec in local/lib/python3/cmk_addons/plugins/notifyme/rulesets that gets applied like this:
    rule_spec_notifyme = NotificationParameters(
        name="notifyme",
        title=Title("notifyme notification parameters"),
        topic=Topic.NOTIFICATIONS,
        parameter_form=_notification_valuespec_notifyme,
    )
    

I would have thought this is enough for Checkmk to detect the parameters in the notification configuration. However, all I get is the default “Call with the following parameters”. :slightly_frowning_face:

Has anyone already tried this and could point me in the right direction?

EDIT

I have now employed a workaround to get the desired behaviour. I am using the notification parameter registry to register the valuespec, but first converting it. This looks something like:

# We still need the old style valuespecs for notification configs to work properly
# FIXME / HACK: This NEEDS to be cleaned up one day!
from cmk.gui.valuespec import Dictionary as OldDictionary
from cmk.gui.valuespec import TextAreaUnicode as OldMultilineText
from cmk.gui.valuespec import TextInput as OldString
from cmk.gui.valuespec import ValueSpec
from cmk.gui.wato import notification_parameter_registry, NotificationParameter
from cmk.utils.i18n import _


@notification_parameter_registry.register
class NotificationParameterNotifyme(NotificationParameter):
    @property
    def ident(self) -> str:
        return "notifyme"

    @property
    def spec(self) -> OldDictionary:
        new_style_spec = _notification_valuespec_discord()

        dict_elements = new_style_spec.elements.items()

        def convert_to_old(element: Tuple[str, DictElement]) -> Tuple[str, ValueSpec]:
            name, vs = element
            parameter_form = vs.parameter_form
            parameter_form_inst = type(parameter_form)
            if parameter_form_inst == String:
                conv_vs = OldString(
                    title=_(parameter_form.title._arg), default_value=parameter_form.prefill.value
                )
            elif parameter_form_inst == MultilineText:
                conv_vs = OldMultilineText(
                    title=parameter_form.title._arg,
                    monospaced=parameter_form.monospaced,
                    default_value=parameter_form.prefill.value,
                )

            return name, conv_vs

        dict_elements = list(map(convert_to_old, dict_elements))

        return OldDictionary(
            title=_(rule_spec_discord.title._arg), elements=dict_elements, optional_keys=[]
        )

Of course, this is highly specific to my use-case. The inline convert_to_old function would have to be adapted to the new-style valuespec in case someone else wants to use this.
This hack basically spares me from re-writing the entire spec in old format…

@checkmk Any news on this?

I have the same problem and Checkmk 2.3.0p30+ throw errors because the of the deprecated dictionaries (~/local/share/).

Hi @StefanM !

Just got news that it is being worked on.
I’ll keep you updated on the progress.

Good news!
The fix should be released soon :slight_smile:

Hm… maybe I’m overseeing something, but it does not work for me with 2.4.0p4 / 2.3.0p34 either:

The Notification Script is placed in ./local/share/check_mk/notifications/notifyme:

#!/usr/bin/env bash
# notifyme
# Bulk: no
env | sort > $OMD_ROOT/tmp/notify-debug.out
echo "Debug written to $OMD_ROOT/tmp/notify-debug.out"

The Ruleset Script placed in ./local/lib/python3/cmk_addons/plugins/notifyme/ruleset_notifyme.py

#!/usr/bin/env python3
from cmk.rulesets.v1 import Label, Title
from cmk.rulesets.v1.form_specs import BooleanChoice, DictElement, Dictionary
from cmk.rulesets.v1.rule_specs import Topic, NotificationParameters

def _parameter_notification_form() -> Dictionary:
    return Dictionary(
        title=Title("Test Settings"),
        elements={
            "notifyme_test": DictElement(
                parameter_form=BooleanChoice(
                    label=Label("Test")
                ),
                required=True,
            ),
        }
    )

rule_spec_notifyme = NotificationParameters(
    name="notifyme",
    title=Title("notifyme"),
    topic=Topic.NOTIFICATIONS,
    parameter_form=_parameter_notification_form,
)

I think the new rule_spec should be placed inside ~/local/lib/python3/cmk_addons/plugins/notifyme/rulesets.

facepalm

Thank you…! That was the problem… :roll_eyes:

I hope Checkmk will get rid of all the old pathes soon (and implement and document the new alternatives beforehand). I run into the same problems regularly…

This still does not quite work.

  1. A migrate function does not get called by cmk-update-config. It does not change the rule in notifications.mk. My old ruleset used the old Password valuespec that stored the password in a string. The new Password valuespec has a nested tuple.

  2. The drop down below the notification plugin only displays ??? instead of “Create notification with the following parameters” and the parameters are not shown. I have to select the “Cancel” option first and go back.

Hello Robert,

Unfortunately I can’t help you with the migrate function (I haven’t tested it myself), but the “???” in the settings appear because your dict has no title (and obviously there is no default Title in place):

def _parameter_notification_form() -> Dictionary:
    return Dictionary(
        title=Title("no more ???"),
        elements={
        ...
        },
    )

Thanks. Now the question marks are gone but the parameters still don’t show right away.
Only after changing the dropdown to Cancel and back they are shown but are empty, even on existing rules.

I have this code as migrate function for the Password valuespec:

def _migrate_password(model):
    print(f"migrating password: {model}")
    if isinstance(model, str):
        model = ("password", model)
        print(f"intermediate password: {model}")
    model = cmk.rulesets.v1.form_specs.migrate_to_password(model)
    print(f"migrated password: {model}")
    return model

The output generated in $OMD_ROOT/var/log/apache/error_log is this:

migrating password: testpass
intermediate password: ('password', 'testpass')
migrated password: ('cmk_postprocessed', 'explicit_password', ('throwaway-id', 'testpass'))
migrating password: ('cmk_postprocessed', 'explicit_password', ('uuid2e87c1db-aff5-47a7-aa9f-2b0fa8be1d74', ''))
migrated password: ('cmk_postprocessed', 'explicit_password', ('uuid2e87c1db-aff5-47a7-aa9f-2b0fa8be1d74', ''))

It looks like the migrate function gets called twice, but the second time with an empty password.
The form is empty after the page has been loaded.

No parameter in a notification rule must be “required=True”. This causes the display issues I have seen.