Add three Cisco plugins (GDOI, SLA, BGP) used for BCCD-13.
This commit is contained in:
parent
0aa461839b
commit
bb424f90fe
BIN
check_mk-cisco_bgp_peer/Cisco_BGP_Peer3-1.1.mkp
Executable file
BIN
check_mk-cisco_bgp_peer/Cisco_BGP_Peer3-1.1.mkp
Executable file
Binary file not shown.
1
check_mk-cisco_bgp_peer/README.md
Normal file
1
check_mk-cisco_bgp_peer/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is a modification of a GPL plugin to additionally support CISCO-BGP4-MIB::CbgpPeer3Entry
|
@ -0,0 +1,665 @@
|
|||||||
|
#!/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-26
|
||||||
|
#
|
||||||
|
# Monitor status of Cisco BGP Peer (IPv4 and IPv6)
|
||||||
|
#
|
||||||
|
# 2018-05-24: changed counters to 1/s
|
||||||
|
# 2018-05-25: a lot of code cleanup
|
||||||
|
# packet name changed from cisco_bgp to cisco_bgp_peer
|
||||||
|
# added support of more then one address family per peer
|
||||||
|
# (changed item from remoteip to remoteip+familyname, rewrite of parer, inventory and check function)
|
||||||
|
# 2018-05-27: changed scan function from '.1.3.6.1.4.1.9.9.187.1.2.7.1.3.* to sysdecr contains cisco
|
||||||
|
# 2018-05-28: changed wato, added peer alias, state if not found, infotext values
|
||||||
|
# 2018-05-29: fixed longoutpout (removed not configured)
|
||||||
|
# 2018-11-02: modified scanfunction (from "find 'cisco' =-1" to "'cisco' in OID"
|
||||||
|
# 2019-18-02: added fix for empty values ("" instead of "0") sugested by Laurent Barbier (lbarbier[at]arkane-studios[dot]com)
|
||||||
|
# 2020-02-24: added workaround for missing cbgpPeer2AddrFamily (example L2VPN EVPN peers, Fix for jonale82[at]gmail[dot]com)
|
||||||
|
# 2020-03-02: changed handling of perfdata, add only data the are really there (not None, instead of setting them to 0)
|
||||||
|
# 2020-06-04: code cleanup --> changed isdigit test to try/except loop, changed peer.get test to try/except loop
|
||||||
|
# 2020-09-10: fixed typo in metrics file. FMS --> FSM (thanks martin[dot]pechstein[at]posteo[dot]de)
|
||||||
|
# 2021-03-27: rewrite for CMK2.0
|
||||||
|
# 2021-03-28: added warning for missing admin prefix limit/warn threshold
|
||||||
|
# 2023-01-15: modified by Spearhead Systems to support CISCO-BGP4-MIB::CbgpPeer3Entry
|
||||||
|
|
||||||
|
#
|
||||||
|
# snmpwalk sample
|
||||||
|
#
|
||||||
|
# CISCO-BGP4-MIB::cbgpPeer2AddrFamilyEntry
|
||||||
|
#
|
||||||
|
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c <removed> simulant 1.3.6.1.4.1.9.9.187.1.2.7
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.7.1.3.1.4.62.214.127.57.1.1 = STRING: "IPv4 Unicast"
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.7.1.3.1.4.217.119.208.1.1.1 = STRING: "IPv4 Unicast"
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.7.1.3.1.4.217.119.208.33.1.1 = STRING: "IPv4 Unicast"
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.7.1.3.2.16.32.1.20.56.7.0.0.39.0.0.0.0.0.0.0.1.2.1 = STRING: "IPv6 Unicast"
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.7.1.3.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = STRING: "IPv6 Unicast"
|
||||||
|
#
|
||||||
|
# CISCO-BGP4-MIB::CbgpPeer2Entry (IPv4)
|
||||||
|
#
|
||||||
|
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c <removed> simulant 1.3.6.1.4.1.9.9.187.1.2.5.1| grep 62.214.127.57
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.3.1.4.62.214.127.57 = INTEGER: 6
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.4.1.4.62.214.127.57 = INTEGER: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.5.1.4.62.214.127.57 = INTEGER: 4
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.6.1.4.62.214.127.57 = Hex-STRING: 3E D6 7F 3A
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.7.1.4.62.214.127.57 = Gauge32: 29418
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.8.1.4.62.214.127.57 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.9.1.4.62.214.127.57 = IpAddress: 217.119.208.2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.10.1.4.62.214.127.57 = Gauge32: 179
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.11.1.4.62.214.127.57 = Gauge32: 8881
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.12.1.4.62.214.127.57 = IpAddress: 62.214.127.57
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.13.1.4.62.214.127.57 = Counter32: 18
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.14.1.4.62.214.127.57 = Counter32: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.15.1.4.62.214.127.57 = Counter32: 205
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.16.1.4.62.214.127.57 = Counter32: 195
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.17.1.4.62.214.127.57 = Hex-STRING: 00 00
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.18.1.4.62.214.127.57 = Counter32: 1
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.19.1.4.62.214.127.57 = Gauge32: 10446
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.20.1.4.62.214.127.57 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.21.1.4.62.214.127.57 = INTEGER: 180
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.22.1.4.62.214.127.57 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.23.1.4.62.214.127.57 = INTEGER: 180
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.24.1.4.62.214.127.57 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.25.1.4.62.214.127.57 = INTEGER: 30
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.26.1.4.62.214.127.57 = INTEGER: 30
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.27.1.4.62.214.127.57 = Gauge32: 5824
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.28.1.4.62.214.127.57 = ""
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.29.1.4.62.214.127.57 = INTEGER: 5
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# CISCO-BGP4-MIB::CbgpPeer2Entry (IPv6)
|
||||||
|
#
|
||||||
|
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c <removed> simulant 1.3.6.1.4.1.9.9.187.1.2.5.1| grep 16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.3.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 6
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.4.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.5.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 4
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.6.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Hex-STRING: 2A 05 57 C0 00 00 FF FF 00 00 00 00 00 00 00 11
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.7.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 179
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.8.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.9.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = IpAddress: 217.119.208.2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.10.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 35062
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.11.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 31259
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.12.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = IpAddress: 217.119.208.1
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.13.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Counter32: 5
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.14.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Counter32: 6
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.15.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Counter32: 157
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.16.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Counter32: 161
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.17.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Hex-STRING: 06 04
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.18.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Counter32: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.19.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 8430
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.20.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.21.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 180
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.22.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.23.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 180
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.24.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 60
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.25.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.26.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.27.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = Gauge32: 1494
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.28.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = STRING: "Administrative Reset"
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.5.1.29.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16 = INTEGER: 5
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# CISCO-BGP4-MIB::cbgpPeer2AddrFamilyPrefixEntry (IPv4)
|
||||||
|
#
|
||||||
|
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c <removed> simulant 1.3.6.1.4.1.9.9.187.1.2.8.1| grep 16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.1.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Counter32: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.2.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.3.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 100000
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.4.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 85
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.5.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 80
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.6.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 10
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.7.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.8.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# CISCO-BGP4-MIB::cbgpPeer2AddrFamilyPrefixEntry (IPv6)
|
||||||
|
#
|
||||||
|
# OMD[mysite]:~$ snmpwalk -ObentU -v2c -c <removed> simulant 1.3.6.1.4.1.9.9.187.1.2.8.1| grep 16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.1.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Counter32: 2
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.2.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.3.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 100000
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.4.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 85
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.5.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 80
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.6.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 10
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.7.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
# .1.3.6.1.4.1.9.9.187.1.2.8.1.8.2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.16.2.1 = Gauge32: 0
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# sample info
|
||||||
|
#
|
||||||
|
# [
|
||||||
|
# [
|
||||||
|
# ['1.4.77.235.182.229', '6', '2', 'M\xeb\xb6\xe6', '0', '217.119.208.1', '21413', '77.235.182.229', '1', '3', '48',
|
||||||
|
# '53', '\x04\x00', '8', '2581', '2581', 'hold time expired', '5'],
|
||||||
|
# ['1.4.217.119.208.2', '6', '2', '\xd9w\xd0\x01', '0', '217.119.208.1', '31259', '217.119.208.2', '11', '23', '168',
|
||||||
|
# '170', '\x06\x04', '3', '8380', '5774', 'Administrative Reset', '5'],
|
||||||
|
# ['1.4.217.119.208.34', '6', '2', '\xd9w\xd0!', '0', '217.119.208.1', '31259', '217.119.208.2', '11', '23', '168',
|
||||||
|
# '170', '\x06\x04', '3', '8377', '5774', 'Administrative Reset', '5'],
|
||||||
|
# ['2.16.42.0.28.160.16.0.1.53.0.0.0.0.0.0.0.1', '6', '2', '*\x00\x1c\xa0\x10\x00\x015\x00\x00\x00\x00\x00\x00\x00\x02',
|
||||||
|
# '0', '217.119.208.1', '21413', '77.235.182.229', '0', '4', '108', '121', '\x06\x04', '6', '6295', '0',
|
||||||
|
# 'Administrative Reset', '5'],
|
||||||
|
# ['2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17', '6', '2', '*\x05W\xc0\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x10',
|
||||||
|
# '0', '217.119.208.1', '31259', '217.119.208.2', '6', '5', '160', '157', '\x06\x04', '2', '8380', '1409',
|
||||||
|
# 'Administrative Reset', '5']
|
||||||
|
# ],
|
||||||
|
# [
|
||||||
|
# ['1.4.77.235.182.229.1.1', 'IPv4 Unicast', '1', '0', '', '', '', '6', '0', '0'],
|
||||||
|
# ['1.4.217.119.208.2.1.1', 'IPv4 Unicast', '4', '0', '', '', '', '17', '0', '10'],
|
||||||
|
# ['1.4.217.119.208.34.1.1', 'IPv4 Unicast', '4', '0', '', '', '', '17', '0', '10'],
|
||||||
|
# ['2.16.42.0.28.160.16.0.1.53.0.0.0.0.0.0.0.1.2.1', 'IPv6 Unicast', '0', '0', '100000', '85', '80', '6', '0', '0'],
|
||||||
|
# ['2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17.2.1', 'IPv6 Unicast', '2', '0', '100000', '85', '80', '8', '0', '0']
|
||||||
|
# ]
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import re, time
|
||||||
|
from typing import Mapping, Dict, List, Tuple, NamedTuple
|
||||||
|
|
||||||
|
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
|
||||||
|
DiscoveryResult,
|
||||||
|
CheckResult,
|
||||||
|
StringTable,
|
||||||
|
)
|
||||||
|
|
||||||
|
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
|
||||||
|
register,
|
||||||
|
Service,
|
||||||
|
Result,
|
||||||
|
check_levels,
|
||||||
|
State,
|
||||||
|
SNMPTree,
|
||||||
|
contains,
|
||||||
|
OIDEnd,
|
||||||
|
get_rate,
|
||||||
|
get_value_store,
|
||||||
|
Metric,
|
||||||
|
render,
|
||||||
|
)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Section:
|
||||||
|
peer_prefixes: dict
|
||||||
|
peer_table: dict
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# DATA Parser function
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
|
||||||
|
def bgp_render_ipv4_address(bytestring):
|
||||||
|
return ".".join(["%s" % ord(m) for m in bytestring])
|
||||||
|
|
||||||
|
def bgp_shorten_ipv6_adress(address):
|
||||||
|
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]
|
||||||
|
return address
|
||||||
|
|
||||||
|
def bgp_render_ipv6_address(bytestring):
|
||||||
|
address = ":".join(["%02s" % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
|
||||||
|
address = bgp_shorten_ipv6_adress(address)
|
||||||
|
|
||||||
|
return address
|
||||||
|
|
||||||
|
def bgp_render_ip_address(bytestring):
|
||||||
|
if len(bytestring) == 4:
|
||||||
|
return bgp_render_ipv4_address(bytestring)
|
||||||
|
elif len(bytestring) == 16:
|
||||||
|
return bgp_render_ipv6_address(bytestring)
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def cisco_bgp_get_peer(OID_END):
|
||||||
|
# returns peer address string from OID_END
|
||||||
|
# u'1.4.217.119.208.34.1.1' --> 217.119.208.34
|
||||||
|
# u'2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17.2.1' --> 42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17
|
||||||
|
peer_ip = ''
|
||||||
|
OID_END = OID_END.split('.')
|
||||||
|
if int(len(OID_END)) == 7: # length of ip address
|
||||||
|
peer_ip = '.'.join(OID_END[3:7]) # ipv4 address
|
||||||
|
elif int(OID_END[1]) == 16: # ipv6 address
|
||||||
|
peer_ip = ':'.join('%02s' % hex(int(m))[2:] for m in OID_END[2:18]).replace(' ', '0').upper()
|
||||||
|
peer_ip = bgp_shorten_ipv6_adress(peer_ip)
|
||||||
|
|
||||||
|
return peer_ip
|
||||||
|
|
||||||
|
def cisco_bgp_errors(bytestring):
|
||||||
|
lasterrorhex = ''.join(["%02X " % ord(x) for x in bytestring]).strip()
|
||||||
|
byte1, byte2 = lasterrorhex.split()
|
||||||
|
|
||||||
|
names = {}
|
||||||
|
names[0] = {0: 'NO ERROR'}
|
||||||
|
names[1] = {0: 'Message',
|
||||||
|
2: 'Connection Not Synchronized',
|
||||||
|
3: 'Bad Message Length',
|
||||||
|
4: 'Bad Message Type',
|
||||||
|
}
|
||||||
|
names[2] = {0: 'OPEN',
|
||||||
|
1: 'Unsupported Version Number',
|
||||||
|
2: 'Bad Peer AS',
|
||||||
|
3: 'Bad BGP Identifier',
|
||||||
|
4: 'Unsupported Optional Parameter',
|
||||||
|
5: 'Authentication Failure',
|
||||||
|
6: 'Unacceptable Hold',
|
||||||
|
}
|
||||||
|
names[3] = {0: 'UPDATE',
|
||||||
|
1: 'Malformed Attribute List',
|
||||||
|
2: 'Unrecognized Well-known Attribute',
|
||||||
|
3: 'Missing Well-known Attribute',
|
||||||
|
4: 'Attribute Flags Error',
|
||||||
|
5: 'Attribute Length Error',
|
||||||
|
6: 'Invalid ORIGIN Attribute',
|
||||||
|
7: 'AS Routing Loop',
|
||||||
|
8: 'Invalid NEXT_HOP Attribute',
|
||||||
|
9: 'Optional Attribute Error',
|
||||||
|
10: 'Invalid Network Field',
|
||||||
|
11: 'Malformed AS_PATH',
|
||||||
|
}
|
||||||
|
names[4] = {0: 'Hold Timer Expired', }
|
||||||
|
|
||||||
|
names[5] = {0: 'Finite State Machine Error', }
|
||||||
|
|
||||||
|
names[6] = {0: 'Administratively Shutdown',
|
||||||
|
1: 'Max Prefix Reached',
|
||||||
|
2: 'Peer Unconfigured',
|
||||||
|
3: 'Administratively Reset',
|
||||||
|
4: 'Connection Rejected',
|
||||||
|
5: 'Other Configuration Change',
|
||||||
|
}
|
||||||
|
|
||||||
|
return names[int(byte1, 16)].get(int(byte2, 16))
|
||||||
|
|
||||||
|
# bgp not active
|
||||||
|
if not string_table == [[], [], []]:
|
||||||
|
|
||||||
|
cbgpPeer2Entry, cbgpPeer3Entry, cbgpPeer2AddrFamily = string_table
|
||||||
|
cbgpPeerEntry = cbgpPeer2Entry + cbgpPeer3Entry
|
||||||
|
|
||||||
|
peer_prefixes = {}
|
||||||
|
# create dictionary from cbgpPeer2AddrFamily ('remoteip addrfamilyname' as index)
|
||||||
|
if len(cbgpPeer2AddrFamily) > 0:
|
||||||
|
for entry in cbgpPeer2AddrFamily:
|
||||||
|
oid_end, addrfamilyname, acceptedprefixes, deniedprefixes, prefixadminlimit, prefixthreshold, \
|
||||||
|
prefixclearthreshold, advertisedprefixes, suppressedprefixes, withdrawnprefixes = entry
|
||||||
|
|
||||||
|
remoteaddr = cisco_bgp_get_peer(entry[0])
|
||||||
|
peer = {
|
||||||
|
'remoteaddr': remoteaddr,
|
||||||
|
'addrfamilyname': addrfamilyname
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in [
|
||||||
|
('prefixadminlimit', prefixadminlimit),
|
||||||
|
('prefixthreshold', prefixthreshold),
|
||||||
|
('prefixclearthreshold', prefixclearthreshold),
|
||||||
|
('acceptedprefixes', acceptedprefixes),
|
||||||
|
('advertisedprefixes', advertisedprefixes),
|
||||||
|
('deniedprefixes', deniedprefixes),
|
||||||
|
('suppressedprefixes', suppressedprefixes),
|
||||||
|
('withdrawnprefixes', withdrawnprefixes),
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
peer[key] = int(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
peer_prefixes.update({'%s %s' % (remoteaddr, addrfamilyname): peer})
|
||||||
|
|
||||||
|
# workaround: get remote ip from cbgpPeerEntry if cbgpPeer2AddrFamilyName is missing :-(
|
||||||
|
elif len(cbgpPeerEntry) > 0:
|
||||||
|
for entry in cbgpPeerEntry:
|
||||||
|
remoteaddr = cisco_bgp_get_peer(entry[0])
|
||||||
|
addrfamilyname = ''
|
||||||
|
|
||||||
|
peer = {'remoteaddr': remoteaddr, }
|
||||||
|
|
||||||
|
peer_prefixes.update({'%s %s' % (remoteaddr, addrfamilyname): peer})
|
||||||
|
|
||||||
|
# create dictionary from cbgpPeerEntry (peer ip address as index)
|
||||||
|
peer_table = {}
|
||||||
|
for entry in cbgpPeerEntry:
|
||||||
|
oid_end, state, adminstatus, localaddr, localas, localidentifier, remoteas, remoteidentifier, inupdates, \
|
||||||
|
outupdates, intotalmessages, outtotalmessages, lasterror, fsmestablishedtransitions, fsmestablishedtime, \
|
||||||
|
inupdateelapsedtime, lasterrortxt, prevstate = entry
|
||||||
|
|
||||||
|
peer = {'remoteaddr': cisco_bgp_get_peer(oid_end),
|
||||||
|
'localaddr': bgp_render_ip_address(localaddr),
|
||||||
|
'localid': localidentifier,
|
||||||
|
'remoteid': remoteidentifier,
|
||||||
|
'lasterror': cisco_bgp_errors(lasterror),
|
||||||
|
'lasterrortxt': lasterrortxt,
|
||||||
|
'prevstate': int(prevstate),
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in [
|
||||||
|
('state', state),
|
||||||
|
('adminstate', adminstatus),
|
||||||
|
('localas', localas),
|
||||||
|
('remoteas', remoteas),
|
||||||
|
('inupdates', inupdates),
|
||||||
|
('outupdates', outupdates),
|
||||||
|
('intotalmessages', intotalmessages),
|
||||||
|
('outtotalmessages', outtotalmessages),
|
||||||
|
('fsmestablishedtransitions', fsmestablishedtransitions),
|
||||||
|
('fsmestablishedtime', fsmestablishedtime),
|
||||||
|
('inupdateelapsedtime', inupdateelapsedtime),
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
peer[key] = int(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
peer_table.update({'%s' % cisco_bgp_get_peer(oid_end): peer})
|
||||||
|
|
||||||
|
return Section(
|
||||||
|
peer_prefixes=peer_prefixes,
|
||||||
|
peer_table=peer_table,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# INVENTORY function
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def discovery_cisco_bgp_peer(section: Section) -> DiscoveryResult:
|
||||||
|
for key in section.peer_prefixes.keys():
|
||||||
|
yield Service(item=key)
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# CHECK function
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def check_cisco_bgp_peer(item, params, section) -> CheckResult:
|
||||||
|
def cisco_bgp_adminstate(state):
|
||||||
|
names = {1: 'stop',
|
||||||
|
2: 'start', }
|
||||||
|
return names.get(state, 'unknown (%s)' % state)
|
||||||
|
|
||||||
|
def cisco_bgp_peerstate(state):
|
||||||
|
names = {0: 'none',
|
||||||
|
1: 'idle',
|
||||||
|
2: 'connect',
|
||||||
|
3: 'active',
|
||||||
|
4: 'opensned',
|
||||||
|
5: 'openconfirm',
|
||||||
|
6: 'established'}
|
||||||
|
return names.get(state, 'unknown (%s)' % state)
|
||||||
|
|
||||||
|
peer_prefixes = section.peer_prefixes
|
||||||
|
peer_table = section.peer_table
|
||||||
|
|
||||||
|
prefixes = peer_prefixes.get(item, None)
|
||||||
|
|
||||||
|
alias = ''
|
||||||
|
peer_not_found_state = 3
|
||||||
|
|
||||||
|
for bgp_connection, bgp_alias, not_found_state in params.get('peer_list', []):
|
||||||
|
if item == bgp_connection:
|
||||||
|
alias = bgp_alias
|
||||||
|
peer_not_found_state = not_found_state
|
||||||
|
|
||||||
|
if prefixes:
|
||||||
|
longoutput = ''
|
||||||
|
|
||||||
|
peer = peer_table.get(prefixes.get('remoteaddr'))
|
||||||
|
|
||||||
|
if peer.get('localas') == 0:
|
||||||
|
peer.update({'localas': params.get('useaslocalas')})
|
||||||
|
|
||||||
|
if alias != '':
|
||||||
|
yield Result(state=State.OK, summary='Alias: %s' % alias)
|
||||||
|
|
||||||
|
peerstate = peer.get('state')
|
||||||
|
adminstate = peer.get('adminstate')
|
||||||
|
establishedtime = peer.get('fsmestablishedtime')
|
||||||
|
|
||||||
|
if peerstate == 1: # idle
|
||||||
|
yield Result(state=State.CRIT, summary='Peer state: %s' % cisco_bgp_peerstate(peerstate))
|
||||||
|
elif peerstate == 6: # established
|
||||||
|
yield from check_levels(
|
||||||
|
value=establishedtime,
|
||||||
|
label='Uptime',
|
||||||
|
levels_lower=params['minuptime'],
|
||||||
|
render_func=render.timespan
|
||||||
|
)
|
||||||
|
|
||||||
|
else: # everything else
|
||||||
|
yield Result(state=State.WARN, summary='Peer state: %s' % cisco_bgp_peerstate(peerstate))
|
||||||
|
|
||||||
|
if not adminstate == 2: # not start
|
||||||
|
yield Result(state=State.WARN, summary='Admin state: %s' % cisco_bgp_adminstate(adminstate))
|
||||||
|
|
||||||
|
for key, value in [
|
||||||
|
('remoteid', 'Remote ID: %s'),
|
||||||
|
('remoteas', 'Remote AS: %s'),
|
||||||
|
('localaddr', 'Local address: %s'),
|
||||||
|
('localid', 'Local ID: %s'),
|
||||||
|
('localas', 'Local AS: %s'),
|
||||||
|
]:
|
||||||
|
if key in params['infotext_values']:
|
||||||
|
try:
|
||||||
|
yield Result(state=State.OK, summary=value % peer[key])
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
bgptype = ''
|
||||||
|
if not peer.get('localas') == 0:
|
||||||
|
if peer.get('remoteas') == peer.get('localas'):
|
||||||
|
bgptype = ' (iBGP)'
|
||||||
|
else:
|
||||||
|
bgptype = ' (eBGP)'
|
||||||
|
|
||||||
|
longoutput_data = [
|
||||||
|
['IP-address (remote/local)', peer.get('remoteaddr'), peer.get('localaddr')],
|
||||||
|
['Router-ID (remote/local)', peer.get('remoteid'), peer.get('localid')],
|
||||||
|
['Autonomus System (remote/local)', peer.get('remoteas'), str(peer.get('localas')) + bgptype],
|
||||||
|
['State', cisco_bgp_peerstate(peerstate), ''],
|
||||||
|
['Admin state', cisco_bgp_adminstate(adminstate), ''],
|
||||||
|
['Last error', peer.get('lasterror'), ''],
|
||||||
|
['Last error text', peer.get('lasterrortxt'), ''],
|
||||||
|
['Previous state', cisco_bgp_peerstate(peer.get('prevstate')), ''],
|
||||||
|
['Address family name', prefixes.get('addrfamilyname', 'unknown'), ''],
|
||||||
|
['Prefix clear threshold (%)', '%.0d' % prefixes.get('prefixclearthreshold', 0), '']
|
||||||
|
,
|
||||||
|
]
|
||||||
|
|
||||||
|
acceptedprefixes = prefixes.get('acceptedprefixes', None)
|
||||||
|
prefixadminlimit = prefixes.get('prefixadminlimit', None)
|
||||||
|
prefixthreshold = prefixes.get('prefixthreshold', None)
|
||||||
|
|
||||||
|
if prefixadminlimit is not None and prefixthreshold is not None:
|
||||||
|
warnthreshold = prefixadminlimit / 100.0 * prefixthreshold # use float (100.0) to get xx.xx in division
|
||||||
|
longoutput_data.append(['Prefix admin limit (prefixes)', '%.0d' % prefixadminlimit, ''])
|
||||||
|
longoutput_data.append(['Prefix threshold (prefixes/%)', '%.0d' % warnthreshold, '%.0d' % prefixthreshold])
|
||||||
|
else:
|
||||||
|
yield Result(state=State(params['noprefixlimit']), notice='No admin prefix limit/warn threshold configured on the device.')
|
||||||
|
warnthreshold = None
|
||||||
|
|
||||||
|
if params.get('htmloutput', False):
|
||||||
|
#
|
||||||
|
# disable 'Escape HTML codes in plugin output' in wato --> global settings
|
||||||
|
#
|
||||||
|
table_bracket = '<table border="1">%s</table>'
|
||||||
|
line_bracket = '<tr>%s</tr>'
|
||||||
|
cell_bracket = '<td>%s</td><td>%s</td><td>%s</td>'
|
||||||
|
cell_seperator = ''
|
||||||
|
|
||||||
|
longoutput = '\n' + table_bracket % (''.join(
|
||||||
|
[line_bracket % cell_seperator.join([cell_bracket % (entry[0], entry[1], entry[2])]) for entry in
|
||||||
|
longoutput_data]))
|
||||||
|
else:
|
||||||
|
longoutput += '\nfor nicer output' \
|
||||||
|
'\ndisable \'Escape HTML codes in plugin output\' in wato -> global settings and enable HTML output in \'Parameters for this service\''
|
||||||
|
for entry in longoutput_data:
|
||||||
|
if not entry[2] == '':
|
||||||
|
longoutput += '\n{}: {} / {}'.format(entry[0], entry[1], entry[2])
|
||||||
|
else:
|
||||||
|
longoutput += '\n{}: {}'.format(entry[0], entry[1])
|
||||||
|
|
||||||
|
if prefixadminlimit is not None:
|
||||||
|
yield from check_levels(
|
||||||
|
value=acceptedprefixes,
|
||||||
|
metric_name='cisco_bgp_peer_acceptedprefixes',
|
||||||
|
levels_upper=(warnthreshold, prefixadminlimit),
|
||||||
|
label='Prefixes accepted',
|
||||||
|
render_func=lambda v: '%s' % str(v)
|
||||||
|
)
|
||||||
|
|
||||||
|
now_time = time.time()
|
||||||
|
value_store = get_value_store()
|
||||||
|
rate_item = item.replace(' ', '_').replace(':', '_')
|
||||||
|
|
||||||
|
for key in [
|
||||||
|
'deniedprefixes',
|
||||||
|
'advertisedprefixes',
|
||||||
|
'withdrawnprefixes',
|
||||||
|
'suppressedprefixes',
|
||||||
|
'inupdates',
|
||||||
|
'outupdates',
|
||||||
|
'intotalmessages',
|
||||||
|
'outtotalmessages',
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
value = get_rate(value_store, 'cisco_bgp_peer.%s.%s' % (key, rate_item), now_time, prefixes[key],
|
||||||
|
raise_overflow=False)
|
||||||
|
yield Metric(name='cisco_bgp_peer_%s' % key, value=value, boundaries=(0, None))
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for key in [
|
||||||
|
'fsmestablishedtransitions',
|
||||||
|
'fsmestablishedtime',
|
||||||
|
'inupdateelapsedtime'
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
yield Metric(name='cisco_bgp_peer_%s' % key, value=peer[key], boundaries=(0, None))
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
yield Result(state=State.OK, notice=longoutput)
|
||||||
|
else:
|
||||||
|
if alias != '':
|
||||||
|
yield Result(state=State.OK, summary=', Alias: %s' % alias)
|
||||||
|
yield Result(state=State(peer_not_found_state), summary='Item not found in SNMP data')
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# CHECK info
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
register.snmp_section(
|
||||||
|
name='cisco_bgp_peer',
|
||||||
|
parse_function=parse_cisco_bgp_peer,
|
||||||
|
fetch=[
|
||||||
|
SNMPTree(
|
||||||
|
base='.1.3.6.1.4.1.9.9.187.1.2.5.1', # CCISCO-BGP4-MIB::cbgpPeer2Entry
|
||||||
|
oids=[
|
||||||
|
OIDEnd(),
|
||||||
|
'3', # cbgpPeer2State
|
||||||
|
'4', # cbgpPeer2AdminStatus
|
||||||
|
'6', # cbgpPeer2LocalAddr
|
||||||
|
'8', # cbgpPeer2LocalAs -> empty
|
||||||
|
'9', # cbgpPeer2LocalIdentifier
|
||||||
|
'11', # cbgpPeer2RemoteAs
|
||||||
|
'12', # cbgpPeer2RemoteIdentifier
|
||||||
|
'13', # cbgpPeer2InUpdates
|
||||||
|
'14', # cbgpPeer2OutUpdates
|
||||||
|
'15', # cbgpPeer2InTotalMessages
|
||||||
|
'16', # cbgpPeer2OutTotalMessages
|
||||||
|
'17', # cbgpPeer2LastError
|
||||||
|
'18', # cbgpPeer2FsmEstablishedTransitions
|
||||||
|
'19', # cbgpPeer2FsmEstablishedTime
|
||||||
|
'27', # cbgpPeer2InUpdateElapsedTime
|
||||||
|
'28', # cbgpPeer2LastErrorTxt
|
||||||
|
'29', # cbgpPeer2PrevState
|
||||||
|
]
|
||||||
|
),
|
||||||
|
SNMPTree(
|
||||||
|
base='.1.3.6.1.4.1.9.9.187.1.2.9.1', # CCISCO-BGP4-MIB::cbgpPeer3Entry
|
||||||
|
oids=[
|
||||||
|
OIDEnd(),
|
||||||
|
'5', # cbgpPeer3State
|
||||||
|
'6', # cbgpPeer3AdminStatus
|
||||||
|
'8', # cbgpPeer3LocalAddr
|
||||||
|
'10', # cbgpPeer3LocalAs -> empty
|
||||||
|
'11', # cbgpPeer3LocalIdentifier
|
||||||
|
'13', # cbgpPeer3RemoteAs
|
||||||
|
'14', # cbgpPeer3RemoteIdentifier
|
||||||
|
'15', # cbgpPeer3InUpdates
|
||||||
|
'16', # cbgpPeer3OutUpdates
|
||||||
|
'17', # cbgpPeer3InTotalMessages
|
||||||
|
'18', # cbgpPeer3OutTotalMessages
|
||||||
|
'19', # cbgpPeer3LastError
|
||||||
|
'20', # cbgpPeer3FsmEstablishedTransitions
|
||||||
|
'21', # cbgpPeer3FsmEstablishedTime
|
||||||
|
'29', # cbgpPeer3InUpdateElapsedTime
|
||||||
|
'30', # cbgpPeer3LastErrorTxt
|
||||||
|
'31', # cbgpPeer3PrevState
|
||||||
|
]
|
||||||
|
),
|
||||||
|
SNMPTree(
|
||||||
|
base='.1.3.6.1.4.1.9.9.187.1.2', # cbgpPeer
|
||||||
|
oids=[
|
||||||
|
OIDEnd(), #
|
||||||
|
# .7.1 --> cbgpPeer2AddrFamilyEntry
|
||||||
|
'7.1.3', # cbgpPeer2AddrFamilyName
|
||||||
|
# .8.1 --> cbgpPeer2AddrFamilyPrefixEntry
|
||||||
|
'8.1.1', # cbgpPeer2AcceptedPrefixes
|
||||||
|
'8.1.2', # cbgpPeer2DeniedPrefixes
|
||||||
|
'8.1.3', # cbgpPeer2PrefixAdminLimit
|
||||||
|
'8.1.4', # cbgpPeer2PrefixThreshold
|
||||||
|
'8.1.5', # cbgpPeer2PrefixClearThreshold
|
||||||
|
'8.1.6', # cbgpPeer2AdvertisedPrefixes
|
||||||
|
'8.1.7', # cbgpPeer2SuppressedPrefixes
|
||||||
|
'8.1.8', # cbgpPeer2WithdrawnPrefixes
|
||||||
|
]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
detect=contains('.1.3.6.1.2.1.1.1.0', 'Cisco'),
|
||||||
|
)
|
||||||
|
|
||||||
|
register.check_plugin(
|
||||||
|
name='cisco_bgp_peer',
|
||||||
|
service_name='Cisco BGP peer %s',
|
||||||
|
discovery_function=discovery_cisco_bgp_peer,
|
||||||
|
check_function=check_cisco_bgp_peer,
|
||||||
|
check_default_parameters={
|
||||||
|
'minuptime': (7200, 3600),
|
||||||
|
'useaslocalas': 0,
|
||||||
|
'htmloutput': False,
|
||||||
|
'noprefixlimit': 1,
|
||||||
|
'infotext_values': [],
|
||||||
|
'peer_list': [],
|
||||||
|
},
|
||||||
|
check_ruleset_name='cisco_bgp_peer',
|
||||||
|
)
|
@ -0,0 +1,178 @@
|
|||||||
|
#!/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-26
|
||||||
|
#
|
||||||
|
# Cisco BGP Peer metrics plugin
|
||||||
|
#
|
||||||
|
# 2018-05-25: cleanup
|
||||||
|
# 2020-09-10: fixed typo FMS --> FSM (Thanks martin[dot]pechstein[at]posteo[dot]de)
|
||||||
|
# 2021-03-27: rewrite for CMK 2.0
|
||||||
|
#
|
||||||
|
from cmk.gui.i18n import _
|
||||||
|
|
||||||
|
from cmk.gui.plugins.metrics import (
|
||||||
|
metric_info,
|
||||||
|
graph_info,
|
||||||
|
perfometer_info
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#####################################################################################################################
|
||||||
|
#
|
||||||
|
# define metrics for bgp peer perfdata
|
||||||
|
#
|
||||||
|
#####################################################################################################################
|
||||||
|
|
||||||
|
metric_info['cisco_bgp_peer_acceptedprefixes'] = {
|
||||||
|
'title': _('Prefixes accepted'),
|
||||||
|
'help': _('number of accepted prefixes'),
|
||||||
|
'unit': 'count',
|
||||||
|
'color': '11/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_deniedprefixes'] = {
|
||||||
|
'title': _('Prefixes denied'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '21/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_advertisedprefixes'] = {
|
||||||
|
'title': _('Prefixes advertised'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '31/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_withdrawnprefixes'] = {
|
||||||
|
'title': _('Prefixes withdrawn'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '41/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_suppressedprefixes'] = {
|
||||||
|
'title': _('Prefixes suppressed'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '12/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_inupdates'] = {
|
||||||
|
'title': _('Updates received'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '22/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_outupdates'] = {
|
||||||
|
'title': _('Updates send'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '32/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_intotalmessages'] = {
|
||||||
|
'title': _('Total messages received'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '42/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_outtotalmessages'] = {
|
||||||
|
'title': _('Total messages send'),
|
||||||
|
'unit': '1/s',
|
||||||
|
'color': '13/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_fsmestablishedtransitions'] = {
|
||||||
|
'title': _('FSM transitions'),
|
||||||
|
'unit': 'count',
|
||||||
|
'color': '23/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_fsmestablishedtime'] = {
|
||||||
|
'title': _('FSM last change'),
|
||||||
|
'unit': 's',
|
||||||
|
'color': '26/a',
|
||||||
|
}
|
||||||
|
metric_info['cisco_bgp_peer_inupdateelapsedtime'] = {
|
||||||
|
'title': _('Last update received'),
|
||||||
|
'unit': 's',
|
||||||
|
'color': '43/a',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################################################################
|
||||||
|
#
|
||||||
|
# how to graph perdata for bgp peer
|
||||||
|
#
|
||||||
|
######################################################################################################################
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.prefixes_accepted']={
|
||||||
|
'title': _('Accepted Prefixes'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_acceptedprefixes', 'line'),
|
||||||
|
],
|
||||||
|
'scalars': [
|
||||||
|
('cisco_bgp_peer_acceptedprefixes:crit', _('crit')),
|
||||||
|
('cisco_bgp_peer_acceptedprefixes:warn', _('warn')),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.prefixes_per_second']={
|
||||||
|
'title': _('Prefixes/s'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_deniedprefixes', 'line'),
|
||||||
|
('cisco_bgp_peer_advertisedprefixes', 'line'),
|
||||||
|
('cisco_bgp_peer_withdrawnprefixes', 'line'),
|
||||||
|
('cisco_bgp_peer_suppressedprefixes', 'line'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.updates_in_out']={
|
||||||
|
'title': _('Updates'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_inupdates', 'area'),
|
||||||
|
('cisco_bgp_peer_outupdates', '-area'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.messages_in_out']={
|
||||||
|
'title': _('Total messages'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_intotalmessages', 'area'),
|
||||||
|
('cisco_bgp_peer_outtotalmessages', '-area'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.fms_transitions_from_to']={
|
||||||
|
'title': _('FSM transitions from/to established'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_fsmestablishedtransitions', 'line'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.fms_transitions_last_change']={
|
||||||
|
'title': _('FSM established last change'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_fsmestablishedtime', 'line'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_info['cisco_bgp_peer.time_since_last_update']={
|
||||||
|
'title': _('Time since last update received'),
|
||||||
|
'metrics': [
|
||||||
|
('cisco_bgp_peer_inupdateelapsedtime', 'line'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################################################################
|
||||||
|
#
|
||||||
|
# define perf-o-meter for bgp peer uptime + prefixes accepted/advertised
|
||||||
|
#
|
||||||
|
######################################################################################################################
|
||||||
|
|
||||||
|
perfometer_info.append(('stacked', [
|
||||||
|
{
|
||||||
|
'type': 'logarithmic',
|
||||||
|
'metric': 'cisco_bgp_peer_fsmestablishedtime',
|
||||||
|
'half_value': 2592000.0, # ome month
|
||||||
|
'exponent': 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'logarithmic',
|
||||||
|
'metric': 'cisco_bgp_peer_acceptedprefixes',
|
||||||
|
'half_value': 500000.0,
|
||||||
|
'exponent': 2,
|
||||||
|
}
|
||||||
|
]))
|
@ -0,0 +1,126 @@
|
|||||||
|
#!/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_bgp_peers WATO plugin
|
||||||
|
#
|
||||||
|
# 2021-03-27: rewrite for CMK 2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
from cmk.gui.i18n import _
|
||||||
|
from cmk.gui.valuespec import (
|
||||||
|
Dictionary,
|
||||||
|
Integer,
|
||||||
|
TextAscii,
|
||||||
|
ListOfStrings,
|
||||||
|
FixedValue,
|
||||||
|
ListChoice,
|
||||||
|
ListOf,
|
||||||
|
Tuple,
|
||||||
|
TextUnicode,
|
||||||
|
MonitoringState,
|
||||||
|
)
|
||||||
|
|
||||||
|
from cmk.gui.plugins.wato import (
|
||||||
|
CheckParameterRulespecWithItem,
|
||||||
|
rulespec_registry,
|
||||||
|
RulespecGroupCheckParametersNetworking,
|
||||||
|
)
|
||||||
|
|
||||||
|
cisco_bgp_peer_infotext_values = [
|
||||||
|
('remoteid', 'Remote router ID'),
|
||||||
|
('remoteas', 'Remote autonomous system'),
|
||||||
|
('localaddr', 'Local peer IP address'),
|
||||||
|
('localid', 'Local router ID'),
|
||||||
|
('localas', 'Local autonomous system'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _parameter_valuespec_cisco_bgp_peer():
|
||||||
|
return Dictionary(elements=[
|
||||||
|
('minuptime',
|
||||||
|
Tuple(
|
||||||
|
title=_('Minimum uptime for peer'),
|
||||||
|
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.'),
|
||||||
|
elements=[
|
||||||
|
Integer(title=_('Warning if below'), unit='seconds', default_value=7200, minvalue=0),
|
||||||
|
Integer(title=_('Critical if below'), unit='seconsa', default_value=3600, minvalue=0)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
('useaslocalas',
|
||||||
|
Integer(
|
||||||
|
help=_('Use this AS number if the SNMP Value for CISCO-BGP4-MIB::cbgpPeer2LocalAs is \'0\'.'),
|
||||||
|
title=_('Use AS as local AS, if SNMP cbgpPeer2LocalAs is not valid.'),
|
||||||
|
default_value=0,
|
||||||
|
# allow_empty=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
('htmloutput',
|
||||||
|
FixedValue(
|
||||||
|
True,
|
||||||
|
help=_('render long output of check plugin (multiline) as HTML table. Needs \'Escape HTML codes in plugin output\' in wato --> global settings disabled'),
|
||||||
|
title=_('enable HTML Output for long output of check plugin (multiline)'),
|
||||||
|
totext=_('enable HTML Output for long output of check plugin (multiline)'),
|
||||||
|
default_value=False,
|
||||||
|
)),
|
||||||
|
('noprefixlimit',
|
||||||
|
MonitoringState(
|
||||||
|
default_value=1,
|
||||||
|
title=_('State if no admin prefix limit/warn threshold configured.'),
|
||||||
|
help=_('The admin prefix limit and warn threshold needs to be configured on the device. '
|
||||||
|
'For example: neighbor 172.17.10.10 maximum-prefix 10000 80. The threshold is in percentage '
|
||||||
|
'of the prefix limit')
|
||||||
|
)),
|
||||||
|
('infotext_values',
|
||||||
|
ListChoice(
|
||||||
|
title=_('Add values to check info'),
|
||||||
|
help=_('Select values to add to the check output.'),
|
||||||
|
choices=cisco_bgp_peer_infotext_values,
|
||||||
|
default_value=[],
|
||||||
|
)),
|
||||||
|
('peer_list',
|
||||||
|
ListOf(
|
||||||
|
Tuple(
|
||||||
|
# title=('BGP Peers'),
|
||||||
|
elements=[
|
||||||
|
TextUnicode(
|
||||||
|
title=_('BGP Peer item name (without "Cisco BGP peer")'),
|
||||||
|
help=_('The configured value must match a BGP item reported by the monitored '
|
||||||
|
'device. For example: "10.194.115.98 IPv4 Unicast"'),
|
||||||
|
allow_empty=False,
|
||||||
|
),
|
||||||
|
TextUnicode(
|
||||||
|
title=_('BGP Peer Alias'),
|
||||||
|
help=_('You can configure an individual alias here for the BGP peer matching '
|
||||||
|
'the text configured in the "BGP Peer item name" field. The alias will '
|
||||||
|
'be shown in the infotext'),
|
||||||
|
),
|
||||||
|
MonitoringState(
|
||||||
|
default_value=2,
|
||||||
|
title=_('State if not found'),
|
||||||
|
help=_('You can configure an individual state if the BGP peer matching the text '
|
||||||
|
'configured in the "BGP Peer item name" field is not found')
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
add_label=_('Add BGP peer'),
|
||||||
|
movable=False,
|
||||||
|
title=_('BGP Peers'),
|
||||||
|
)),
|
||||||
|
])
|
||||||
|
|
||||||
|
rulespec_registry.register(
|
||||||
|
CheckParameterRulespecWithItem(
|
||||||
|
check_group_name='cisco_bgp_peer',
|
||||||
|
group=RulespecGroupCheckParametersNetworking,
|
||||||
|
item_spec=lambda: TextAscii(title=_('BGP peer specific configuration'), ),
|
||||||
|
match_type='dict',
|
||||||
|
parameter_valuespec=_parameter_valuespec_cisco_bgp_peer,
|
||||||
|
title=lambda: _('Cisco BGP peer'),
|
||||||
|
))
|
1
check_mk-cisco_gdoi/README.md
Normal file
1
check_mk-cisco_gdoi/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This plugin checks the registration status (and KEK key timeout) of GDOI Group Members with GDOI Key Servers.
|
BIN
check_mk-cisco_gdoi/cisco_gdoi-1.1.0.mkp
Executable file
BIN
check_mk-cisco_gdoi/cisco_gdoi-1.1.0.mkp
Executable file
Binary file not shown.
@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# More information about this Cisco system:
|
||||||
|
# https://www.cisco.com/en/US/docs/ios-xml/ios/sec_conn_getvpn/configuration/15-2mt/sec-get-vpn.html
|
||||||
|
#
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
|
||||||
|
register,
|
||||||
|
Service,
|
||||||
|
Result,
|
||||||
|
State,
|
||||||
|
SNMPTree,
|
||||||
|
contains,
|
||||||
|
OIDEnd,
|
||||||
|
)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Section:
|
||||||
|
kek_info: dict
|
||||||
|
|
||||||
|
def chars_to_ip_addr(chars):
|
||||||
|
return ".".join(map(lambda c: str(ord(c)), [*chars]))
|
||||||
|
|
||||||
|
conversions = {
|
||||||
|
"1": "using",
|
||||||
|
"2": "new",
|
||||||
|
"3": "old",
|
||||||
|
}
|
||||||
|
|
||||||
|
# SNMP parsing function
|
||||||
|
def parse_cisco_gdoi(string_table):
|
||||||
|
def parse(data):
|
||||||
|
lookup = {}
|
||||||
|
|
||||||
|
for val in data:
|
||||||
|
ip = chars_to_ip_addr(val[0])
|
||||||
|
remaining = int(val[1])
|
||||||
|
state = conversions[val[2]]
|
||||||
|
|
||||||
|
lookup.setdefault(ip, {})
|
||||||
|
lookup[ip][state] = remaining
|
||||||
|
|
||||||
|
return lookup
|
||||||
|
|
||||||
|
if string_table == [[]]:
|
||||||
|
return
|
||||||
|
|
||||||
|
return Section(
|
||||||
|
kek_info=parse(string_table[0]),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Inventory function, returning inventory based upon SNMP parsed result above
|
||||||
|
def discovery_cisco_gdoi(section):
|
||||||
|
yield Service(item="Keyservers", parameters=section.kek_info)
|
||||||
|
|
||||||
|
# Check function, returning ok/crit based upon SNMP parsed result above
|
||||||
|
def check_cisco_gdoi(item, params, section):
|
||||||
|
state = params
|
||||||
|
registered = False
|
||||||
|
|
||||||
|
for ip, state in params.items():
|
||||||
|
in_use = state.get("using")
|
||||||
|
|
||||||
|
if in_use > 0:
|
||||||
|
registered = True
|
||||||
|
yield Result(state=State.OK, summary="Registered, using KEK from " + ip)
|
||||||
|
|
||||||
|
if not registered:
|
||||||
|
yield Result(state=State.CRIT, summary="Unregistered")
|
||||||
|
|
||||||
|
register.snmp_section(
|
||||||
|
name="cisco_gdoi",
|
||||||
|
parse_function=parse_cisco_gdoi,
|
||||||
|
fetch=[
|
||||||
|
SNMPTree(
|
||||||
|
# ciscoGdoiMIB::cgmGdoiGmKekRemainingLifetime
|
||||||
|
base=".1.3.6.1.4.1.9.9.759.1.3.2.1",
|
||||||
|
oids=[
|
||||||
|
"5", # cgmGdoiGmKekSrcIdValue
|
||||||
|
"20", # cgmGdoiGmKekRemainingLifetime
|
||||||
|
"21", # cgmGdoiGmKekStatus
|
||||||
|
]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
detect=contains(".1.3.6.1.2.1.1.1.0", "Cisco"),
|
||||||
|
)
|
||||||
|
|
||||||
|
register.check_plugin(
|
||||||
|
name="cisco_gdoi",
|
||||||
|
service_name="Cisco GDOI %s",
|
||||||
|
discovery_function=discovery_cisco_gdoi,
|
||||||
|
check_function=check_cisco_gdoi,
|
||||||
|
check_default_parameters={},
|
||||||
|
check_ruleset_name="cisco_gdoi",
|
||||||
|
)
|
1
check_mk-cisco_ip_sla/README.md
Normal file
1
check_mk-cisco_ip_sla/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is a modification of a Tribe29 GPL plugin to support tracking packet loss as well.
|
BIN
check_mk-cisco_ip_sla/cisco_ip_sla-1.0.1.mkp
Normal file
BIN
check_mk-cisco_ip_sla/cisco_ip_sla-1.0.1.mkp
Normal file
Binary file not shown.
@ -0,0 +1,208 @@
|
|||||||
|
#!/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 cmk.gui.i18n import _
|
||||||
|
from cmk.gui.plugins.wato.utils import (
|
||||||
|
CheckParameterRulespecWithItem,
|
||||||
|
rulespec_registry,
|
||||||
|
RulespecGroupCheckParametersNetworking,
|
||||||
|
)
|
||||||
|
from cmk.gui.valuespec import Dictionary, DropdownChoice, Integer, TextInput, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
def _item_spec_cisco_ip_sla():
|
||||||
|
return TextInput(
|
||||||
|
title=_("RTT row index of the service"),
|
||||||
|
allow_empty=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _parameter_valuespec_cisco_ip_sla():
|
||||||
|
return Dictionary(
|
||||||
|
elements=[
|
||||||
|
(
|
||||||
|
"rtt_type",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("RTT type"),
|
||||||
|
choices=[
|
||||||
|
("echo", _("echo")),
|
||||||
|
("path echo", _("path echo")),
|
||||||
|
("file IO", _("file IO")),
|
||||||
|
("UDP echo", _("UDP echo")),
|
||||||
|
("TCP connect", _("TCP connect")),
|
||||||
|
("HTTP", _("HTTP")),
|
||||||
|
("DNS", _("DNS")),
|
||||||
|
("jitter", _("jitter")),
|
||||||
|
("DLSw", _("DLSw")),
|
||||||
|
("DHCP", _("DHCP")),
|
||||||
|
("FTP", _("FTP")),
|
||||||
|
("VoIP", _("VoIP")),
|
||||||
|
("RTP", _("RTP")),
|
||||||
|
("LSP group", _("LSP group")),
|
||||||
|
("ICMP jitter", _("ICMP jitter")),
|
||||||
|
("LSP ping", _("LSP ping")),
|
||||||
|
("LSP trace", _("LSP trace")),
|
||||||
|
("ethernet ping", _("ethernet ping")),
|
||||||
|
("ethernet jitter", _("ethernet jitter")),
|
||||||
|
("LSP ping pseudowire", _("LSP ping pseudowire")),
|
||||||
|
],
|
||||||
|
default_value="echo",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"threshold",
|
||||||
|
Integer(
|
||||||
|
title=_("Treshold"),
|
||||||
|
help=_(
|
||||||
|
"Depending on the precision the unit can be "
|
||||||
|
"either milliseconds or micoseconds."
|
||||||
|
),
|
||||||
|
unit=_("ms/us"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=5000,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"state",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("State"),
|
||||||
|
choices=[
|
||||||
|
("active", _("active")),
|
||||||
|
("inactive", _("inactive")),
|
||||||
|
("reset", _("reset")),
|
||||||
|
("orderly stop", _("orderly stop")),
|
||||||
|
("immediate stop", _("immediate stop")),
|
||||||
|
("pending", _("pending")),
|
||||||
|
("restart", _("restart")),
|
||||||
|
],
|
||||||
|
default_value="active",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"connection_lost_occured",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("Connection lost occured"),
|
||||||
|
choices=[
|
||||||
|
("yes", _("yes")),
|
||||||
|
("no", _("no")),
|
||||||
|
],
|
||||||
|
default_value="no",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"timeout_occured",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("Timeout occured"),
|
||||||
|
choices=[
|
||||||
|
("yes", _("yes")),
|
||||||
|
("no", _("no")),
|
||||||
|
],
|
||||||
|
default_value="no",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"completion_time_over_treshold_occured",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("Completion time over treshold occured"),
|
||||||
|
choices=[
|
||||||
|
("yes", _("yes")),
|
||||||
|
("no", _("no")),
|
||||||
|
],
|
||||||
|
default_value="no",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"latest_rtt_completion_time",
|
||||||
|
Tuple(
|
||||||
|
title=_("Latest RTT completion time"),
|
||||||
|
help=_(
|
||||||
|
"Depending on the precision the unit can be "
|
||||||
|
"either milliseconds or micoseconds."
|
||||||
|
),
|
||||||
|
elements=[
|
||||||
|
Integer(
|
||||||
|
title=_("Warning at"),
|
||||||
|
unit=_("ms/us"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=100,
|
||||||
|
),
|
||||||
|
Integer(
|
||||||
|
title=_("Critical at"),
|
||||||
|
unit=_("ms/us"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=200,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"latest_rtt_state",
|
||||||
|
DropdownChoice(
|
||||||
|
title=_("Latest RTT state"),
|
||||||
|
choices=[
|
||||||
|
("ok", _("OK")),
|
||||||
|
("disconnected", _("disconnected")),
|
||||||
|
("over treshold", _("over treshold")),
|
||||||
|
("timeout", _("timeout")),
|
||||||
|
("other", _("other")),
|
||||||
|
],
|
||||||
|
default_value="ok",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"packets_lost_src->dest",
|
||||||
|
Tuple(
|
||||||
|
title=_("Packets lost src->dest"),
|
||||||
|
elements=[
|
||||||
|
Integer(
|
||||||
|
title=_("Warning at"),
|
||||||
|
unit=_("packets"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=100,
|
||||||
|
),
|
||||||
|
Integer(
|
||||||
|
title=_("Critical at"),
|
||||||
|
unit=_("packets"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=1000,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"packets_lost_dest->src",
|
||||||
|
Tuple(
|
||||||
|
title=_("Packets lost dest->src"),
|
||||||
|
elements=[
|
||||||
|
Integer(
|
||||||
|
title=_("Warning at"),
|
||||||
|
unit=_("packets"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=100,
|
||||||
|
),
|
||||||
|
Integer(
|
||||||
|
title=_("Critical at"),
|
||||||
|
unit=_("packets"),
|
||||||
|
minvalue=1,
|
||||||
|
default_value=1000,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rulespec_registry.register(
|
||||||
|
CheckParameterRulespecWithItem(
|
||||||
|
check_group_name="cisco_ip_sla",
|
||||||
|
group=RulespecGroupCheckParametersNetworking,
|
||||||
|
item_spec=_item_spec_cisco_ip_sla,
|
||||||
|
match_type="dict",
|
||||||
|
parameter_valuespec=_parameter_valuespec_cisco_ip_sla,
|
||||||
|
title=lambda: _("Cisco IP SLA"),
|
||||||
|
)
|
||||||
|
)
|
237
check_mk-cisco_ip_sla/local/share/check_mk/checks/cisco_ip_sla
Normal file
237
check_mk-cisco_ip_sla/local/share/check_mk/checks/cisco_ip_sla
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
#!/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.
|
||||||
|
|
||||||
|
factory_settings["cisco_ip_sla_default_levels"] = {
|
||||||
|
"state": "active",
|
||||||
|
"connection_lost_occured": "no",
|
||||||
|
"timeout_occured": "no",
|
||||||
|
"completion_time_over_treshold_occured": "no",
|
||||||
|
"latest_rtt_completion_time": (250, 500),
|
||||||
|
"latest_rtt_state": "ok",
|
||||||
|
"packets_lost_src->dest": (100, 1000),
|
||||||
|
"packets_lost_dest->src": (100, 1000),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_cisco_ip_sla(info):
|
||||||
|
precisions = {line[0]: "ms" if line[-1] == "1" else "us" for line in info[0]}
|
||||||
|
|
||||||
|
rtt_types = {
|
||||||
|
"1": "echo",
|
||||||
|
"2": "path echo",
|
||||||
|
"3": "file IO",
|
||||||
|
"4": "script",
|
||||||
|
"5": "UDP echo",
|
||||||
|
"6": "TCP connect",
|
||||||
|
"7": "HTTP",
|
||||||
|
"8": "DNS",
|
||||||
|
"9": "jitter",
|
||||||
|
"10": "DLSw",
|
||||||
|
"11": "DHCP",
|
||||||
|
"12": "FTP",
|
||||||
|
"13": "VoIP",
|
||||||
|
"14": "RTP",
|
||||||
|
"15": "LSP group",
|
||||||
|
"16": "ICMP jitter",
|
||||||
|
"17": "LSP ping",
|
||||||
|
"18": "LSP trace",
|
||||||
|
"19": "ethernet ping",
|
||||||
|
"20": "ethernet jitter",
|
||||||
|
"21": "LSP ping pseudowire",
|
||||||
|
}
|
||||||
|
|
||||||
|
states = {
|
||||||
|
"1": "reset",
|
||||||
|
"2": "orderly stop",
|
||||||
|
"3": "immediate stop",
|
||||||
|
"4": "pending",
|
||||||
|
"5": "inactive",
|
||||||
|
"6": "active",
|
||||||
|
"7": "restart",
|
||||||
|
}
|
||||||
|
|
||||||
|
rtt_states = {
|
||||||
|
"0": "other",
|
||||||
|
"1": "ok",
|
||||||
|
"2": "disconnected",
|
||||||
|
"3": "over threshold",
|
||||||
|
"4": "timeout",
|
||||||
|
"5": "busy",
|
||||||
|
"6": "not connected",
|
||||||
|
"7": "dropped",
|
||||||
|
"8": "sequence error",
|
||||||
|
"9": "verify error",
|
||||||
|
"10": "application specific error",
|
||||||
|
}
|
||||||
|
|
||||||
|
def to_ip_address(int_list):
|
||||||
|
if len(int_list) == 4:
|
||||||
|
return "%d.%d.%d.%d" % tuple(int_list)
|
||||||
|
elif len(int_list) == 6:
|
||||||
|
return "%d:%d:%d:%d:%d:%d" % tuple(int_list)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# contains description, parse function, unit and type
|
||||||
|
contents = [
|
||||||
|
( # rttMonEchoAdminEntry
|
||||||
|
("Target address", to_ip_address, "", None),
|
||||||
|
("Source address", to_ip_address, "", None),
|
||||||
|
# rttMonEchoAdminPrecision is deliberatly dropped by zip below
|
||||||
|
),
|
||||||
|
( # rttMonCtrlAdminEntry
|
||||||
|
("Owner", None, "", None),
|
||||||
|
("Tag", None, "", None),
|
||||||
|
("RTT type", lambda x: rtt_types.get(x, "unknown"), "", "option"),
|
||||||
|
("Threshold", int, "ms", "option"),
|
||||||
|
),
|
||||||
|
( # rttMonCtrlOperEntry
|
||||||
|
("State", lambda x: states.get(x, "unknown"), "", "option"),
|
||||||
|
("Text", None, "", None),
|
||||||
|
("Connection lost occured", lambda x: "yes" if x == "1" else "no", "", "option"),
|
||||||
|
("Timeout occured", lambda x: "yes" if x == "1" else "no", "", "option"),
|
||||||
|
(
|
||||||
|
"Completion time over treshold occured",
|
||||||
|
lambda x: "yes" if x == "1" else "no",
|
||||||
|
"",
|
||||||
|
"option",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
( # rttMonLatestRttOperEntry
|
||||||
|
("Latest RTT completion time", int, "ms/us", "level"),
|
||||||
|
("Latest RTT state", lambda x: rtt_states.get(x, "unknown"), "", "option"),
|
||||||
|
),
|
||||||
|
( # rttMonJitterStatsEntry
|
||||||
|
("Packets lost src->dest", int, "packets", "level"),
|
||||||
|
("Packets lost dest->src", int, "packets", "level"),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed = {}
|
||||||
|
for content, entries in zip(contents, info):
|
||||||
|
if not entries:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for entry in entries:
|
||||||
|
index, values = entry[0], entry[1:]
|
||||||
|
data = parsed.setdefault(index, [])
|
||||||
|
for (description, parser, unit, type_), value in zip(content, values):
|
||||||
|
if parser:
|
||||||
|
value = parser(value)
|
||||||
|
if unit == "ms/us":
|
||||||
|
unit = precisions[index]
|
||||||
|
data.append((description, value, unit, type_))
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
|
||||||
|
def inventory_cisco_ip_sla(parsed):
|
||||||
|
for index in parsed:
|
||||||
|
yield index, {}
|
||||||
|
|
||||||
|
|
||||||
|
@get_parsed_item_data
|
||||||
|
def check_cisco_ip_sla(_item, params, data):
|
||||||
|
for description, value, unit, type_ in data:
|
||||||
|
if not value and "packets" not in unit:
|
||||||
|
continue
|
||||||
|
|
||||||
|
state = 0
|
||||||
|
if unit:
|
||||||
|
infotext = "%s: %s %s" % (description, value, unit)
|
||||||
|
else:
|
||||||
|
infotext = "%s: %s" % (description, value)
|
||||||
|
perfdata = []
|
||||||
|
|
||||||
|
param = params.get(description.lower().replace(" ", "_"))
|
||||||
|
|
||||||
|
if type_ == "option":
|
||||||
|
if param and param != value:
|
||||||
|
state = 1
|
||||||
|
infotext += " (expected %s)" % param
|
||||||
|
elif type_ == "level":
|
||||||
|
warn, crit = param # a default level hat to exist
|
||||||
|
if value >= crit:
|
||||||
|
state = 2
|
||||||
|
elif value >= warn:
|
||||||
|
state = 1
|
||||||
|
|
||||||
|
if state:
|
||||||
|
infotext += " (warn/crit at %s/%s)" % (warn, crit)
|
||||||
|
|
||||||
|
if unit == "ms/us":
|
||||||
|
factor = 1e3 if unit == "ms" else 1e6
|
||||||
|
perfdata = [
|
||||||
|
("rtt", value / factor, warn / factor, crit / factor)
|
||||||
|
] # fixed: true-division
|
||||||
|
elif unit == "packets":
|
||||||
|
perfdata = [
|
||||||
|
("lost", value, warn, crit)
|
||||||
|
]
|
||||||
|
|
||||||
|
yield state, infotext, perfdata
|
||||||
|
|
||||||
|
|
||||||
|
check_info["cisco_ip_sla"] = {
|
||||||
|
"parse_function": parse_cisco_ip_sla,
|
||||||
|
"inventory_function": inventory_cisco_ip_sla,
|
||||||
|
"check_function": check_cisco_ip_sla,
|
||||||
|
"service_description": "Cisco IP SLA %s",
|
||||||
|
"group": "cisco_ip_sla",
|
||||||
|
"default_levels_variable": "cisco_ip_sla_default_levels",
|
||||||
|
"has_perfdata": True,
|
||||||
|
"snmp_scan_function": lambda oid: "cisco" in oid(".1.3.6.1.2.1.1.1.0").lower()
|
||||||
|
and "ios" in oid(".1.3.6.1.2.1.1.1.0").lower()
|
||||||
|
and oid(".1.3.6.1.4.1.9.9.42.1.2.2.1.37.*"),
|
||||||
|
"snmp_info": [
|
||||||
|
(
|
||||||
|
".1.3.6.1.4.1.9.9.42.1.2.2.1",
|
||||||
|
[
|
||||||
|
OID_END,
|
||||||
|
BINARY(2), # rttMonEchoAdminTargetAddress
|
||||||
|
BINARY(6), # rttMonEchoAdminSourceAddress
|
||||||
|
# only needed to determine the unit (ms/us)
|
||||||
|
37, # rttMonEchoAdminPrecision
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
".1.3.6.1.4.1.9.9.42.1.2.1.1",
|
||||||
|
[
|
||||||
|
OID_END,
|
||||||
|
2, # rttMonCtrlAdminOwner
|
||||||
|
3, # rttMonCtrlAdminTag
|
||||||
|
4, # rttMonCtrlAdminRttType
|
||||||
|
5, # rttMonCtrlAdminThreshold
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
".1.3.6.1.4.1.9.9.42.1.2.9.1",
|
||||||
|
[
|
||||||
|
OID_END,
|
||||||
|
10, # rttMonCtrlOperState
|
||||||
|
2, # rttMonCtrlOperDiagText
|
||||||
|
5, # rttMonCtrlOperConnectionLostOccurred
|
||||||
|
6, # rttMonCtrlOperTimeoutOccurred
|
||||||
|
7, # rttMonCtrlOperOverThresholdOccurred
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
".1.3.6.1.4.1.9.9.42.1.2.10.1",
|
||||||
|
[
|
||||||
|
OID_END,
|
||||||
|
1, # rttMonLatestRttOperCompletionTime
|
||||||
|
2, # rttMonLatestRttOperSense
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
".1.3.6.1.4.1.9.9.42.1.5.2.1",
|
||||||
|
[
|
||||||
|
OID_END,
|
||||||
|
26, # rttMonLatestJitterOperPacketLossSD
|
||||||
|
27, # rttMonLatestJitterOperPacketLossDS
|
||||||
|
]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user