Zertificon SNMP Check - Failed to process rule

CheckMK Version: CME 2.2.0p9

Hello everyone,

I am currently writing an SNMP check for a Zertificon appliance that monitors the status of the individual products. This is an enforced check because Zertificon does not have its own enterprise branch for SNMP.

The good thing is that the check works. I can search for and set it up via the setup, the service appears on the host and the status mapping also works.

But when I call up the page “Parameter for this Service” via the service, I get the following error message and the page does not load any further.

I cannot find the error here. I think it will be an error in the Wato file, something with the two dictionaries?!

Do you have any idea what the problem could be?

Following the check and the WATO plugin

Check:

#!/usr/bin/env python3usage_crit
# -*- encoding: utf-8; py-indent-offset: 4 -*-

from .agent_based_api.v1 import register, Result, Service, all_of, SNMPTree, State, exists, not_exists

def discover_product_status(section):
    yield Service()

def check_product_status(params, section):

    print("SECTION: ", section)
    print("PARAMS: ", params)

# SECTION:  {'CertServer': {'status': '0'}, 'SecureMail Gateway': {'status': '0'}, 'SecureMail Messenger': {'status': '1'}, 'SecureHub 2.x': {'status': '1'}}
# PARAMS:  Parameters({'CertServer': {'status_error': 2, 'status_ok': 0},
#  'SecureHub 2.x': {'status_error': 2, 'status_ok': 0},
#  'SecureMail Gateway': {'status_error': 2, 'status_ok': 0},
#  'SecureMail Messenger': {'status_error': 2, 'status_ok': 0}})


    certserver_status = int(section["CertServer"]["status"])
    smgw_status = int(section["SecureMail Gateway"]["status"])
    smmsg_status = int(section["SecureMail Messenger"]["status"])
    sechub_status = int(section["SecureHub 2.x"]["status"])


    if certserver_status == 1:
        service_state=State(params['CertServer']['status_error'])
        summary_text="CertServer has an ERROR!"
    elif certserver_status == 0:
        service_state=State(params['CertServer']['status_ok'])
        summary_text="CertServer is OK"
    else:
        service_state=State.UNKNOWN
        summary_text="CertServer has an unknown state"
    yield Result(state=service_state, summary=f"{summary_text}")


    if smgw_status == 1:
        service_state=State(params['SecureMail Gateway']['status_error'])
        summary_text="SecureMail Gateway has an ERROR!"
    elif smgw_status == 0:
        service_state=State(params['SecureMail Gateway']['status_ok'])
        summary_text="SecureMail Gateway is OK"
    else:
        service_state=State.UNKNOWN
        summary_text="SecureMail Gateway has an unknown state"
    yield Result(state=service_state, summary=f"{summary_text}")


    if smmsg_status == 1:
        service_state=State(params['SecureMail Messenger']['status_error'])
        summary_text="SecureMail Messenger has an ERROR!"
    elif smmsg_status == 0:
        service_state=State(params['SecureMail Messenger']['status_ok'])
        summary_text="SecureMail Messenger is OK"
    else:
        service_state=State.UNKNOWN
        summary_text="SecureMail Messenger has an unknown state"
    yield Result(state=service_state, summary=f"{summary_text}")


    if sechub_status == 1:
        service_state=State(params['SecureHub 2.x']['status_error'])
        summary_text="SecureHub 2.x has an ERROR!"
    elif sechub_status == 0:
        service_state=State(params['SecureHub 2.x']['status_ok'])
        summary_text="SecureHub 2.x is OK"
    else:
        service_state=State.UNKNOWN
        summary_text="SecureHub 2.x has an unknown state"
    yield Result(state=service_state, summary=f"{summary_text}")

    return


def parse_product_status(string_table):
    print(string_table)
    parsed = {}
    parsed["CertServer"] = {"status": string_table[0][0]}
    parsed["SecureMail Gateway"] = {"status": string_table[0][1]}
    parsed["SecureMail Messenger"] = {"status": string_table[0][2]}
    parsed["SecureHub 2.x"] = {"status": string_table[0][3]}
    print(parsed)
    return parsed


