How I can automate the plugin generation

Hey there!
I need a help with my plugin. I’m a beginner as a plugin developer. My question is how I can automate the plugin generation, because I don’t get to do an automatic plugin genarator. I’m working in Check MK 2.3.0p20 version Raw Edition.

Below is my plugin implementation:

from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    Metric,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable
)

SIZE = 5000
TIME = 30

port_informations = ["ifIndex", "ifDescr", "ifAdminStatus", "ifSpeed", "ifInOctets", "ifOutOctets", "ifInErrors", "ifOutErrors", "ifInDiscards", "ifOutDiscards",
                     "ifInBroadcasts", "ifOutBroadcasts", "ifInMulticasts", "ifOutMulticasts", "ifInUcasts", "ifOutUcasts"]


port_names = ["Huawei-MA5800-V100R022-GPON_UNI 0/1/0", "Huawei-MA5800-V100R022-GPON_UNI 0/1/1", "Huawei-MA5800-V100R022-GPON_UNI 0/1/2",
              "Huawei-MA5800-V100R022-GPON_UNI 0/1/3", "Huawei-MA5800-V100R022-GPON_UNI 0/1/4", "Huawei-MA5800-V100R022-GPON_UNI 0/1/5",
              "Huawei-MA5800-V100R022-GPON_UNI 0/1/6", "Huawei-MA5800-V100R022-GPON_UNI 0/1/7", "Huawei-MA5800-V100R022-GPON_UNI 0/1/8",
              "Huawei-MA5800-V100R022-GPON_UNI 0/1/9", "Huawei-MA5800-V100R022-GPON_UNI 0/1/10", "Huawei-MA5800-V100R022-GPON_UNI 0/1/11",
              "Huawei-MA5800-V100R022-GPON_UNI 0/1/12", "Huawei-MA5800-V100R022-GPON_UNI 0/1/13", "Huawei-MA5800-V100R022-GPON_UNI 0/1/14",
              "Huawei-MA5800-V100R022-GPON_UNI 0/1/15"]


def parse_huawei_olt_gpon_ports(string_table):
    gpon_ports = {}

    for i in range(len(string_table)):
        port_info = {}
        k = 0
        for j in port_informations:
            port_info[j] = string_table[i][k]
            k += 1

        gpon_ports[port_info["ifDescr"]] = port_info

    return gpon_ports


def discover_huawei_olt(section):
    yield Service()
    return


def _ifStatus(ifStatus):

    if ifStatus == '1':
        status = "up"
    elif ifStatus == '2':
        status = "down"
    elif ifStatus == '3':
        status = "testing"
    elif ifStatus == '4':
        status = "unknown"
    elif ifStatus == '5':
        status = "dormant"
    elif ifStatus == '6':
        status = "not present"
    
    return status


def _ifSpeed(ifSpeed):

    if ifSpeed > 1_000_000_000:
        speed = "10 GBit/s"
    elif ifSpeed > 100_000_000:
        speed = "1 GBit/s"
    elif ifSpeed > 10_000_000:
        speed = "100 MBit/s"
    else:
        speed = "10 MBit/s"

    return speed


def _ifOctets(ifOctets):

    if ifOctets > 100_000_000:
        bytes = ifOctets / 1_000_000_000
        result = f"{bytes:.2f} GB/s"
    elif ifOctets > 100_000:
        bytes = ifOctets / 1_000_000
        result = f"{bytes:.2f} MB/s"
    elif ifOctets > 100:
        bytes = ifOctets / 1_000
        result = f"{bytes:.2f} KB/s"
    else:
        bytes = ifOctets
        result = f"{bytes:.2f} B/s"

    return result


def _ifPercBytes(ifOctets, speed):
    
    if speed == "10 GBit/s":
        max = 10_000_000_000
    elif speed == "1 GBit/s":
        max = 1_000_000_000
    elif speed == "100 MBit/s":
        max = 100_000_000
    elif speed == "10 MBit/s":
        max = 10_000_000

    perc = (ifOctets * 100) / max

    if perc == 0:
        result = f"0"
    elif perc < 0.01:
        result = f"<0.01"
    else:
        result = f"{perc:.2f}"

    return result


def _ifErrors(ifErrors, ifOctets):
    
    if ifOctets == 0:
        perc = 0
    else:
        perc = (ifErrors / ifOctets) * 100

    if perc < 0.01:
        result = "0"
    else:
        result = f"{perc:.2f}"

    return result


