Collection of CheckMK checks (see https://checkmk.com/). All checks and plugins are provided as is. Absolutely no warranty. Send any comments to thl-cmk[at]outlook[dot]com

Skip to content
Snippets Groups Projects
Commit 5cc8b760 authored by thl-cmk's avatar thl-cmk :flag_na:
Browse files

update project

parent 285eebca
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
#
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-17-20
#
# Monitor status of Cisco EIGRP AS info
#
# 2018-02-11: removed unnecessary OIDs
# 2018-08-06: modified scan function
# 2019-10-16: added support for IPv6 and VRFs, added parser function
#
#
# snmpwalk sample
#
# thl@surfbox-ii:~$ snmpwalk -v2c -c router-01 -ObentU simulant .1.3.6.1.4.1.9.9.449.1.2.1.1
# .1.3.6.1.4.1.9.9.449.1.2.1.1.2.65536.10 = Gauge32: 3
# .1.3.6.1.4.1.9.9.449.1.2.1.1.3.65536.10 = Counter32: 37436
# .1.3.6.1.4.1.9.9.449.1.2.1.1.4.65536.10 = Counter32: 32170
# .1.3.6.1.4.1.9.9.449.1.2.1.1.5.65536.10 = Counter32: 161
# .1.3.6.1.4.1.9.9.449.1.2.1.1.6.65536.10 = Counter32: 143
# .1.3.6.1.4.1.9.9.449.1.2.1.1.7.65536.10 = Counter32: 14
# .1.3.6.1.4.1.9.9.449.1.2.1.1.8.65536.10 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.9.65536.10 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.10.65536.10 = Counter32: 14
# .1.3.6.1.4.1.9.9.449.1.2.1.1.11.65536.10 = Counter32: 143
# .1.3.6.1.4.1.9.9.449.1.2.1.1.12.65536.10 = Counter32: 132
# .1.3.6.1.4.1.9.9.449.1.2.1.1.13.65536.10 = Gauge32: 2
# .1.3.6.1.4.1.9.9.449.1.2.1.1.14.65536.10 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.15.65536.10 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.16.65536.10 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.17.65536.10 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.2.1.1.18.65536.10 = Hex-STRING: 0A A7 DC FF # can be also in the form of "10.10.10.10" :-(
# .1.3.6.1.4.1.9.9.449.1.2.1.1.19.65536.10 = Counter32: 10
# .1.3.6.1.4.1.9.9.449.1.2.1.1.20.65536.10 = Counter64: 1
# .1.3.6.1.4.1.9.9.449.1.2.1.1.21.65536.10 = Counter64: 135
# .1.3.6.1.4.1.9.9.449.1.2.1.1.22.65536.10 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.2.1.1.23.65536.10 = Gauge32: 0
#
# sample info
# [
# [u'65536.10', u'1', u'7081', u'6637', u'37', u'45', u'0', u'0', u'0', u'0', u'26', u'32', u'2', u'0', u'0', u'0', u'1', u'\n\xa7\xdc\xfd', u'10', u'0']
# ]
#
#
from time import time
from dataclasses import dataclass
from typing import Optional, List
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
register,
Service,
Result,
check_levels,
State,
SNMPTree,
all_of,
contains,
exists,
OIDEnd,
Metric,
get_rate,
get_value_store,
GetRateError,
IgnoreResultsError,
)
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
DiscoveryResult,
CheckResult,
StringTable,
)
_InetAddressType = {0: 'unknown',
1: 'ipv4',
2: 'ipv6',
3: 'ipv4z',
4: 'ipv6z',
16: 'dns',
}
def _render_ip_address(bytestring):
return ".".join(["%s" % ord(m) for m in bytestring])
###########################################################################
#
# DATA Parser function
#
###########################################################################
def parse_cisco_eigrp_as_info(string_table: List[StringTable]):
ASInfoTable = []
ASTable = {}
ASInfo, VrfInfo = string_table
for OID_END, cEigrpNbrCount, cEigrpHellosSent, cEigrpHellosRcvd, cEigrpUpdatesSent, cEigrpUpdatesRcvd, cEigrpQueriesSent, \
cEigrpQueriesRcvd, cEigrpRepliesSent, cEigrpRepliesRcvd, cEigrpAcksSent, cEigrpAcksRcvd, cEigrpInputQHighMark, cEigrpInputQDrops, \
cEigrpSiaQueriesSent, cEigrpSiaQueriesRcvd, cEigrpAsRouterIdType, cEigrpAsRouterId, cEigrpTopoRoutes, cEigrpXmitPendReplies in ASInfo:
cEigrpVrfId = int(OID_END.split('.')[0])
cEigrpAS = OID_END.split('.')[1]
cEigrpVrfName = ''
for VrfId, VrfName in VrfInfo:
if int(VrfId) == cEigrpVrfId:
cEigrpVrfName = VrfName
if cEigrpVrfId < 100000:
cEigrpAddrFammily = 'IPv4'
else:
cEigrpAddrFammily = 'IPv6'
if int(cEigrpAsRouterIdType) == 1:
if len(cEigrpAsRouterId) == 4:
cEigrpAsRouterId = _render_ip_address(cEigrpAsRouterId)
ASInfoTable.append({
'cEigrpAS': cEigrpAS,
'cEigrpVrfName': cEigrpVrfName,
'cEigrpVrfId': cEigrpVrfId,
'cEigrpAddrFammily': cEigrpAddrFammily,
'cEigrpNbrCount': int(cEigrpNbrCount),
'cEigrpHellosSent': int(cEigrpHellosSent),
'cEigrpHellosRcvd': int(cEigrpHellosRcvd),
'cEigrpUpdatesSent': int(cEigrpUpdatesSent),
'cEigrpUpdatesRcvd': int(cEigrpUpdatesRcvd),
'cEigrpQueriesSent': int(cEigrpQueriesSent),
'cEigrpQueriesRcvd': int(cEigrpQueriesRcvd),
'cEigrpRepliesSent': int(cEigrpRepliesSent),
'cEigrpRepliesRcvd': int(cEigrpRepliesRcvd),
'cEigrpAcksSent': int(cEigrpAcksSent),
'cEigrpAcksRcvd': int(cEigrpAcksRcvd),
'cEigrpInputQHighMark': int(cEigrpInputQHighMark),
'cEigrpInputQDrops': int(cEigrpInputQDrops),
'cEigrpSiaQueriesSent': int(cEigrpSiaQueriesSent),
'cEigrpSiaQueriesRcvd': int(cEigrpSiaQueriesRcvd),
'cEigrpAsRouterId': cEigrpAsRouterId,
'cEigrpTopoRoutes': int(cEigrpTopoRoutes),
'cEigrpXmitPendReplies': int(cEigrpXmitPendReplies),
})
if cEigrpVrfName == 'default' and cEigrpAddrFammily == 'IPv4':
ASTable.update({cEigrpVrfId: {'ServiceText': cEigrpAS, 'cEigrpVrfId': cEigrpVrfId}})
elif cEigrpVrfName == 'default' and cEigrpAddrFammily == 'IPv6':
ASTable.update({cEigrpVrfId:{'ServiceText': '%s IPv6' % cEigrpAS, 'cEigrpVrfId': cEigrpVrfId}})
elif cEigrpVrfName != 'default' and cEigrpAddrFammily == 'IPv4':
ASTable.update({cEigrpVrfId:{'ServiceText': '%s VRF %s' % (cEigrpAS, cEigrpVrfName), 'cEigrpVrfId': cEigrpVrfId}})
elif cEigrpVrfName != 'default' and cEigrpAddrFammily == 'IPv6':
ASTable.update({cEigrpVrfId:{'ServiceText': '%s IPv6 VRF %s' % (cEigrpAS, cEigrpVrfName), 'cEigrpVrfId': cEigrpVrfId}})
return [ASTable, ASInfoTable]
###########################################################################
#
# INVENTORY function
#
###########################################################################
def discovery_cisco_eigrp_as_info(section) -> DiscoveryResult:
ASTable, ASInfoTable = section
ASTable = dict(ASTable)
for Key in ASTable.keys():
ServiceText = ASTable.get(Key).get('ServiceText')
yield Service(item=ServiceText)
###########################################################################
#
# CHECK function
#
###########################################################################
def check_cisco_eigrp_as_info(item, params, section) -> CheckResult:
ASTable, ASInfoTable = section
ASTable = dict(ASTable)
cEigrpVrfId = ''
for Key in ASTable.keys():
ServiceText = ASTable.get(Key).get('ServiceText')
if ServiceText == item:
cEigrpVrfId = ASTable.get(Key).get('cEigrpVrfId')
if cEigrpVrfId != '':
for AS in ASInfoTable:
if AS.get('cEigrpVrfId') == cEigrpVrfId:
cEigrpNbrCount = AS.get('cEigrpNbrCount')
cEigrpHellosSent = AS.get('cEigrpHellosSent')
cEigrpHellosRcvd = AS.get('cEigrpHellosRcvd')
cEigrpUpdatesSent = AS.get('cEigrpUpdatesSent')
cEigrpUpdatesRcvd = AS.get('cEigrpUpdatesRcvd')
cEigrpQueriesSent = AS.get('cEigrpQueriesSent')
cEigrpQueriesRcvd = AS.get('cEigrpQueriesRcvd')
cEigrpRepliesSent = AS.get('cEigrpRepliesSent')
cEigrpRepliesRcvd = AS.get('cEigrpRepliesRcvd')
cEigrpAcksSent = AS.get('cEigrpAcksSent')
cEigrpAcksRcvd = AS.get('cEigrpAcksRcvd')
cEigrpInputQHighMark = AS.get('cEigrpInputQHighMark')
cEigrpInputQDrops = AS.get('cEigrpInputQDrops')
cEigrpSiaQueriesSent = AS.get('cEigrpSiaQueriesSent')
cEigrpSiaQueriesRcvd = AS.get('cEigrpSiaQueriesRcvd')
cEigrpAsRouterId = AS.get('cEigrpAsRouterId')
cEigrpTopoRoutes = AS.get('cEigrpTopoRoutes')
cEigrpXmitPendReplies = AS.get('cEigrpXmitPendReplies')
yield Result(
state=State.OK,
summary=f'Router-ID: {cEigrpAsRouterId}, neighbors: {cEigrpNbrCount}, Routes in topologie table: {cEigrpTopoRoutes}')
for key, value in [
('cEigrpNbrCount', cEigrpNbrCount),
('cEigrpUpdatesSent', cEigrpUpdatesSent),
('cEigrpUpdatesRcvd', cEigrpUpdatesRcvd),
('cEigrpQueriesSent', cEigrpQueriesSent),
('cEigrpQueriesRcvd', cEigrpQueriesRcvd),
('cEigrpRepliesSent', cEigrpRepliesSent),
('cEigrpRepliesRcvd', cEigrpRepliesRcvd),
('cEigrpAcksSent', cEigrpAcksSent),
('cEigrpAcksRcvd', cEigrpAcksRcvd),
('cEigrpInputQHighMark', cEigrpInputQHighMark),
('cEigrpInputQDrops', cEigrpInputQDrops),
('cEigrpSiaQueriesSent', cEigrpSiaQueriesSent),
('cEigrpSiaQueriesRcvd', cEigrpSiaQueriesRcvd),
('cEigrpTopoRoutes', cEigrpTopoRoutes),
('cEigrpXmitPendReplies', cEigrpXmitPendReplies),
]:
yield Metric(name=f'cisco_eigrp_as_info_{key}', value=value)
now_time = time()
rate_item=item.replace(' ', '_').replace(':', '_')
value_store = get_value_store()
raise_ingore_res = False
for key, value in [
('cEigrpHellosSent', cEigrpHellosSent),
('cEigrpHellosRcvd', cEigrpHellosRcvd),
]:
try:
try:
value = get_rate(
value_store,
f'cisco_eigrp_as_info_{key}.{rate_item}',
now_time,
value,
raise_overflow=False
)
except GetRateError:
raise_ingore_res = True
value = 0
yield Metric(name=f'cisco_eigrp_as_info_{key}', value=value, boundaries=(0, None))
except KeyError:
pass
if raise_ingore_res:
raise IgnoreResultsError('Initializing counters')
###########################################################################
#
# CHECK info
#
###########################################################################
register.snmp_section(
name='cisco_eigrp_as_info',
parse_function=parse_cisco_eigrp_as_info,
fetch=[
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.2.1.1', # CISCO-TRUSTSEC-MIB::ctsEnvironmentDataObjects
oids=[
OIDEnd(), # AS number
'2', # cEigrpNbrCount [1]
'3', # cEigrpHellosSent [2]
'4', # cEigrpHellosRcvd [3]
'5', # cEigrpUpdatesSent [4]
'6', # cEigrpUpdatesRcvd [5]
'7', # cEigrpQueriesSent [6]
'8', # cEigrpQueriesRcvd [7]
'9', # cEigrpRepliesSent [8]
'10', # cEigrpRepliesRcvd [9]
'11', # cEigrpAcksSent [10]
'12', # cEigrpAcksRcvd [11]
'13', # cEigrpInputQHighMark [12]
'14', # cEigrpInputQDrops [13]
'15', # cEigrpSiaQueriesSent [14]
'16', # cEigrpSiaQueriesRcvd [15]
'17', # cEigrpAsRouterIdType [16]
'18', # cEigrpAsRouterId [17]
'19', # cEigrpTopoRoutes [18]
'22', # cEigrpXmitPendReplies [19]
# '20', # cEigrpHeadSerial []
# '21', # cEigrpNextSerial []
# '23', # cEigrpXmitDummies []
]
),
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.1.1.1', # CISCO-TRUSTSEC-MIB::ctsEnvironmentDataObjects
oids=[
OIDEnd(), # VRF ID
'2', # cEigrpVpnName
]
),
],
detect=all_of(
contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr
exists('.1.3.6.1.4.1.9.9.449.1.2.1.1.2.*'), # CISCO-EIGRP-MIB::cEigrpNbrCount
))
register.check_plugin(
name='cisco_eigrp_as_info',
service_name='EIGRP AS number %s',
discovery_function=discovery_cisco_eigrp_as_info,
check_function=check_cisco_eigrp_as_info,
check_default_parameters={
},
check_ruleset_name='cisco_eigrp_as_info',
)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
#
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-17-21
#
# Monitor status of Cisco EIGRP interface info
#
# 2018-01-23: Th.L.: inventory skip Loopback interface
# 2018-02-11: Th.L.: removed unnecessary OIDs
# 2018-08-06: modified scan function
# 2019-10-14: added support for hamc-sha-256 authentication, md5 moved to warn, none moved to crit
# 2019-10-16: added support for IPv6 and VRFs, added data parser function
# 2019-10-31: changed item from interface long-name to interface short name
#
# snmpwalk sample
#
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c router-01 simulant .1.3.6.1.4.1.9.9.449.1.5.1.1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.3.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.3.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.3.65536.10.8 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.3.65536.10.9 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.4.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.4.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.4.65536.10.8 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.4.65536.10.9 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.5.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.5.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.5.65536.10.8 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.5.65536.10.9 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.6.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.6.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.6.65536.10.8 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.6.65536.10.9 = Gauge32: 19
# .1.3.6.1.4.1.9.9.449.1.5.1.1.7.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.7.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.7.65536.10.8 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.7.65536.10.9 = Gauge32: 23
# .1.3.6.1.4.1.9.9.449.1.5.1.1.8.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.8.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.8.65536.10.8 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.8.65536.10.9 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.9.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.9.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.9.65536.10.8 = Gauge32: 50
# .1.3.6.1.4.1.9.9.449.1.5.1.1.9.65536.10.9 = Gauge32: 84
# .1.3.6.1.4.1.9.9.449.1.5.1.1.10.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.10.65536.10.7 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.10.65536.10.8 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.10.65536.10.9 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.11.65536.10.1 = Gauge32: 5
# .1.3.6.1.4.1.9.9.449.1.5.1.1.11.65536.10.7 = Gauge32: 5
# .1.3.6.1.4.1.9.9.449.1.5.1.1.11.65536.10.8 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.11.65536.10.9 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.12.65536.10.1 = Counter64: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.12.65536.10.7 = Counter64: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.12.65536.10.8 = Counter64: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.12.65536.10.9 = Counter64: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.13.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.13.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.13.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.13.65536.10.9 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.14.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.14.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.14.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.14.65536.10.9 = Counter32: 18
# .1.3.6.1.4.1.9.9.449.1.5.1.1.15.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.15.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.15.65536.10.8 = Counter32: 64
# .1.3.6.1.4.1.9.9.449.1.5.1.1.15.65536.10.9 = Counter32: 40
# .1.3.6.1.4.1.9.9.449.1.5.1.1.16.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.16.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.16.65536.10.8 = Counter32: 66
# .1.3.6.1.4.1.9.9.449.1.5.1.1.16.65536.10.9 = Counter32: 27
# .1.3.6.1.4.1.9.9.449.1.5.1.1.17.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.17.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.17.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.17.65536.10.9 = Counter32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.18.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.18.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.18.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.18.65536.10.9 = Counter32: 2
# .1.3.6.1.4.1.9.9.449.1.5.1.1.19.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.19.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.19.65536.10.8 = Counter32: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.19.65536.10.9 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.20.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.20.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.20.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.20.65536.10.9 = Counter32: 5
# .1.3.6.1.4.1.9.9.449.1.5.1.1.21.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.21.65536.10.7 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.21.65536.10.8 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.5.1.1.21.65536.10.9 = Counter32: 3
# .1.3.6.1.4.1.9.9.449.1.5.1.1.22.65536.10.1 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.22.65536.10.7 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.5.1.1.22.65536.10.8 = INTEGER: 2
# .1.3.6.1.4.1.9.9.449.1.5.1.1.22.65536.10.9 = INTEGER: 2
# .1.3.6.1.4.1.9.9.449.1.5.1.1.23.65536.10.1 = ""
# .1.3.6.1.4.1.9.9.449.1.5.1.1.23.65536.10.7 = ""
# .1.3.6.1.4.1.9.9.449.1.5.1.1.23.65536.10.8 = STRING: "KEY-EIGRP-10"
# .1.3.6.1.4.1.9.9.449.1.5.1.1.23.65536.10.9 = STRING: "KEY-EIGRP-10"
# #
# sample info
# [
# [
# [u'65536.10.1', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'5', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'1', u''],
# [u'65536.10.7', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'5', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'1', u''],
# [u'65536.10.8', u'1', u'0', u'0', u'1', u'0', u'0', u'50', u'0', u'1', u'0', u'0', u'0', u'64', u'66', u'0', u'0', u'1', u'0', u'0', u'2', u'KEY-EIGRP-10'],
# [u'65536.10.9', u'1', u'0', u'0', u'19', u'23', u'0', u'84', u'0', u'1', u'0', u'0', u'18', u'40', u'27', u'1', u'2', u'0', u'5', u'3', u'2', u'KEY-EIGRP-10']
# ],
# [
# [u'1', u'GigabitEthernet0/0/0'],
# [u'2', u'GigabitEthernet0/0/1'],
# [u'3', u'GigabitEthernet0/0/2'],
# [u'4', u'GigabitEthernet0/0/3'],
# [u'5', u'GigabitEthernet0'],
# [u'6', u'Null0'],
# [u'7', u'Loopback0'],
# [u'8', u'Tunnel10'],
# [u'9', u'Tunnel101']
# ]
# ]
#
from time import mktime, gmtime
from dataclasses import dataclass
from typing import Optional, List, Dict
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
register,
Service,
Result,
check_levels,
State,
SNMPTree,
all_of,
contains,
exists,
OIDEnd,
Metric,
)
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
DiscoveryResult,
CheckResult,
StringTable,
)
@dataclass
class EigrpInterface:
cEigrpVrfId: int
cEigrpAS: str
cEigrpVrfName: str
cEigrpIfName: str
cEigrpPeerCount: int
cEigrpXmitReliableQ: int
cEigrpXmitUnreliableQ: int
cEigrpMeanSrtt: int
cEigrpPendingRoutes: int
cEigrpHelloInterval: int
cEigrpUMcasts: int
cEigrpUUcasts: int
cEigrpRUcasts: int
cEigrpMcastExcepts: int
cEigrpCRpkts: int
cEigrpAcksSuppressed: int
cEigrpRetransSent: int
cEigrpOOSrvcd: int
cEigrpAuthMode: str
cEigrpAuthKeyChain: str
_InetAddressType = {
0: 'unknown',
1: 'ipv4',
2: 'ipv6',
3: 'ipv4z',
4: 'ipv6z',
16: 'dns',
}
def _eigrp_authmode(mode: int) -> str:
name = {
0: 'unknown',
1: 'none',
2: 'md5',
3: 'hmac-sha-256'
}
return name.get(mode, f'unknown {mode}')
def _get_short_if_name(st: str) -> str:
names = {
'ethernet': 'Eth',
'fastethernet': 'Fa',
'gigabitethernet': 'Gi',
'tengigabitethernet': 'Te',
'fortygigabitethernet': 'Fo',
'hundredgigabitethernet': 'Hu',
'port-channel': 'Po',
'tunnel': 'Tu',
'loopback': 'Lo',
}
for item in names.keys():
if st.lower().startswith(item):
st = st.lower().replace(item, names.get(item))
return st
###########################################################################
#
# DATA Parser function
#
###########################################################################
def parse_cisco_eigrp_interface(string_table: List[StringTable]) -> Dict[str, EigrpInterface]:
EigrpInterfaces, InterfaceNames, VrfInfo = string_table
EigrpIfTable = {}
for OID_END, cEigrpPeerCount, cEigrpXmitReliableQ, cEigrpXmitUnreliableQ, cEigrpMeanSrtt, cEigrpPendingRoutes, \
cEigrpHelloInterval, cEigrpUMcasts, cEigrpRMcasts, cEigrpUUcasts, cEigrpRUcasts, cEigrpMcastExcepts, \
cEigrpCRpkts, cEigrpAcksSuppressed, cEigrpRetransSent, cEigrpOOSrvcd, cEigrpAuthMode, \
cEigrpAuthKeyChain in EigrpInterfaces:
cEigrpVrfId = int(OID_END.split('.')[0])
cEigrpAS = OID_END.split('.')[1]
cEigrpIfIndex = int(OID_END.split('.')[2])
cEigrpIfName = ''
for ifindex, ifname, iftype in InterfaceNames:
if int(ifindex) == cEigrpIfIndex: # compare interface index
if not int(iftype) == 24: # skip Loopback interfaces
cEigrpIfName = _get_short_if_name(ifname)
if cEigrpIfName != '':
cEigrpVrfName = ''
for VrfId, VrfName in VrfInfo:
if int(VrfId) == cEigrpVrfId:
cEigrpVrfName = VrfName
if cEigrpVrfId < 100000:
cEigrpAddrFammily = 'IPv4'
else:
cEigrpAddrFammily = 'IPv6'
ServiceText = ''
if cEigrpVrfName == 'default' and cEigrpAddrFammily == 'IPv4':
ServiceText = f'{cEigrpIfName} on AS {cEigrpAS}'
elif cEigrpVrfName == 'default' and cEigrpAddrFammily == 'IPv6':
ServiceText = f'{cEigrpIfName} on AS {cEigrpAS} IPv6'
elif cEigrpVrfName != 'default' and cEigrpAddrFammily == 'IPv4':
ServiceText = f'{cEigrpIfName} on AS {cEigrpAS} VRF {cEigrpVrfName}'
elif cEigrpVrfName != 'default' and cEigrpAddrFammily == 'IPv6':
ServiceText = f'{cEigrpIfName} on AS {cEigrpAS} IPv6 VRF {cEigrpVrfName}'
EigrpIfTable[ServiceText] = EigrpInterface(
cEigrpVrfId=cEigrpVrfId,
cEigrpAS=cEigrpAS,
cEigrpVrfName=cEigrpVrfName,
cEigrpIfName=cEigrpIfName,
cEigrpPeerCount=int(cEigrpPeerCount),
cEigrpXmitReliableQ=int(cEigrpXmitReliableQ),
cEigrpXmitUnreliableQ=int(cEigrpXmitUnreliableQ),
cEigrpMeanSrtt=int(cEigrpMeanSrtt),
cEigrpPendingRoutes=int(cEigrpPendingRoutes),
cEigrpHelloInterval=int(cEigrpHelloInterval),
cEigrpUMcasts=int(cEigrpUMcasts),
cEigrpUUcasts=int(cEigrpUUcasts),
cEigrpRUcasts=int(cEigrpRUcasts),
cEigrpMcastExcepts=int(cEigrpMcastExcepts),
cEigrpCRpkts=int(cEigrpCRpkts),
cEigrpAcksSuppressed=int(cEigrpAcksSuppressed),
cEigrpRetransSent=int(cEigrpRetransSent),
cEigrpOOSrvcd=int(cEigrpOOSrvcd),
cEigrpAuthMode=_eigrp_authmode(int(cEigrpAuthMode)),
cEigrpAuthKeyChain=cEigrpAuthKeyChain,
)
return EigrpIfTable
###########################################################################
#
# INVENTORY function
#
###########################################################################
def discovery_cisco_eigrp_interface(section: Dict[str, EigrpInterface]) -> DiscoveryResult:
for key in section.keys():
yield Service(item=key)
###########################################################################
#
# CHECK function
#
###########################################################################
def check_cisco_eigrp_interface(item, params, section: Dict[str, EigrpInterface]) -> CheckResult:
try:
eigrp_if = section[item]
except KeyError:
return
interface_type = 0
yield Result(state=State.OK, summary=f'Peer count: {eigrp_if.cEigrpPeerCount}, Hello interval: {eigrp_if.cEigrpHelloInterval}, Auth Mode: {eigrp_if.cEigrpAuthMode}')
md5_auth_state = params.get('md5_auth_state')
no_auth_state = params.get('no_auth_state')
if interface_type not in params.get('ignore_interfaces_auth'):
if eigrp_if.cEigrpAuthMode in ['md5'] and md5_auth_state != 0:
yield Result(state=State(md5_auth_state), notice='weak authentication set')
# yield Result(state=State.OK, notice=f'you can change the authentication mode to hmac-sha-256 by removing the eigrp authentication')
# yield Result(state=State.OK, notice=f'configuration from the interface and move it to the "router eigrp configuration"')
# yield Result(state=State.OK, notice=f'you need to change to "named mode configuration"')
# yield Result(state=State.OK, notice=f'router eigrp YOUR-EIGRP-NAME')
# yield Result(state=State.OK, notice=f' address-family ipv4 unicast autonomous-system {eigrp_if.cEigrpAS}')
# yield Result(state=State.OK, notice=f' af-interface {eigrp_if.cEigrpIfName}')
# yield Result(state=State.OK, notice=f' authentication mode hmac-sha-256 YOUR-EIGRPKEY')
# yield Result(state=State.OK, notice=f' exit-af-interface')
# yield Result(state=State.OK, notice=f' eigrp YOUR-ROUTER-ID')
# yield Result(state=State.OK, notice=f' network ....')
# yield Result(state=State.OK, notice=f'end')
elif eigrp_if.cEigrpAuthMode == 'none' and no_auth_state != 0:
yield Result(state=State(no_auth_state), notice='no authentication set')
if eigrp_if.cEigrpAuthKeyChain != '':
yield Result(state=State.OK, notice=f'Key chain: {eigrp_if.cEigrpAuthKeyChain}')
for key, value in [
('cEigrpPeerCount', eigrp_if.cEigrpPeerCount),
('cEigrpXmitReliableQ', eigrp_if.cEigrpXmitReliableQ),
('cEigrpXmitUnreliableQ', eigrp_if.cEigrpXmitUnreliableQ),
('cEigrpMeanSrtt', eigrp_if.cEigrpMeanSrtt),
('cEigrpPendingRoutes', eigrp_if.cEigrpPendingRoutes),
# ('cEigrpRMcasts', eigrp_if.cEigrpRMcasts),
('cEigrpUMcasts', eigrp_if.cEigrpUMcasts),
('cEigrpUUcasts', eigrp_if.cEigrpUUcasts),
('cEigrpRUcasts', eigrp_if.cEigrpRUcasts),
('cEigrpMcastExcepts', eigrp_if.cEigrpMcastExcepts),
('cEigrpCRpkts', eigrp_if.cEigrpCRpkts),
('cEigrpAcksSuppressed', eigrp_if.cEigrpAcksSuppressed),
('cEigrpRetransSent', eigrp_if.cEigrpRetransSent),
('cEigrpOOSrvcd', eigrp_if.cEigrpOOSrvcd),
]:
yield Metric(name=f'cisco_eigrp_interface_{key}', value=value)
###########################################################################
#
# CHECK info
#
###########################################################################
register.snmp_section(
name='cisco_eigrp_interface',
parse_function=parse_cisco_eigrp_interface,
fetch=[
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.5.1.1', # CISCO-TRUSTSEC-MIB::ctsEnvironmentDataObjects
oids=[
OIDEnd(), # AS number and interface index [0] (u'65536.10.1')
'3', # cEigrpPeerCount [1]
'4', # cEigrpXmitReliableQ [2]
'5', # cEigrpXmitUnreliableQ [3]
'6', # cEigrpMeanSrtt [4]
'10', # cEigrpPendingRoutes [5]
'11', # cEigrpHelloInterval [6]
'13', # cEigrpUMcasts [7]
'14', # cEigrpRMcasts [8]
'15', # cEigrpUUcasts [9]
'16', # cEigrpRUcasts [10]
'17', # cEigrpMcastExcepts [11]
'18', # cEigrpCRpkts [12]
'19', # cEigrpAcksSuppressed [13]
'20', # cEigrpRetransSent [14]
'21', # cEigrpOOSrvcd [15]
'22', # cEigrpAuthMode [16]
'23', # cEigrpAuthKeyChain [17]
# '7', # cEigrpPacingReliable []
# '8', # cEigrpPacingUnreliable []
# '9', # cEigrpMFlowTimer []
# '12', # cEigrpXmitNextSerial []
]
),
SNMPTree(
base='.1.3.6.1.2.1.2.2.1', #
oids=[
'1', # ifIndex
'2', # ifDescr
'3', # ifType
]
),
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.1.1.1', #
oids=[
OIDEnd(), # VRF ID
'2', # cEigrpVpnName [0]
]
),
],
detect=all_of(
contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr
exists('.1.3.6.1.4.1.9.9.449.1.5.1.1.3.*'), # CISCO-EIGRP-MIB::cEigrpPeerCount
))
register.check_plugin(
name='cisco_eigrp_interface',
service_name='EIGRP interface %s',
discovery_function=discovery_cisco_eigrp_interface,
check_function=check_cisco_eigrp_interface,
check_default_parameters={
'ignore_interfaces_auth': [24, ], # Loopback
'no_auth_state': 2,
'md5_auth_state': 1,
},
check_ruleset_name='cisco_eigrp_interface',
)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
#
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-17-20
#
# Monitor status of Cisco EIGRP peers
#
# 2018-02-11: removed unnecessary OIDs
# 2018-07-26: code cleanup, removed hold time from infotext (it is the actual time, not the configured value)
# 2018-08-06: modified scan function
# 2019-07-01: fixed uptime for peers up for more then 1 year...
# 2019-10-15: added initial support for IPv6, code cleanup (parser function)
# 2019-10-16: added VRF support, fixed ipv4 address rendering
# 2021-08-02: rewritten for CMK 2.0
#
# ToDo: state_peer_not_found, alias, min_uptime_levels in WATO
#
# snmpwalk sample
#
# thl@surfbox-ii:~$ snmpwalk -v2c -c router-01 -ObentU simulant .1.3.6.1.4.1.9.9.449.1.4.1.1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.2.65536.10.1 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.2.65536.10.2 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.2.65536.10.3 = INTEGER: 1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.3.65536.10.1 = Hex-STRING: 0A A7 DD 3A # can be also in the form of "10.10.10.10" :-(
# .1.3.6.1.4.1.9.9.449.1.4.1.1.3.65536.10.2 = Hex-STRING: 0A A7 DD 39
# .1.3.6.1.4.1.9.9.449.1.4.1.1.3.65536.10.3 = Hex-STRING: 0A A7 DD 3C
# .1.3.6.1.4.1.9.9.449.1.4.1.1.4.65536.10.1 = INTEGER: 9
# .1.3.6.1.4.1.9.9.449.1.4.1.1.4.65536.10.2 = INTEGER: 9
# .1.3.6.1.4.1.9.9.449.1.4.1.1.4.65536.10.3 = INTEGER: 9
# .1.3.6.1.4.1.9.9.449.1.4.1.1.5.65536.10.1 = Gauge32: 2
# .1.3.6.1.4.1.9.9.449.1.4.1.1.5.65536.10.2 = Gauge32: 2
# .1.3.6.1.4.1.9.9.449.1.4.1.1.5.65536.10.3 = Gauge32: 2
# .1.3.6.1.4.1.9.9.449.1.4.1.1.6.65536.10.1 = STRING: "01:05:33"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.6.65536.10.2 = STRING: "01:06:06"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.6.65536.10.3 = STRING: "01:05:57"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.7.65536.10.1 = Gauge32: 469
# .1.3.6.1.4.1.9.9.449.1.4.1.1.7.65536.10.2 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.7.65536.10.3 = Gauge32: 1
# .1.3.6.1.4.1.9.9.449.1.4.1.1.8.65536.10.1 = Gauge32: 2814
# .1.3.6.1.4.1.9.9.449.1.4.1.1.8.65536.10.2 = Gauge32: 100
# .1.3.6.1.4.1.9.9.449.1.4.1.1.8.65536.10.3 = Gauge32: 100
# .1.3.6.1.4.1.9.9.449.1.4.1.1.9.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.9.65536.10.2 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.9.65536.10.3 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.10.65536.10.1 = Gauge32: 30
# .1.3.6.1.4.1.9.9.449.1.4.1.1.10.65536.10.2 = Gauge32: 33
# .1.3.6.1.4.1.9.9.449.1.4.1.1.10.65536.10.3 = Gauge32: 24
# .1.3.6.1.4.1.9.9.449.1.4.1.1.11.65536.10.1 = STRING: "20.0/2.0"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.11.65536.10.2 = STRING: "20.0/2.0"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.11.65536.10.3 = STRING: "20.0/2.0"
# .1.3.6.1.4.1.9.9.449.1.4.1.1.12.65536.10.1 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.12.65536.10.2 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.12.65536.10.3 = Counter32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.13.65536.10.1 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.13.65536.10.2 = Gauge32: 0
# .1.3.6.1.4.1.9.9.449.1.4.1.1.13.65536.10.3 = Gauge32: 0
#
# sample info
# [
# [
# [u'65536.10.0', u'1', u'\n\xa7\xdd7', u'10', u'2', u'01:05:34', u'1', u'100', u'0', u'147', u'23.0/2.0', u'0', u'0']
# ],
# [
# [u'1', u'FastEthernet0', u'6'],
# [u'2', u'FastEthernet1', u'6'],
# [u'3', u'FastEthernet2', u'6'],
# [u'4', u'FastEthernet3', u'6'],
# [u'5', u'FastEthernet4', u'6'],
# [u'6', u'VoIP-Null0', u'1'],
# [u'7', u'Null0', u'1'],
# [u'8', u'Vlan1', u'53'],
# [u'9', u'Loopback0', u'24'],
# [u'10', u'Tunnel100', u'131']
# ]
# ]
#
import re
from dataclasses import dataclass
from typing import List, Dict
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
register,
Service,
Result,
check_levels,
State,
SNMPTree,
all_of,
contains,
exists,
OIDEnd,
Metric,
render,
)
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
DiscoveryResult,
CheckResult,
StringTable,
)
@dataclass
class EigrpPeer:
cEigrpPeerAS: str
cEigrpPeerAddr: str
cEigrpUpTimeSeconds: int
cEigrpSrtt: int
cEigrpRto: int
cEigrpPktsEnqueued: int
cEigrpRetrans: int
cEigrpRetries: int
cEigrpHoldTime: int
cEigrpVrfName: str
cEigrpVrfId: int
cEigrpAddrFammily: str
PeerInterface: str
_InetAddressType = {
0: 'unknown',
1: 'ipv4',
2: 'ipv6',
3: 'ipv4z',
4: 'ipv6z',
16: 'dns',
}
def _render_ip4_address(bytestring: str) -> str:
if len(bytestring) == 4: # byte sting length = 4 bytes
return ".".join(["%s" % ord(m) for m in bytestring])
elif len(bytestring) >= 7: # ipv4 address > 4 octets + 3 dots
return bytestring
def _shorten_ipv6_adress(address: str) -> str:
address = address.split(':')
span = 2
address = [''.join(address[i:i + span]) for i in range(0, len(address), span)]
for m in range(0, len(address)):
address[m] = re.sub(r'^0{1,3}', r'', address[m])
address = ':'.join(address)
zeros = ':0:0:0:0:0:0:'
while not zeros == '':
if zeros in address:
address = re.sub(r'%s' % zeros, r'::', address)
zeros = ''
else:
zeros = zeros[:-2]
if address == '0::0':
address = '::'
return address
def _render_ipv6_address(bytestring: str) -> str:
address = ":".join(["%02s" % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
address = _shorten_ipv6_adress(address)
return address
def _get_uptime(uptimestr: str) -> int:
uptime_in_sec = 0
if 'y' in uptimestr and 'w' in uptimestr:
uptimestr = uptimestr.split('y')
uptime_in_sec = int(uptimestr[0]) * 31536000 # 365 * 24 * 3600, one year
uptime_in_sec += int(uptimestr[1][:-1]) * 604800 # 7 * 24 * 3600, one week
if 'w' in uptimestr and 'd' in uptimestr:
uptimestr = uptimestr.split('w')
uptime_in_sec = int(uptimestr[0]) * 604800 # 7 * 24 * 3600, one week
uptime_in_sec += int(uptimestr[1][:-1]) * 86400 # 24 * 3600, on day
elif 'd' in uptimestr and 'h' in uptimestr:
uptimestr = uptimestr.split('d')
uptime_in_sec = int(uptimestr[0]) * 86400 # 24 * 3600, one day
uptime_in_sec += int(uptimestr[1][:-1]) * 3600
elif ':' in uptimestr:
uptime_in_sec = uptimestr.split(':')
if len(uptime_in_sec) == 3: # [19:20:00] hours:minutes:seconds
uptime_in_sec = (int(uptime_in_sec[0]) * 3600) + (int(uptime_in_sec[1]) * 60) + int(uptime_in_sec[2])
elif len(uptime_in_sec) == 4: # [10:19:20:00] days(?):hours:minutes:seconds
uptime_in_sec = (int(uptime_in_sec[0]) * 86400) + \
(int(uptime_in_sec[1]) * 3600) + \
(int(uptime_in_sec[2]) * 60) + \
int(uptime_in_sec[3])
return uptime_in_sec
###########################################################################
#
# DATA Parser function
#
###########################################################################
def parse_cisco_eigrp_peers(string_table: List[StringTable]) -> Dict[str, EigrpPeer]:
peers, peer_interfaces, VrfInfo = string_table
PeerTable = {}
for peer in peers:
OID_END, cEigrpPeerAddrType, cEigrpPeerAddr, cEigrpPeerIfIndex, cEigrpHoldTime, cEigrpUpTime, cEigrpSrtt, \
cEigrpRto, cEigrpPktsEnqueued, cEigrpRetrans, cEigrpRetries = peer
cEigrpVrfId = int(OID_END.split('.')[0])
cEigrpPeerAS = OID_END.split('.')[1]
cEigrpAddrFammily = int(OID_END.split('.')[2])
if int(cEigrpPeerAddrType) == 1: # IPv4 address
cEigrpPeerAddr = _render_ip4_address(cEigrpPeerAddr)
elif int(cEigrpPeerAddrType) == 2: # IPv4 address
cEigrpPeerAddr = _render_ipv6_address(cEigrpPeerAddr)
PeerInterface = ''
for ifIndex, ifDescr, ifType in peer_interfaces:
if int(cEigrpPeerIfIndex) == int(ifIndex):
PeerInterface = ifDescr
cEigrpVrfName = ''
for VrfId, VrfName in VrfInfo:
if int(VrfId) == cEigrpVrfId:
cEigrpVrfName = VrfName
if cEigrpAddrFammily == 2:
cEigrpAddrFammily = 'IPv6'
else:
cEigrpAddrFammily = 'IPv4'
if cEigrpVrfName == 'default':
ServiceText = f'{cEigrpPeerAddr} on AS {cEigrpPeerAS}'
else:
ServiceText = f'{cEigrpPeerAddr} on AS {cEigrpPeerAS}, VRF {cEigrpVrfName}'
PeerTable[ServiceText] = EigrpPeer(
cEigrpPeerAS=cEigrpPeerAS,
cEigrpPeerAddr=cEigrpPeerAddr,
cEigrpUpTimeSeconds=_get_uptime(cEigrpUpTime),
cEigrpSrtt=int(cEigrpSrtt),
cEigrpRto=int(cEigrpRto),
cEigrpPktsEnqueued=int(cEigrpPktsEnqueued),
cEigrpRetrans=int(cEigrpRetrans),
cEigrpRetries=int(cEigrpRetries),
cEigrpHoldTime=int(cEigrpHoldTime),
cEigrpVrfName=cEigrpVrfName,
cEigrpVrfId=cEigrpVrfId,
cEigrpAddrFammily=cEigrpAddrFammily,
PeerInterface=PeerInterface,
)
return PeerTable
###########################################################################
#
# INVENTORY function
#
###########################################################################
def discovery_cisco_eigrp_peers(section: Dict[str, EigrpPeer]) -> DiscoveryResult:
for key in section:
yield Service(item=key)
###########################################################################
#
# CHECK function
#
###########################################################################
def check_cisco_eigrp_peers(item, params, section: Dict[str, EigrpPeer]) -> CheckResult:
try:
peer = section[item]
except KeyError:
yield Result(state=State.CRIT, summary='Peer not found in SNMP data')
return
yield from check_levels(
label='Uptime',
value=peer.cEigrpUpTimeSeconds,
metric_name='uptime',
render_func=render.timespan,
levels_lower=params['minuptime']
)
yield Result(state=State.OK, notice=f'On interface: {peer.PeerInterface}')
yield Result(state=State.OK, notice=f'Hold time: {peer.cEigrpHoldTime}')
for key, value in [
('cEigrpPktsEnqueued', peer.cEigrpPktsEnqueued),
('cEigrpRetrans', peer.cEigrpRetrans),
('cEigrpRetries', peer.cEigrpRetries),
('cEigrpSrtt', peer.cEigrpSrtt),
('cEigrpRto', peer.cEigrpRto),
]:
yield Metric(name=f'cisco_eigrp_peers_{key}', value=value)
###########################################################################
#
# CHECK info
#
###########################################################################
register.snmp_section(
name='cisco_eigrp_peers',
parse_function=parse_cisco_eigrp_peers,
fetch=[
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.4.1.1', #
oids=[
OIDEnd(), # u'65536.10.0'
'2', # cEigrpPeerAddrType
'3', # cEigrpPeerAddr
'4', # cEigrpPeerIfIndex
'5', # cEigrpHoldTime
'6', # cEigrpUpTime
'7', # cEigrpSrtt
'8', # cEigrpRto
'9', # cEigrpPktsEnqueued
'12', # cEigrpRetrans
'13', # cEigrpRetries
# '10', # cEigrpLastSeq
# '11', # cEigrpVersion
]
),
SNMPTree(
base='.1.3.6.1.2.1.2.2.1', #
oids=[
'1', # ifIndex
'2', # ifDescr
'3', # ifType
]
),
SNMPTree(
base='.1.3.6.1.4.1.9.9.449.1.1.1.1', #
oids=[
OIDEnd(), # VRF ID
'2', # cEigrpVpnName
]
),
],
detect=all_of(
contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr
exists('.1.3.6.1.4.1.9.9.449.1.4.1.1.*'), # CISCO-EIGRP-MIB::cEigrpPeerEntry
))
register.check_plugin(
name='cisco_eigrp_peers',
service_name='EIGRP peer %s',
discovery_function=discovery_cisco_eigrp_peers,
check_function=check_cisco_eigrp_peers,
check_default_parameters={
'minuptime': (3600, 7200)
},
check_ruleset_name='cisco_eigrp_peers',
)
This diff is collapsed.
No preview for this file type
{'author': u'Th.L. (thl-cmk[at]outlook[dot]com)',
'description': u'Monitor Cisco EIGRP. Checks:\n - cisco_eigrp_peers: creates one service for the every IPv4/IPV6 peer, AS and VRF\n - cisco_eigrp_as_info: creates one service per autonomous system (AS)\n - cisco_eigrp_interface: creates one service per EIGRP enabled interface and AS\n - cisco_eigrp_topology_table: creates one service per topology table, AS and VRF\n',
{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)',
'description': 'Monitor Cisco EIGRP. Checks:\n'
' - cisco_eigrp_peers: creates one service for the every '
'IPv4/IPV6 peer, AS and VRF\n'
' - cisco_eigrp_as_info: creates one service per autonomous '
'system (AS)\n'
' - cisco_eigrp_interface: creates one service per EIGRP '
'enabled interface and AS\n'
' - cisco_eigrp_topology_table: creates one service per '
'topology table, AS and VRF\n',
'download_url': 'https://thl-cmk.hopto.org',
'files': {'checks': ['cisco_eigrp_peers',
'cisco_eigrp_as_info',
'cisco_eigrp_interface',
'cisco_eigrp_topology_table'],
'files': {'agent_based': ['cisco_eigrp_as_info.py',
'cisco_eigrp_interface.py',
'cisco_eigrp_peers.py',
'cisco_eigrp_topology_table.py'],
'web': ['plugins/wato/cisco_eigrp_peers.py',
'plugins/wato/cisco_eigrp_interface.py',
'plugins/wato/cisco_eigrp_topology_table.py',
'plugins/metrics/cisco_eigrp.py']},
'name': 'cisco_eigrp',
'num_files': 8,
'title': u'Cisco EIGRP checks',
'version': '20191021v.0.2a',
'version.min_required': '1.2.8b8',
'version.packaged': '1.4.0p35'}
\ No newline at end of file
'title': 'Cisco EIGRP checks',
'version': '20210803v.0.3',
'version.min_required': '2.0.0',
'version.packaged': '2021.07.14',
'version.usable_until': None}
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-12-27
#
# Check_MK cisco_eigrp_peer WATO plugin
#
# Author: Th.L.
# Date: 2017-12-27
#
#
#
#
from cmk.gui.i18n import _
from cmk.gui.valuespec import (
Dictionary,
Integer,
TextAscii,
Tuple,
MonitoringState,
ListChoice,
)
ignore_interfaces_auth = [
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersNetworking,
)
_ignore_interfaces_auth = [
(6, 'Ethernet CSMAD'),
(24, 'Loopback'),
(53, 'Proprietary Virtual (Cisco VLAN L3)'),
......@@ -20,19 +34,16 @@ ignore_interfaces_auth = [
(136, 'Layer 3 IP VLAN'),
]
register_check_parameters(
subgroup_networking,
'cisco_eigrp_interface',
_('Cisco EIGRP interface'),
Dictionary(
def _parameter_valuespec_cisco_eigrp_interface():
return Dictionary(
help=_(''),
elements=[
('ignore_interfaces_auth',
ListChoice(
title=_('no warning if EIRGP authentication not configured on selected interface types'),
label=_('no warning if EIRGP authentication not configured on selected interface types'),
help=_('no warning if EIRGP authentication not configured on selected interface types'),
choices=ignore_interfaces_auth,
choices=_ignore_interfaces_auth,
default_value=[],
)),
('no_auth_state',
......@@ -47,12 +58,21 @@ register_check_parameters(
('md5_auth_state',
MonitoringState(
title=_('State to report when interface uses MD5 authentication'),
help=_('State if an EIGRP enabled interface uses an MD5 hash as authentication method. Default is warning'),
help=_(
'State if an EIGRP enabled interface uses an MD5 hash as authentication method. Default is warning'),
default_value=1,
),
),
],
),
TextAscii(title=_('Cisco EIGRP interface')),
match_type='dict',
)
)
rulespec_registry.register(
CheckParameterRulespecWithItem(
check_group_name='cisco_eigrp_interface',
group=RulespecGroupCheckParametersNetworking,
item_spec=lambda: TextAscii(title=_('Cisco EIGRP interface'), ),
match_type='dict',
parameter_valuespec=_parameter_valuespec_cisco_eigrp_interface,
title=lambda: _('Cisco EIGRP interface'),
))
#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-12-25
#
# Check_MK cisco_eigrp_peer WATO plugin
#
# Author: Th.L.
# Date: 2017-12-25
#
#
#
#
register_check_parameters(
subgroup_networking,
'cisco_eigrp_peers',
_('Cisco EIGRP peer'),
Dictionary(
from cmk.gui.i18n import _
from cmk.gui.valuespec import (
Dictionary,
Integer,
TextAscii,
Tuple,
)
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersNetworking,
)
def _parameter_valuespec_cisco_eigrp_peers():
return Dictionary(
help=_(''),
elements=[
('minuptime',
Integer(
help=_('Set the time in seconds, a peer must be up before the peer is considered sable.'
'If the peer uptime less then X, the check outcome is set to warning.'),
title=_('Minimum uptime for peer. If uptime less, set check outcome to warning. Default is 1 day.'),
default_value=86400,
allow_empty=False,
unit='seconds',
minvalue=1,
),
)
Tuple(
title=_('Minimum uptime for peer. Default is 1/2 hours.'),
help=_('Set the time in seconds, a peer must be up before the peer is considered stable.'
'If the peer uptime less then X, the check outcome is set to warning/critical.'),
elements=[
Integer(title=_('Warning below'),
unit='seconds',
default_value=7200,
help=_('The uptime in seconds below which a warning state is triggered. Default is 7200s'),
),
Integer(title=_('Critical below'),
unit='seconds',
default_value=3600,
help=_('The uptime in seconds below which a critical state is triggered. default is 3600s'),
)
],
)),
],
),
TextAscii(title=_('Cisco EIGRP peer')),
match_type='dict',
)
\ No newline at end of file
)
rulespec_registry.register(
CheckParameterRulespecWithItem(
check_group_name='cisco_eigrp_peers',
group=RulespecGroupCheckParametersNetworking,
item_spec=lambda: TextAscii(title=_('Cisco EIGRP peer'), ),
match_type='dict',
parameter_valuespec=_parameter_valuespec_cisco_eigrp_peers,
title=lambda: _('Cisco EIGRP peer'),
))
#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
#
# Check_MK cisco_eigrp_topology_table WATO plugin
#
# Author: Th.L.
# Date: 2017-12-27
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2017-12-27
#
#
# Check_MK cisco_eigrp_topology_table WATO plugin
#
from cmk.gui.i18n import _
from cmk.gui.valuespec import (
Dictionary,
ListChoice,
TextAscii,
)
nowarnon = [('siaroutes', 'Stuck in active (SIA) routes'),
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersNetworking,
)
_nowarnon = [('siaroutes', 'Stuck in active (SIA) routes'),
('activeroutes', 'Active routes')]
register_check_parameters(
subgroup_networking,
'cisco_eigrp_topology_table',
_('Cisco EIGRP topology table'),
Dictionary(
def _parameter_valuespec_cisco_eigrp_topology_table():
return Dictionary(
help=_(''),
elements=[
('nowarnon',
ListChoice(
title=_('no warning if EIRGP SIA/active route found'),
label=_('no warning if EIRGP SIA/active route found'),
help=_('no warning if EIRGP Stuck in active (SIA) / active route found'),
choices=nowarnon,
choices=_nowarnon,
default_value=[],
),
)
],
),
TextAscii(title=_('Cisco EIGRP topology table')),
match_type='dict',
)
)
rulespec_registry.register(
CheckParameterRulespecWithItem(
check_group_name='cisco_eigrp_topology_table',
group=RulespecGroupCheckParametersNetworking,
item_spec=lambda: TextAscii(title=_('Cisco EIGRP topology table'), ),
match_type='dict',
parameter_valuespec=_parameter_valuespec_cisco_eigrp_topology_table,
title=lambda: _('Cisco EIGRP topology table'),
))
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment