Skip to content

Commit

Permalink
AudioCodes Temperature: Add new check plugin
Browse files Browse the repository at this point in the history
CMK-20914

Change-Id: Idfeeab5be400919a73bebe9138d3b028efff1ea8
  • Loading branch information
racicLuka committed Jan 22, 2025
1 parent f5c335c commit 9599d56
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 68 deletions.
89 changes: 49 additions & 40 deletions cmk/plugins/audiocodes/agent_based/fru.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from collections.abc import Mapping, Sequence
from collections.abc import Mapping
from dataclasses import dataclass

from cmk.agent_based.v2 import (
Expand All @@ -13,13 +13,13 @@
OIDEnd,
Result,
Service,
SNMPSection,
SimpleSNMPSection,
SNMPTree,
State,
StringTable,
)

from .lib import DETECT_AUDIOCODES
from .lib import data_by_item, DETECT_AUDIOCODES

ACTION_MAPPING = {
"0": ("Invalid action", State.UNKNOWN),
Expand Down Expand Up @@ -59,71 +59,80 @@ class FRUModule:
status: Status


def parse_audiocodes_fru(string_table: Sequence[StringTable]) -> Mapping[str, FRUModule] | None:
if not all(string_table):
def parse_audiocodes_fru(string_table: StringTable) -> Mapping[str, FRUModule] | None:
if not string_table:
return None

name_by_module_index = {module[0]: f"{module[1]} {module[0]}" for module in string_table[0]}
modules_by_index = {
return {
module[0]: FRUModule(
action=Action(*ACTION_MAPPING[module[1]]),
status=Status(*STATUS_MAPPING[module[2]]),
)
for module in string_table[1]
for module in string_table
}

return {
name: module
for module_idx, module in modules_by_index.items()
if (name := name_by_module_index.get(module_idx))
}


snmp_section_audiocodes_fru = SNMPSection(
snmp_section_audiocodes_fru = SimpleSNMPSection(
name="audiocodes_fru",
detect=DETECT_AUDIOCODES,
fetch=[
SNMPTree(
base=".1.3.6.1.2.1.47.1.1.1.1",
oids=[
OIDEnd(),
"2",
],
),
SNMPTree(
base=".1.3.6.1.4.1.5003.9.10.10.4.21.1",
oids=[
OIDEnd(),
"13", # acSysModuleFRUaction
"14", # acSysModuleFRUstatus
],
),
],
fetch=SNMPTree(
base=".1.3.6.1.4.1.5003.9.10.10.4.21.1",
oids=[
OIDEnd(),
"13", # acSysModuleFRUaction
"14", # acSysModuleFRUstatus
],
),
parse_function=parse_audiocodes_fru,
)


def discover_audiocodes_fru(section: Mapping[str, FRUModule]) -> DiscoveryResult:
yield from (Service(item=module_name) for module_name in section)
def discover_audiocodes_fru(
section_audiocodes_module_names: Mapping[str, str] | None,
section_audiocodes_fru: Mapping[str, FRUModule] | None,
) -> DiscoveryResult:
if not section_audiocodes_module_names or not section_audiocodes_fru:
return

yield from (
Service(item=item)
for item in data_by_item(
section_audiocodes_module_names,
section_audiocodes_fru,
)
)


def check_audiocodes_fru(item: str, section: Mapping[str, FRUModule]) -> CheckResult:
if (module := section.get(item)) is None:
def check_audiocodes_fru(
item: str,
section_audiocodes_module_names: Mapping[str, str] | None,
section_audiocodes_fru: Mapping[str, FRUModule] | None,
) -> CheckResult:
if not section_audiocodes_fru or not section_audiocodes_module_names:
return

if (
module_fru := data_by_item(
section_audiocodes_module_names,
section_audiocodes_fru,
).get(item)
) is None:
return

yield Result(
state=module.action.state,
summary=f"Action: {module.action.name}",
state=module_fru.action.state,
summary=f"Action: {module_fru.action.name}",
)
yield Result(
state=module.status.state,
summary=f"Status: {module.status.name}",
state=module_fru.status.state,
summary=f"Status: {module_fru.status.name}",
)


check_plugin_audiocodes_fru = CheckPlugin(
name="audiocodes_fru",
service_name="AudioCodes FRU %s",
sections=["audiocodes_module_names", "audiocodes_fru"],
discovery_function=discover_audiocodes_fru,
check_function=check_audiocodes_fru,
)
16 changes: 16 additions & 0 deletions cmk/plugins/audiocodes/agent_based/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@
# conditions defined in the file COPYING, which is part of this source code package.


from collections.abc import Mapping
from typing import TypeVar

from cmk.agent_based.v2 import contains

DETECT_AUDIOCODES = contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.5003.8.1.1")

T = TypeVar("T")


def data_by_item(
section_audiocodes_module_names: Mapping[str, str],
data_section: Mapping[str, T],
) -> dict[str, T]:
return {
f"{name} {index}": data
for index, data in data_section.items()
if (name := section_audiocodes_module_names.get(index)) is not None
}
36 changes: 36 additions & 0 deletions cmk/plugins/audiocodes/agent_based/module_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from collections.abc import Mapping

from cmk.agent_based.v2 import (
OIDEnd,
SimpleSNMPSection,
SNMPTree,
StringTable,
)

from .lib import DETECT_AUDIOCODES


def parse_module_names(string_table: StringTable) -> Mapping[str, str] | None:
if not string_table:
return None

return {module[0]: module[1] for module in string_table}


snmp_section_audiocodes_module_names = SimpleSNMPSection(
name="audiocodes_module_names",
detect=DETECT_AUDIOCODES,
fetch=SNMPTree(
base=".1.3.6.1.2.1.47.1.1.1.1",
oids=[
OIDEnd(),
"2",
],
),
parse_function=parse_module_names,
)
100 changes: 100 additions & 0 deletions cmk/plugins/audiocodes/agent_based/temperature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from collections.abc import Mapping

from cmk.agent_based.v2 import (
CheckPlugin,
CheckResult,
DiscoveryResult,
OIDEnd,
Result,
Service,
SimpleSNMPSection,
SNMPTree,
State,
StringTable,
)
from cmk.plugins.lib.temperature import check_temperature, TempParamDict

from .lib import data_by_item, DETECT_AUDIOCODES


def parse_audiocodes_temperature(string_table: StringTable) -> Mapping[str, float] | None:
if not string_table:
return None

return {module[0]: float(module[1]) for module in string_table}


snmp_section_audiocodes_temperature = SimpleSNMPSection(
name="audiocodes_temperature",
detect=DETECT_AUDIOCODES,
fetch=SNMPTree(
base=".1.3.6.1.4.1.5003.9.10.10.4.21.1",
oids=[
OIDEnd(),
"11", # acSysModuleTemperature
],
),
parse_function=parse_audiocodes_temperature,
)


def discover_audiocodes_temperature(
section_audiocodes_module_names: Mapping[str, str] | None,
section_audiocodes_temperature: Mapping[str, float] | None,
) -> DiscoveryResult:
if not section_audiocodes_module_names or not section_audiocodes_temperature:
return

yield from (
Service(item=item)
for item in data_by_item(
section_audiocodes_module_names,
section_audiocodes_temperature,
)
)


def check_audiocodes_temperature(
item: str,
params: TempParamDict,
section_audiocodes_module_names: Mapping[str, str] | None,
section_audiocodes_temperature: Mapping[str, float] | None,
) -> CheckResult:
if not section_audiocodes_temperature or not section_audiocodes_module_names:
return

if (
module_temp := data_by_item(
section_audiocodes_module_names,
section_audiocodes_temperature,
).get(item)
) is None:
return

if module_temp == -1:
yield Result(
state=State.OK,
summary="Temperature is not available",
)
return

yield from check_temperature(
reading=module_temp,
params=params,
)


check_plugin_audiocodes_temperature = CheckPlugin(
name="audiocodes_temperature",
service_name="AudioCodes Temperature %s",
sections=["audiocodes_module_names", "audiocodes_temperature"],
discovery_function=discover_audiocodes_temperature,
check_function=check_audiocodes_temperature,
check_default_parameters={},
check_ruleset_name="temperature",
)
10 changes: 10 additions & 0 deletions cmk/plugins/audiocodes/checkman/audiocodes_temperature
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: AudioCodes: Temperature
agents: snmp
catalog: agentless
license: GPLv2
distribution: check_mk
description:
This check monitors the temperature of every module in an AudioCodes device.

discovery:
One service is created for every module.
Loading

0 comments on commit 9599d56

Please sign in to comment.