def check_huawei_olt(params,section):

    for port in section:
        if port == params["port"]:
            gpon = section[port]
            # Informação do Index
            index = gpon["ifIndex"]

            # Informação do Status
            status = _ifStatus(gpon["ifAdminStatus"])
            if status == "up":
                _state=State.OK
            elif status == "down":
                _state=State.CRIT
            else:
                _state=State.WARN

            # Informação da Velocidade
            speed = _ifSpeed(int(gpon["ifSpeed"]))

            # Informação da Entrada
            _input = _ifOctets(int(gpon["ifInOctets"]))
            in_perc = _ifPercBytes(int(gpon["ifInOctets"]), speed)
            yield Metric("Input_Bandwidth", float(_input.split()[0]))

            # Informação da Saída
            _output = _ifOctets(int(gpon["ifOutOctets"]))
            out_perc = _ifPercBytes(int(gpon["ifOutOctets"]), speed)
            yield Metric("Output_Bandwidth", float(_output.split()[0]))
            
            # Informação de Erros - Entrada
            in_errors = _ifErrors(int(gpon["ifInErrors"]), int(gpon["ifInOctets"]))
            yield Metric("Input_Errors", float(in_errors))

            # Informação de Descartes - Entrada
            in_discards = int(gpon["ifInDiscards"]) / TIME
            yield Metric("Input_Discards", float(in_discards))

            # Informação de Multicast - Entrada
            in_multicast = int(gpon["ifInMulticasts"]) / TIME
            yield Metric("Input_Multicast", float(in_multicast))

            # Informação de Broadcast - Entrada
            in_broadcast = int(gpon["ifInBroadcasts"]) / TIME
            yield Metric("Input_Broadcast", float(in_broadcast))

            # Informação de Unicast - Entrada
            in_unicast = int(gpon["ifInUcasts"]) / TIME
            yield Metric("Input_Unicast", float(in_unicast))

            # Informação de Não Unicast - Entrada
            in_nonunicast = in_multicast + in_broadcast

            # Informação de Erros - Saída
            out_errors = _ifErrors(int(gpon["ifOutErrors"]), int(gpon["ifOutOctets"]))
            yield Metric("Output_Errors", float(out_errors))

            # Informação de Descartes - Saída
            out_discards = int(gpon["ifOutDiscards"]) / TIME
            yield Metric("Input_Discards", float(out_discards))

            # Informação de Multicast - Saída
            out_multicast = int(gpon["ifOutMulticasts"]) / TIME
            yield Metric("Output_Multicast", float(out_multicast))

            # Informação de Broadcast - Saída
            out_broadcast = int(gpon["ifOutBroadcasts"]) / TIME
            yield Metric("Output_Broadcast", float(out_broadcast))

            # Informação de Unicast - Saída
            out_unicast = int(gpon["ifOutUcasts"]) / TIME
            yield Metric("Output_Unicast", float(out_unicast))

            # Informação de Não Unicast - Saída
            out_nonunicast = out_multicast + out_broadcast

            yield Result(state=_state,
                         summary=f"[{index}], ({status}), Speed: {speed}, In: {_input} ({in_perc}%), Out: {_output} ({out_perc}%)",
                         details=f"\
                         [{index}]\n\
                         Operational state: {status}\n\
                         Speed: {speed}\n\
                         In: {_input} ({in_perc}%)\n\
                         Out: {_output} ({out_perc}%)\n\
                         Errors in: {in_errors}%\n\
                         Discards in: {in_discards:.2f} packets/s\n\
                         Multicast in: {in_multicast:.2f} packets/s\n\
                         Broadcast in: {in_broadcast:.2f} packets/s\n\
                         Unicast in: {in_unicast:.2f} packets/s\n\
                         Non-unicast in: {in_nonunicast:.2f} packets/s\n\
                         Errors out: {out_errors}%\n\
                         Discards out: {out_discards:.2f} packets/s\n\
                         Multicast out: {out_multicast:.2f} packets/s\n\
                         Broadcast out: {out_broadcast:.2f} packets/s\n\
                         Unicast out: {out_unicast:.2f} packets/s\n\
                         Non-unicast out: {out_nonunicast:.2f} packets/s")


