Custom SNMP Plugin(s) best practise - Combine into one Script or keep as seperate script

Hi guys,

I successfully got my first CheckMK plugin to work, it’s checking the license status of each license on a Sophos Firewall. Every License type has its own service, which contains the status as well as the time to expiry.

Due to my limited coding experience, I split the checks for each license type into their own file, for better visibility.

At first, I tried doing everything in one script, but just could not get it to work and didn’t know how to properly parse the results so they can be used for each Service that is to be generated. I have to write a check and discovery function for every Service that is to be created, correct?

The Documentation on this unfortunately isn’t as complete as I would wish and I didn’t quite understand how I can register a plugin for each service with the proper name in the %s variable, where does that variable get the name from?

The SNMP output when pulling the whole Licensing branch instead of each sub-branch is a list of two lists, like this:

[[“licensestatus”, “licensestatus”, “licensestatus”, “licensestatus”][“expirydate”, “expirydate”, “expirydate”, “expirydate”]]

Now, does each discovery and check function receive the same input or can I split the data beforehand to only pass what is needed to the functions?

Now, when refactoring something, I’d have to edit every one of those scripts by hand instead of just one script that does everything. What is the best practise here? Is it better to split these or to keep them in one script?

Here’s the code, the only thing that changes between the scripts for license types is the function names, Service name and the last digit of the SNMP base:

#!usr/bin/env python3

from .agent_based_api.v1 import *
from datetime import datetime, timedelta

def parse_sandstorm_license(string_table):
    result = {}
    result["license_status"] = string_table[0][0]
    result["license_expiry"] = string_table[0][1]
    return result

def discovery_sandstorm_license(section):
    yield Service()

def check_sandstorm_license(section):
    possible_states = {
        "1": "Evaluating",
        "2": "Not subscribed",
        "3": "Subscribed",
        "4": "Expired",
        "5": "Deactivated",
    }
    summary_string = possible_states[section["license_status"]]

    if section["license_status"] == "3":
        yield Result(state=State.OK, summary=summary_string)
    else:
        yield Result(state=State.CRIT, summary=summary_string)

    license_expiry = section["license_expiry"]
    license_expiry_date = datetime.strptime(license_expiry, "%b %d %Y")
    time_left = license_expiry_date - datetime.now().replace(microsecond=0)
    summary_string = f"Expires in {time_left.days} days, on {license_expiry_date.date()}"

    if time_left <= timedelta(days=60):
        yield Result(state=State.WARN, summary=summary_string)
    
    else:
        yield Result(state=State.OK, summary=summary_string)

register.snmp_section(
    name = "sandstorm_license",
    parse_function = parse_sandstorm_license,
    detect = all_of(
        startswith(".1.3.6.1.2.1.1.2.0", "sfosXGMIB"),
        startswith(".1.3.6.1.4.1.2604.5.1.1.1.0", "svsophos.flahv.local")
    ),
    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.2604.5.1.5.6',
        oids = [
            '1.0',
            '2.0'
        ],
    )
)

register.check_plugin(
    name = "sophos_sandstorm_license", 
    sections = ["sandstorm_license"],
    service_name = "Sophos Sandstorm License",
    discovery_function = discovery_sandstorm_license,
    check_function = check_sandstorm_license,
)