Added checks for Avocent ACS800 Devices for checkmk 2.0 and 2.1
This commit is contained in:
parent
2392bc8390
commit
2b522d2553
BIN
check_mk-avocent/cmk20-cmk21/Avocent-1.1.mkp
Normal file
BIN
check_mk-avocent/cmk20-cmk21/Avocent-1.1.mkp
Normal file
Binary file not shown.
@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2019 tribe29 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 typing import List
|
||||||
|
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
|
||||||
|
register,
|
||||||
|
Result,
|
||||||
|
Service,
|
||||||
|
SNMPTree,
|
||||||
|
startswith,
|
||||||
|
State,
|
||||||
|
)
|
||||||
|
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
|
||||||
|
CheckResult,
|
||||||
|
DiscoveryResult,
|
||||||
|
StringTable,
|
||||||
|
)
|
||||||
|
|
||||||
|
Section = []
|
||||||
|
def parse_avocent_psu(string_table: List[StringTable]) -> Section:
|
||||||
|
return string_table[0][0]
|
||||||
|
|
||||||
|
|
||||||
|
register.snmp_section(
|
||||||
|
name="avocent_psu",
|
||||||
|
detect=startswith(".1.3.6.1.2.1.1.1.0", "Avocent"),
|
||||||
|
parse_function=parse_avocent_psu,
|
||||||
|
fetch=[
|
||||||
|
SNMPTree(
|
||||||
|
base=".1.3.6.1.4.1.10418.26.2.1.8",
|
||||||
|
oids=[
|
||||||
|
"1", #Number of PSU installed
|
||||||
|
"2", #PowerSupply1 state
|
||||||
|
"3", #PowerSupply2 state
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def discovery_avocent_psu(section: Section) -> DiscoveryResult:
|
||||||
|
yield Service()
|
||||||
|
|
||||||
|
|
||||||
|
def _power_supply_status_descr(status_nr: str) -> str:
|
||||||
|
return {
|
||||||
|
"1": "Powered On",
|
||||||
|
"2": "Powered Off",
|
||||||
|
"9999": "Power Supply is not installed",
|
||||||
|
}.get(status_nr, status_nr)
|
||||||
|
|
||||||
|
def _power_supply_state(status_nr: str) -> State:
|
||||||
|
return {
|
||||||
|
"1": State.OK,
|
||||||
|
"2": State.CRIT,
|
||||||
|
"9999": State.OK
|
||||||
|
}.get(status_nr, State.UNKNOWN)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def check_avocent_psu(
|
||||||
|
section: Section,
|
||||||
|
) -> CheckResult:
|
||||||
|
number_of_psu=section[0]
|
||||||
|
state_psu_1=section[1]
|
||||||
|
state_psu_2=section[2]
|
||||||
|
|
||||||
|
yield Result(
|
||||||
|
state=State.OK,
|
||||||
|
summary="Number of PSU installed: %s" % number_of_psu,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield Result(
|
||||||
|
state=_power_supply_state(state_psu_1),
|
||||||
|
summary="Power Supply 1 is %s" % _power_supply_status_descr(state_psu_1),
|
||||||
|
)
|
||||||
|
|
||||||
|
yield Result(
|
||||||
|
state=_power_supply_state(state_psu_2),
|
||||||
|
summary="Power Supply 2 is %s" % _power_supply_status_descr(state_psu_2),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
register.check_plugin(
|
||||||
|
name="avocent_psu",
|
||||||
|
sections=["avocent_psu"],
|
||||||
|
service_name="Power Supplies",
|
||||||
|
discovery_function=discovery_avocent_psu,
|
||||||
|
check_function=check_avocent_psu
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2019 tribe29 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.
|
||||||
|
|
||||||
|
import dataclasses
|
||||||
|
from typing import Mapping
|
||||||
|
|
||||||
|
from .agent_based_api.v1 import (
|
||||||
|
contains,
|
||||||
|
get_value_store,
|
||||||
|
Metric,
|
||||||
|
register,
|
||||||
|
Result,
|
||||||
|
Service,
|
||||||
|
SNMPTree,
|
||||||
|
State,
|
||||||
|
startswith
|
||||||
|
)
|
||||||
|
from .agent_based_api.v1.type_defs import CheckResult, DiscoveryResult, StringTable
|
||||||
|
from .utils.temperature import check_temperature, TempParamType
|
||||||
|
|
||||||
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
class Sensor:
|
||||||
|
value: float
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
class VoltageSensor(Sensor):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
class Section:
|
||||||
|
temperature_sensors: Mapping[str, Sensor]
|
||||||
|
voltage_sensors: Mapping[str, Sensor]
|
||||||
|
|
||||||
|
temperature_sensors_name = ['CPU','Board']
|
||||||
|
voltage_sensors_name = ['PSU 1','PSU 2']
|
||||||
|
|
||||||
|
def parse_avocent_sensors(string_table: StringTable) -> Section:
|
||||||
|
temperature_sensors = {}
|
||||||
|
voltage_sensors = {}
|
||||||
|
position = 0
|
||||||
|
for temp_sens_name in temperature_sensors_name:
|
||||||
|
temperature_sensors[temp_sens_name] = Sensor(value=int(string_table[0][position]))
|
||||||
|
position +=1
|
||||||
|
|
||||||
|
pos = 2
|
||||||
|
for volt_sens_name in voltage_sensors_name:
|
||||||
|
voltage_sensors[volt_sens_name] = Sensor(value=float(string_table[0][pos])/100)
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
return Section(
|
||||||
|
temperature_sensors=temperature_sensors,
|
||||||
|
voltage_sensors=voltage_sensors,
|
||||||
|
)
|
||||||
|
|
||||||
|
register.snmp_section(
|
||||||
|
name="avocent_sensors",
|
||||||
|
detect=startswith(".1.3.6.1.2.1.1.1.0", "Avocent"),
|
||||||
|
parse_function=parse_avocent_sensors,
|
||||||
|
fetch=SNMPTree(
|
||||||
|
base=".1.3.6.1.4.1.10418.26.2.7",
|
||||||
|
oids=[
|
||||||
|
"1", #acsSensorsInternalCurrentCPUTemperature
|
||||||
|
"6", #acsSensorsInternalCurrentBoardTemperature
|
||||||
|
"17", #acsSensorsVoltagePowerSupply1
|
||||||
|
"18", #acsSensorsVoltagePowerSupply2
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def discover_avocent_voltage_sensors(section: Section) -> DiscoveryResult:
|
||||||
|
yield from (Service(item=sensor_name) for sensor_name in section.voltage_sensors)
|
||||||
|
|
||||||
|
|
||||||
|
def check_avocent_voltage_sensors(
|
||||||
|
item: str,
|
||||||
|
section: Section,
|
||||||
|
) -> CheckResult:
|
||||||
|
if not (sensor := section.voltage_sensors.get(item)):
|
||||||
|
return
|
||||||
|
|
||||||
|
yield Result(
|
||||||
|
state=State.OK,
|
||||||
|
summary=f"{sensor.value:.1f} V",
|
||||||
|
)
|
||||||
|
|
||||||
|
yield Metric(
|
||||||
|
name="voltage",
|
||||||
|
value=sensor.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
register.check_plugin(
|
||||||
|
name="avocent_voltage_sensors",
|
||||||
|
sections=["avocent_sensors"],
|
||||||
|
service_name="Voltage %s",
|
||||||
|
discovery_function=discover_avocent_voltage_sensors,
|
||||||
|
check_function=check_avocent_voltage_sensors,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def discover_avocent_sensors_temp(section: Section) -> DiscoveryResult:
|
||||||
|
yield from (Service(item=sensor_name) for sensor_name in section.temperature_sensors)
|
||||||
|
|
||||||
|
|
||||||
|
def check_avocent_sensors_temp(
|
||||||
|
item: str,
|
||||||
|
params: TempParamType,
|
||||||
|
section: Section,
|
||||||
|
) -> CheckResult:
|
||||||
|
if not (sensor := section.temperature_sensors.get(item)):
|
||||||
|
return
|
||||||
|
yield from check_temperature(
|
||||||
|
reading=sensor.value,
|
||||||
|
params=params,
|
||||||
|
unique_name=item,
|
||||||
|
value_store=get_value_store(),
|
||||||
|
)
|
||||||
|
|
||||||
|
register.check_plugin(
|
||||||
|
name="avocent_sensors_temp",
|
||||||
|
sections=["avocent_sensors"],
|
||||||
|
service_name="Temperature %s",
|
||||||
|
discovery_function=discover_avocent_sensors_temp,
|
||||||
|
check_function=check_avocent_sensors_temp,
|
||||||
|
check_ruleset_name="temperature",
|
||||||
|
check_default_parameters={"device_levels_handling": "devdefault"},
|
||||||
|
)
|
@ -0,0 +1,152 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2019 tribe29 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 ..agent_based_api.v1 import (
|
||||||
|
all_of,
|
||||||
|
any_of,
|
||||||
|
contains,
|
||||||
|
equals,
|
||||||
|
exists,
|
||||||
|
not_contains,
|
||||||
|
not_equals,
|
||||||
|
not_exists,
|
||||||
|
not_startswith,
|
||||||
|
startswith,
|
||||||
|
)
|
||||||
|
|
||||||
|
# We are not sure how to safely detect the UCD SNMP Daemon. We know that
|
||||||
|
# it is mainly used on Linux, but not only. But fetching and OID outside
|
||||||
|
# of the info area for scanning is not a good idea. It will slow down
|
||||||
|
# scans for *all* hosts.
|
||||||
|
|
||||||
|
# ---ucd cpu load---------------------------------------------------------
|
||||||
|
|
||||||
|
# We prefer HOST-RESOURCES-MIB implementation but not in case
|
||||||
|
# of check 'ucd_cpu_load' because the HR-MIB has not data
|
||||||
|
# about cpu load
|
||||||
|
|
||||||
|
# ---general ucd/hr-------------------------------------------------------
|
||||||
|
|
||||||
|
HR = exists(".1.3.6.1.2.1.25.1.1.0")
|
||||||
|
|
||||||
|
_NOT_HR = not_exists(".1.3.6.1.2.1.25.1.1.0")
|
||||||
|
|
||||||
|
UCD = any_of(
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "linux"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "cmc-tc"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "hp onboard administrator"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "barracuda"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "pfsense"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "genugate"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "bomgar"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "pulse secure"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "microsens"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "avocent"),
|
||||||
|
all_of( # Artec email archive appliances
|
||||||
|
equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "version"),
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "serial"),
|
||||||
|
),
|
||||||
|
all_of(
|
||||||
|
equals(".1.3.6.1.2.1.1.1.0", ""),
|
||||||
|
exists(".1.3.6.1.4.1.2021.*"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
_NOT_UCD = all_of(
|
||||||
|
# This is an explicit negation of the constant above.
|
||||||
|
# We don't have a generic negation function as we want
|
||||||
|
# discourage constructs like this.
|
||||||
|
# In the future this will be acomplished using the 'supersedes'
|
||||||
|
# feature (according to CMK-4232), and this can be removed.
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "linux"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "cmc-tc"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "hp onboard administrator"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "barracuda"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "pfsense"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "genugate"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "bomgar"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "pulse secure"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "microsens"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "avocent"),
|
||||||
|
any_of( # Artec email archive appliances
|
||||||
|
not_equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "version"),
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "serial"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
PREFER_HR_ELSE_UCD = all_of(UCD, _NOT_HR)
|
||||||
|
|
||||||
|
# ---helper---------------------------------------------------------------
|
||||||
|
|
||||||
|
# Within _is_ucd or _is_ucd_mem we make use of a whitelist
|
||||||
|
# in order to expand this list of devices easily.
|
||||||
|
|
||||||
|
_UCD_MEM = any_of(
|
||||||
|
# Devices for which ucd_mem should be used
|
||||||
|
# if and only if HR-table is not available
|
||||||
|
all_of(
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "pfsense"),
|
||||||
|
not_exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
all_of(
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "ironport model c3"),
|
||||||
|
not_exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
all_of(
|
||||||
|
contains(".1.3.6.1.2.1.1.1.0", "bomgar"),
|
||||||
|
not_exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
all_of(
|
||||||
|
# Astaro and Synology are Linux but should use hr_mem
|
||||||
|
# Otherwise Cache/Buffers are included in used memory
|
||||||
|
# generating critical state
|
||||||
|
not_startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072."),
|
||||||
|
# Otherwise use ucd_mem for listed devices in UCD.
|
||||||
|
UCD,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
_NOT_UCD_MEM = all_of(
|
||||||
|
# This is an explicit negation of the constant above.
|
||||||
|
# We don't have a generic negation function as we want
|
||||||
|
# discourage constructs like this.
|
||||||
|
# In the future this will be acomplished using the 'supersedes'
|
||||||
|
# feature (according to CMK-4232), and this can be removed.
|
||||||
|
any_of(
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "pfsense"),
|
||||||
|
exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
any_of(
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "ironport model c3"),
|
||||||
|
exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
any_of(
|
||||||
|
not_contains(".1.3.6.1.2.1.1.1.0", "bomgar"),
|
||||||
|
exists(".1.3.6.1.2.1.25.1.1.0"),
|
||||||
|
),
|
||||||
|
any_of(
|
||||||
|
# Astaro and Synology are Linux but should use hr_mem
|
||||||
|
# Otherwise Cache/Buffers are included in used memory
|
||||||
|
# generating critical state
|
||||||
|
startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072."),
|
||||||
|
# Otherwise use ucd_mem for listed devices in UCD.
|
||||||
|
_NOT_UCD,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Some devices report incorrect data on both HR and UCD, eg. F5 BigIP
|
||||||
|
_NOT_BROKEN_MEM = all_of(
|
||||||
|
not_startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3375"),
|
||||||
|
not_startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2620"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---memory---------------------------------------------------------------
|
||||||
|
|
||||||
|
USE_UCD_MEM = all_of(_NOT_BROKEN_MEM, _UCD_MEM)
|
||||||
|
|
||||||
|
USE_HR_MEM = all_of(_NOT_BROKEN_MEM, _NOT_UCD_MEM)
|
@ -0,0 +1,15 @@
|
|||||||
|
title: Avocent ACS 800 CPU and Board Temperature
|
||||||
|
agents: snmp
|
||||||
|
catalog: hw/network/avocent
|
||||||
|
license: GPLv2
|
||||||
|
distribution: check_mk
|
||||||
|
description:
|
||||||
|
Checks by SNMP the Temperature for CPU and Board sensors of Avocent ACS 800 devices.
|
||||||
|
|
||||||
|
Return {OK} if no temperature rule is created, otherwise based on the level in
|
||||||
|
the configured temperature rule.
|
||||||
|
item:
|
||||||
|
CPU Temperature and Board Temperature
|
||||||
|
|
||||||
|
discovery:
|
||||||
|
One service is created for CPU Temperature and one service for Board Temperature
|
@ -0,0 +1,15 @@
|
|||||||
|
title: Avocent ACS 800 Power Supply Voltage Sensors
|
||||||
|
agents: snmp
|
||||||
|
catalog: hw/network/avocent
|
||||||
|
license: GPLv2
|
||||||
|
distribution: check_mk
|
||||||
|
description:
|
||||||
|
Checks by SNMP the power supply voltage sensors of Avocent ACS 800 devices.
|
||||||
|
|
||||||
|
Returns {OK} Always.
|
||||||
|
|
||||||
|
item:
|
||||||
|
The Voltage for each power supply.
|
||||||
|
|
||||||
|
discovery:
|
||||||
|
Two services created, one for each Power Supply
|
Loading…
Reference in New Issue
Block a user