snmp_section_huawei_olt_setup = SimpleSNMPSection(
    name = "huawei_olt_base_config",
    parse_function = parse_huawei_olt_gpon_ports,
    detect = startswith(".1.3.6.1.2.1", ""),
    fetch = SNMPTree(base='.1.3.6.1.2.1',
                     oids=['2.2.1.1', '2.2.1.2', '2.2.1.7', '2.2.1.5', '2.2.1.10', '2.2.1.16',
                           '2.2.1.14', '2.2.1.20', '2.2.1.13', '2.2.1.19', '31.1.1.1.3',
                           '31.1.1.1.5', '31.1.1.1.2', '31.1.1.1.4', '2.2.1.11', '2.2.1.17']),
)


# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/0
# =======================================================================
check_plugin__huawei_olt_gpon_00 = CheckPlugin(
    name = "huawei_olt_gpon_00",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/0",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/0"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/1
# =======================================================================
check_plugin__huawei_olt_gpon_01 = CheckPlugin(
    name = "huawei_olt_gpon_01",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/1",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/1"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/2
# =======================================================================
check_plugin__huawei_olt_gpon_02 = CheckPlugin(
    name = "huawei_olt_gpon_02",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/2",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/2"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/3
# =======================================================================
check_plugin__huawei_olt_gpon_03 = CheckPlugin(
    name = "huawei_olt_gpon_03",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/3",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/3"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/4
# =======================================================================
check_plugin__huawei_olt_gpon_04 = CheckPlugin(
    name = "huawei_olt_gpon_04",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/4",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/4"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/5
# =======================================================================
check_plugin__huawei_olt_gpon_05 = CheckPlugin(
    name = "huawei_olt_gpon_05",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/5",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/5"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/6
# =======================================================================
check_plugin__huawei_olt_gpon_06 = CheckPlugin(
    name = "huawei_olt_gpon_06",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/6",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/6"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/7
# =======================================================================
check_plugin__huawei_olt_gpon_07 = CheckPlugin(
    name = "huawei_olt_gpon_07",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/7",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/7"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/8
# =======================================================================
check_plugin__huawei_olt_gpon_08 = CheckPlugin(
    name = "huawei_olt_gpon_08",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/8",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/8"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/9
# =======================================================================
check_plugin__huawei_olt_gpon_09 = CheckPlugin(
    name = "huawei_olt_gpon_09",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/9",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/9"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/10
# =======================================================================
check_plugin__huawei_olt_gpon_10 = CheckPlugin(
    name = "huawei_olt_gpon_10",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/10",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/10"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/11
# =======================================================================
check_plugin__huawei_olt_gpon_11 = CheckPlugin(
    name = "huawei_olt_gpon_11",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/11",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/11"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/12
# =======================================================================
check_plugin__huawei_olt_gpon_12 = CheckPlugin(
    name = "huawei_olt_gpon_12",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/12",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/12"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/13
# =======================================================================
check_plugin__huawei_olt_gpon_13 = CheckPlugin(
    name = "huawei_olt_gpon_13",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/13",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/13"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/14
# =======================================================================
check_plugin__huawei_olt_gpon_14 = CheckPlugin(
    name = "huawei_olt_gpon_14",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/14",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/14"
    },
)

# =======================================================================
# Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/15
# =======================================================================
check_plugin__huawei_olt_gpon_15 = CheckPlugin(
    name = "huawei_olt_gpon_15",
    sections = [ "huawei_olt_base_config" ],
    service_name = "Interface Huawei-MA5800-V100R022-GPON_UNI 0/1/15",
    discovery_function = discover_huawei_olt,
    check_function = check_huawei_olt,
    check_default_parameters = {
        "port": "Huawei-MA5800-V100R022-GPON_UNI 0/1/15"
    },
)

can you try to explain what you want to achieve? Or what problem you want to solve?

you have shared a lot of code but I can’t match it to your question ^^

Sorry,
My question is, instead of having to specify all the plugin blocks for each of the interfaces (from 0 to 15), is there a way of keeping just a single “check_plugin__” block that can inventory all the necessary interfaces?

in general, you can use each interfaces name as the item and then use %s in the service_name Writing agent-based check plug-ins

Regarding your check - are you sure you have to write your own plugin in this case at all? The OIDs look pretty standard on first sight. Wouldn’t a modification of the “Network interface and switch port discovery” gotten these interfaces as well?

I modified it to discover all the interface options, but for some reason the GPON interface indexes are negative, I don’t know if this has anything to do with not being able to do the inventory

another question, how can I put two variables on the same graph the way I’ve implemented it?

1 Like