register.check_plugin(
    name="zertificon_product_status",
    service_name="Status",
    discovery_function=discover_product_status,
    check_function=check_product_status,
    check_default_parameters={},
    check_ruleset_name="zertificon_product_status",
    )

register.snmp_section(
    name = "zertificon_product_status",
    parse_function = parse_product_status,
    # This condition will never match, therefore, zertificon_product_status is only available as an
    # enforced service. This is necessary because Zertificon appliances cannot be decisively
    # identified based on their SNMP data. Hence, no sensible detection condition can be formulated.
    detect=all_of(
        exists(".1.3.6.1.2.1.1.1.0"),
        not_exists(".1.3.6.1.2.1.1.1.0"),
    ),
    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.2021.8.1.100',
        oids = [
            '1', # Z1 CertServer
            '2', # Z1 SecureMail Gateway
            '3', # Z1 SecureMail Messenger
            '16', # Z1 SecureHub 2.x
        ],
    ),
)

Wato Rule:

#!/usr/bin/env python3
# -*- encoding: utf-8; py-indent-offset: 4 -*-

from cmk.gui.i18n import _

from cmk.gui.plugins.wato.utils import (
    ManualCheckParameterRulespec,
    rulespec_registry,
    RulespecGroupEnforcedServicesApplications,
)
from cmk.gui.valuespec import Dictionary, MonitoringState

def _parameter_valuespec_status():
    return Dictionary(
        title=_("Mapping Device States"),
        elements=[
            (product,
                Dictionary(
                    title = _(f"Mapping for {product} status."),
                    elements=[
                        ("status_ok", MonitoringState(title=_("State when device returns OK."), default_value=0)),
                        ("status_error", MonitoringState(title=_("State when device returns ERROR."), default_value=2)),
                    ],
                    optional_keys=False
                )
            )
            for product in [
                "CertServer",
                "SecureMail Gateway",
                "SecureMail Messenger",
                "SecureHub 2.x",
            ]
        ],
        optional_keys=False
    )


rulespec_registry.register(
    ManualCheckParameterRulespec(
        check_group_name="zertificon_product_status",
        group=RulespecGroupEnforcedServicesApplications,
        match_type = "dict",
        #item_spec = _item_valuespec_status,
        parameter_valuespec=_parameter_valuespec_status,
        title=lambda: _("Zertificon Product Status"),
    )
)

If you need more information, feel free to ask.
Many thanks in advance!
Kind regards, Marc

Have you changed your Wato rule during development? Because this error normally means that you have configured a rule with a rule definition that does no longer fit to the current definition. This means you have to delete and recreate this rule or just change it to fit the current definition.
Regarding service discovery: The device does not need to have it’s own enterprise branch. You only need any SNMP value that can be used to identify the device. E.g. you can use some text in oid .1.3.6.1.2.1.1.1.0 to trigger the scan.

Hello Udo,
Thanks for your reply.

I also assumed that the rule was no longer working properly due to the development. So I copied the check and the rule to a fresh new site and I got the same error.

Unfortunately there is no clear identification in this OID or any other OID in the head section. Either it says something about Linux and the distribution that could match on many other (Non-Zertificon) devices or just the hostname that only matches on that one device.
The rule should match for all Zertificon devices. But the enforced rule is entirely fine for my purposes.

just played a little with your code. For me it was working by removing the match_type = "dict", from the rulespec_registry.register(. Not shure why, but it’s the same in the build in Zertificon Mail Queues check.

rulespec_registry.register(
    ManualCheckParameterRulespec(
        check_group_name="zertificon_product_status",
        group=RulespecGroupEnforcedServicesApplications,
        # match_type = "dict",
        # item_spec = _item_valuespec_status,
        parameter_valuespec=_parameter_valuespec_status,
        title=lambda: _("Zertificon Product Status"),
    )
)
1 Like

Hello thl-cmk,

thank you very much, it works by removing the match_type !

But I don’t understand exactly why. The documentation clearly says “The match_type is always 'dict'.” I assumed that it is a mandatory value.

I wish the documentation for the plugin would be a bit better. I hope for version 2.3 :slight_smile:

Thanks for your help!
Kind regards