166 lines
5.1 KiB
Python
166 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2024 Spearhead Systems SRL
|
|
#
|
|
# Docs for this system:
|
|
# https://cdn10.servertech.com/assets/documents/documents/135/original/manual_CDU_Y-30932L.pdf
|
|
# https://cdn10.servertech.com/assets/documents/documents/793/original/Sentry3.mib
|
|
|
|
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
|
|
register,
|
|
Service,
|
|
Result,
|
|
State,
|
|
SNMPTree,
|
|
contains,
|
|
OIDEnd,
|
|
)
|
|
|
|
|
|
def extract_outlet(tower_id, infeed_id, outlet_id, data):
|
|
return next(filter(lambda x: x[0] == f'{tower_id+1}.{infeed_id+1}.{outlet_id+1}', data))[1]
|
|
|
|
|
|
# SNMP parsing function
|
|
def parse_sentry_pdu(string_table):
|
|
outlets_info = {}
|
|
num_towers = int(string_table[0][0][0])
|
|
|
|
for tower_id in range(num_towers):
|
|
num_infeeds = int(string_table[1][0][tower_id])
|
|
|
|
for infeed_id in range(num_infeeds):
|
|
infeed_sid = string_table[2][infeed_id][tower_id]
|
|
infeed_voltage = float(string_table[3][infeed_id][tower_id]) / 10
|
|
num_outlets = int(string_table[4][infeed_id][tower_id])
|
|
|
|
for outlet_id in range(num_outlets):
|
|
outlet_sid = extract_outlet(tower_id, infeed_id, outlet_id, string_table[5])
|
|
outlet_name = extract_outlet(tower_id, infeed_id, outlet_id, string_table[6])
|
|
outlet_load = float(extract_outlet(tower_id, infeed_id, outlet_id, string_table[7])) / 100
|
|
|
|
outlets_info[f'{tower_id}.{infeed_id}.{outlet_id}'] = {
|
|
'infeed_id': infeed_sid,
|
|
'infeed_voltage': infeed_voltage,
|
|
'outlet_id': outlet_sid,
|
|
'outlet_name': outlet_name,
|
|
'outlet_load': outlet_load
|
|
}
|
|
|
|
return outlets_info
|
|
|
|
|
|
# Inventory function, returning inventory based upon SNMP parsed result above
|
|
def discovery_sentry_pdu(section):
|
|
for key, outlet in section.items():
|
|
name = f'{outlet["outlet_id"]} {outlet["outlet_name"]} (infeed {outlet["infeed_id"]}) power'
|
|
yield Service(item=name, parameters={ 'id': key })
|
|
|
|
|
|
# Check function, returning warn/crit based upon SNMP parsed result above
|
|
def check_sentry_pdu(item, params, section):
|
|
outlet = section.get(params['id'])
|
|
if outlet is None:
|
|
return
|
|
|
|
voltage = outlet['infeed_voltage']
|
|
amps = outlet['outlet_load']
|
|
|
|
if voltage < 0:
|
|
yield Result(state=State.WARN, summary='Infeed voltage unavailable')
|
|
return
|
|
elif amps < 0:
|
|
yield Result(state=State.WARN, summary='Outlet load unavailable')
|
|
return
|
|
|
|
power = voltage * amps
|
|
state = State.OK
|
|
|
|
crit_watts_above = params.get('crit_watts_above')
|
|
warn_watts_above = params.get('warn_watts_above')
|
|
warn_watts_below = params.get('warn_watts_below')
|
|
crit_watts_below = params.get('crit_watts_below')
|
|
|
|
if crit_watts_above and crit_watts_above < power:
|
|
state = State.CRIT
|
|
elif crit_watts_below and crit_watts_below > power:
|
|
state = State.CRIT
|
|
elif warn_watts_above and warn_watts_above < power:
|
|
state = State.WARN
|
|
elif warn_watts_below and warn_watts_below > power:
|
|
state = State.WARN
|
|
|
|
yield Result(state=state, summary=f'{power:.1f} watts')
|
|
|
|
|
|
register.snmp_section(
|
|
name='sentry_pdu_outlets_power',
|
|
parse_function=parse_sentry_pdu,
|
|
fetch=[
|
|
# Number of towers (integer from 0 to 4)
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.1.4',
|
|
oids=['0']
|
|
),
|
|
|
|
# Number of infeeds (integer from 0 to 4):
|
|
# .1.3.6.1.4.1.1718.3.2.1.1.5.<tower #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.1.1.5',
|
|
oids=['1', '2', '3', '4'],
|
|
),
|
|
|
|
# Infeed IDs:
|
|
# .1.3.6.1.4.1.1718.3.2.2.1.2.<tower #>.<infeed #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.2.1.2',
|
|
oids=['1', '2', '3', '4'],
|
|
),
|
|
|
|
# Infeed voltage:
|
|
# .1.3.6.1.4.1.1718.3.2.2.1.11.<tower #>.<infeed #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.2.1.11',
|
|
oids=['1', '2', '3', '4'],
|
|
),
|
|
|
|
# Number of outlets (integer from 0 to 64):
|
|
# .1.3.6.1.4.1.1718.3.2.2.1.9.<tower #>.<infeed #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.2.1.9',
|
|
oids=['1', '2', '3', '4'],
|
|
),
|
|
|
|
# Outlet IDs:
|
|
# .1.3.6.1.4.1.1718.3.2.3.1.2.<tower #>.<infeed #>.<outlet #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.3.1',
|
|
oids=[OIDEnd(), '2'],
|
|
),
|
|
|
|
# Outlet names:
|
|
# .1.3.6.1.4.1.1718.3.2.3.1.3.<tower #>.<infeed #>.<outlet #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.3.1',
|
|
oids=[OIDEnd(), '3'],
|
|
),
|
|
|
|
# Outlet load:
|
|
# .1.3.6.1.4.1.1718.3.2.3.1.7.<tower #>.<infeed #>.<outlet #>
|
|
SNMPTree(
|
|
base='.1.3.6.1.4.1.1718.3.2.3.1',
|
|
oids=[OIDEnd(), '7']
|
|
),
|
|
],
|
|
detect=contains('.1.3.6.1.2.1.1.1.0', 'Sentry Switched -48 VDC'),
|
|
)
|
|
|
|
register.check_plugin(
|
|
name='sentry_pdu_outlets_power',
|
|
service_name='Outlet %s',
|
|
discovery_function=discovery_sentry_pdu,
|
|
check_function=check_sentry_pdu,
|
|
check_default_parameters={},
|
|
check_ruleset_name='sentry_pdu_outlets_power',
|
|
)
|