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:
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”.
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…
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…
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.
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.
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):
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: