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 6a841e2a authored by thl-cmk's avatar thl-cmk :flag_na:
Browse files

update project

parent 893b80a3
No related branches found
No related tags found
No related merge requests found
......@@ -12,20 +12,26 @@
# 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
# added support of more then one address family per peer thanks to support[at]heinlein-support[dot]de
# (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)
# 2019-18-02: added fix for empty values ("" instead of "0") sugested by lbarbier[at]arkane-studios[dot]com
# 2020-02-24: added workaround for missing cbgpPeer2AddrFamily (example L2VPN EVPN peers) thanks to 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)
# 2020-09-10: fixed typo in metrics file. FMS --> FSM, thanks to 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
# 2021-03-28: added warning for missing prefix limit/warn threshold
# 2021-07-08: fixed handling of missing prefix limit/accepted prefixes/warn threshold. thanks to Florian[dot]Dille[at]aldi-sued[dot]com
# 2021-07-13: fixed handling of perfdata (in/out updates, in/out total messages). thanks to Florian[dot]Dille[at]aldi-sued[dot]com and timhor[at]outlook[dot]com
# added type hinting for parsed data (section)
# optimised data handling in check function (add prefixes to peer info)
# made default state if item not found configurable via WALO
#
#
#
# snmpwalk sample
#
......@@ -128,44 +134,82 @@
# .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']
# ]
# ]
#
#
#
# sample section
# note: peer_table entry can be used with more than one prefixes_table entry. I.E. one peer with two address families
#
# Section(prefixes_table={
# '10.20.182.229 IPv4 Unicast': {
# 'remoteaddr': '10.20.182.229',
# 'addrfamilyname': 'IPv4 Unicast',
# 'acceptedprefixes': 1,
# 'advertisedprefixes': 6,
# 'deniedprefixes': 0,
# 'suppressedprefixes': 0,
# 'withdrawnprefixes': 0
# },
# '1234:1234:1000:135::1 IPv6 Unicast': {
# 'remoteaddr': '1234:1234:1000:135::1',
# 'addrfamilyname': 'IPv6 Unicast',
# 'prefixadminlimit': 100000,
# 'prefixthreshold': 85,
# 'prefixclearthreshold': 80,
# 'acceptedprefixes': 0,
# 'advertisedprefixes': 6,
# 'deniedprefixes': 0,
# 'suppressedprefixes': 0,
# 'withdrawnprefixes': 0
# },
# },
# peer_table={
# '10.20.182.229': {
# 'remoteaddr': '10.20.182.229',
# 'localaddr': '10.20.182.230',
# 'localid': '10.10.208.1',
# 'remoteid': '10.20.182.229',
# 'lasterror': 'Hold Timer Expired',
# 'lasterrortxt': 'hold time expired',
# 'prevstate': 5,
# 'state': 6,
# 'adminstate': 2,
# 'localas': 0,
# 'remoteas': 21413,
# 'inupdates': 1,
# 'outupdates': 3,
# 'intotalmessages': 48,
# 'outtotalmessages': 53,
# 'fsmestablishedtransitions': 8,
# 'fsmestablishedtime': 2581,
# 'inupdateelapsedtime': 2581
# },
# '1234:1234:1000:135::1': {
# 'remoteaddr': '1234:1234:1000:135::1',
# 'localaddr': '1234:1234:1000:135::2',
# 'localid': '10.10.208.1',
# 'remoteid': '10.20.182.229',
# 'lasterror': 'Connection Rejected',
# 'lasterrortxt': 'Administrative Reset',
# 'prevstate': 5,
# 'state': 6,
# 'adminstate': 2,
# 'localas': 0,
# 'remoteas': 21413,
# 'inupdates': 0,
# 'outupdates': 4,
# 'intotalmessages': 108,
# 'outtotalmessages': 121,
# 'fsmestablishedtransitions': 6,
# 'fsmestablishedtime': 6295,
# 'inupdateelapsedtime': 0
# },
# }
# )
#
#
import re
import time
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 typing import List, Dict, TypedDict, Mapping, Any
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
register,
......@@ -177,135 +221,219 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
contains,
OIDEnd,
get_rate,
GetRateError,
get_value_store,
IgnoreResultsError,
Metric,
render,
)
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
DiscoveryResult,
CheckResult,
StringTable,
)
@dataclass
class Prefixes(TypedDict):
remoteaddr: str
addrfamilyname: str
prefixadminlimit: int
prefixthreshold: int
prefixclearthreshold: int
acceptedprefixes: int
advertisedprefixes: int
deniedprefixes: int
suppressedprefixes: int
withdrawnprefixes: int
@dataclass
class Peer(TypedDict):
remoteaddr: str
localaddr: str
localid: str
remoteid: str
lasterror: str
lasterrortxt: str
prevstate: int
state: int
adminstate: int
localas: int
remoteas: int
inupdates: int
outupdates: int
intotalmessages: int
outtotalmessages: int
fsmestablishedtransitions: int
fsmestablishedtime: int
inupdateelapsedtime: int
# add prefixes to peer info in check function
addrfamilyname: str
prefixadminlimit: int
prefixthreshold: int
prefixclearthreshold: int
acceptedprefixes: int
advertisedprefixes: int
deniedprefixes: int
suppressedprefixes: int
withdrawnprefixes: int
@dataclass
class Section:
peer_prefixes: dict
peer_table: dict
prefixes_table: Dict[str, Prefixes]
peer_table: Dict[str, Peer]
###########################################################################
#
# DATA Parser function
# Helper functions
#
###########################################################################
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 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)
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
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(OID_END[1]) == 4: # length of ip address
peer_ip = '.'.join(OID_END[2:6]) # 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', }
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(OID_END[1]) == 4: # length of ip address
peer_ip = '.'.join(OID_END[2:6]) # 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[6] = {0: 'Administratively Shutdown',
1: 'Max Prefix Reached',
2: 'Peer Unconfigured',
3: 'Administratively Reset',
4: 'Connection Rejected',
5: 'Other Configuration Change',
}
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))
def _cisco_bgp_adminstate(state):
names = {1: 'stop',
2: 'start', }
return names.get(state, 'unknown (%s)' % state)
return names[int(byte1, 16)].get(int(byte2, 16))
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)
###########################################################################
#
# DATA Parser function
#
###########################################################################
def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
# bgp not active
if not string_table == [[], []]:
cbgpPeer2Entry, cbgpPeer2AddrFamily = string_table
peer_prefixes = {}
prefixes_table = {}
# 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 = _cisco_bgp_get_peer(oid_end)
prefixes = Prefixes()
prefixes.update({
'remoteaddr': remoteaddr,
'addrfamilyname': addrfamilyname
}
})
for key, value in [
('prefixadminlimit', prefixadminlimit),
......@@ -318,21 +446,21 @@ def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
('withdrawnprefixes', withdrawnprefixes),
]:
try:
peer[key] = int(value)
prefixes[key] = int(value)
except ValueError:
pass
peer_prefixes.update({'%s %s' % (remoteaddr, addrfamilyname): peer})
prefixes_table.update({'%s %s' % (remoteaddr, addrfamilyname): prefixes})
# workaround: get remote ip from cbgpPeer2Entry if cbgpPeer2AddrFamilyName is missing :-(
elif len(cbgpPeer2Entry) > 0:
for entry in cbgpPeer2Entry:
remoteaddr = cisco_bgp_get_peer(entry[0])
remoteaddr = _cisco_bgp_get_peer(entry[0])
addrfamilyname = ''
peer = {'remoteaddr': remoteaddr, }
peer_prefixes.update({'%s %s' % (remoteaddr, addrfamilyname): peer})
prefixes_table.update({'%s %s' % (remoteaddr, addrfamilyname): peer})
# create dictionary from cbgpPeer2Entry (peer ip address as index)
peer_table = {}
......@@ -341,11 +469,11 @@ def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
outupdates, intotalmessages, outtotalmessages, lasterror, fsmestablishedtransitions, fsmestablishedtime, \
inupdateelapsedtime, lasterrortxt, prevstate = entry
peer = {'remoteaddr': cisco_bgp_get_peer(oid_end),
'localaddr': bgp_render_ip_address(localaddr),
peer = {'remoteaddr': _cisco_bgp_get_peer(oid_end),
'localaddr': _bgp_render_ip_address(localaddr),
'localid': localidentifier,
'remoteid': remoteidentifier,
'lasterror': cisco_bgp_errors(lasterror),
'lasterror': _cisco_bgp_errors(lasterror),
'lasterrortxt': lasterrortxt,
'prevstate': int(prevstate),
}
......@@ -368,10 +496,10 @@ def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
except ValueError:
pass
peer_table.update({'%s' % cisco_bgp_get_peer(oid_end): peer})
peer_table.update({'%s' % _cisco_bgp_get_peer(oid_end): peer})
return Section(
peer_prefixes=peer_prefixes,
prefixes_table=prefixes_table,
peer_table=peer_table,
)
......@@ -384,7 +512,7 @@ def parse_cisco_bgp_peer(string_table: List[StringTable]) -> Section:
def discovery_cisco_bgp_peer(section: Section) -> DiscoveryResult:
for key in section.peer_prefixes.keys():
for key in section.prefixes_table.keys():
yield Service(item=key)
......@@ -396,28 +524,14 @@ def discovery_cisco_bgp_peer(section: Section) -> DiscoveryResult:
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
prefixes_table = section.prefixes_table
peer_table = section.peer_table
prefixes = peer_prefixes.get(item, None)
prefixes = Prefixes()
prefixes.update(prefixes_table.get(item, None))
alias = ''
peer_not_found_state = 3
peer_not_found_state = params.get('peernotfound', 2)
for bgp_connection, bgp_alias, not_found_state in params.get('peer_list', []):
if item == bgp_connection:
......@@ -425,9 +539,15 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
peer_not_found_state = not_found_state
if prefixes:
longoutput = ''
peer = Peer()
peer.update(peer_table.get(prefixes.get('remoteaddr')))
# add prefixes to peer info, no need to use prefixes any more
# no done in parse function, because peer could be used with more than one prefixes entry
for key in prefixes.keys():
peer[key] = prefixes[key]
peer = peer_table.get(prefixes.get('remoteaddr'))
longoutput = ''
if peer.get('localas') == 0:
peer.update({'localas': params.get('useaslocalas')})
......@@ -440,7 +560,7 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
establishedtime = peer.get('fsmestablishedtime')
if peerstate == 1: # idle
yield Result(state=State.CRIT, summary='Peer state: %s' % cisco_bgp_peerstate(peerstate))
yield Result(state=State.CRIT, summary='Peer state: %s' % _cisco_bgp_peerstate(peerstate))
elif peerstate == 6: # established
yield from check_levels(
value=establishedtime,
......@@ -450,23 +570,10 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
)
else: # everything else
yield Result(state=State.WARN, summary='Peer state: %s' % cisco_bgp_peerstate(peerstate))
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
yield Result(state=State.WARN, summary='Admin state: %s' % _cisco_bgp_adminstate(adminstate))
bgptype = ''
if not peer.get('localas') == 0:
......@@ -476,29 +583,34 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
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), ''],
['', 'Local', 'Remote'],
['IP-address', peer.get('localaddr'), peer.get('remoteaddr')],
['Router-ID', peer.get('localid'), peer.get('remoteid')],
['Autonomus System', peer.get('localas'), str(peer.get('remoteas')) + 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), '']
,
['Previous state', _cisco_bgp_peerstate(peer.get('prevstate')), ''],
['Address family name', peer.get('addrfamilyname', 'unknown'), ''],
['Prefix clear threshold (%)', peer.get('prefixclearthreshold', ''), ''],
]
acceptedprefixes = prefixes.get('acceptedprefixes', None)
prefixadminlimit = prefixes.get('prefixadminlimit', None)
prefixthreshold = prefixes.get('prefixthreshold', None)
acceptedprefixes = peer.get('acceptedprefixes', None)
prefixadminlimit = peer.get('prefixadminlimit', None)
prefixthreshold = peer.get('prefixthreshold', None)
warnthreshold = 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.')
# yield Result(state=State.OK, notice=f'Prefix limit/warn threshold: {prefixadminlimit}/{prefixthreshold}')
elif acceptedprefixes is not None:
yield Result(
state=State(params['noprefixlimit']),
notice='Prefix limit/warn threshold: not configured on the device.',
)
warnthreshold = None
if params.get('htmloutput', False):
......@@ -515,14 +627,17 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
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\''
'\ndisable \'Escape HTML codes in plugin output\' in wato -> ' \
'global settings and enable HTML output in \'Parameters for this service\' or' \
'\n add a Rule to the \'Cisco BGP peer\' service (Setup - Services - Service monitoring ' \
'rules - Escape HTML in service output.'
for entry in longoutput_data:
if not entry[2] == '':
longoutput += '\n{}: {} / {}'.format(entry[0], entry[1], entry[2])
longoutput += f'\n{entry[0]}: {entry[1]} / {entry[2]}'
else:
longoutput += '\n{}: {}'.format(entry[0], entry[1])
longoutput += f'\n{entry[0]}: {entry[1]}'
if prefixadminlimit is not None:
if acceptedprefixes is not None:
yield from check_levels(
value=acceptedprefixes,
metric_name='cisco_bgp_peer_acceptedprefixes',
......@@ -534,6 +649,7 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
now_time = time.time()
value_store = get_value_store()
rate_item = item.replace(' ', '_').replace(':', '_')
raise_ingore_res = False
for key in [
'deniedprefixes',
......@@ -546,12 +662,19 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
'outtotalmessages',
]:
try:
value = get_rate(value_store, 'cisco_bgp_peer.%s.%s' % (key, rate_item), now_time, prefixes[key],
raise_overflow=False)
try:
value = get_rate(value_store, 'cisco_bgp_peer.%s.%s' % (key, rate_item), now_time, peer[key],
raise_overflow=False)
except GetRateError:
raise_ingore_res = True
value = 0
yield Metric(name='cisco_bgp_peer_%s' % key, value=value, boundaries=(0, None))
except KeyError:
pass
if raise_ingore_res:
raise IgnoreResultsError('Initializing counters')
for key in [
'fsmestablishedtransitions',
'fsmestablishedtime',
......@@ -562,6 +685,19 @@ def check_cisco_bgp_peer(item, params, section) -> CheckResult:
except KeyError:
pass
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
yield Result(state=State.OK, notice=longoutput)
else:
if alias != '':
......
No preview for this file type
......@@ -20,7 +20,7 @@
'name': 'cisco_bgp_peer',
'num_files': 3,
'title': 'Cisco BGP Peer',
'version': '20210327.v.0.3',
'version': '20210713.v.0.3c',
'version.min_required': '2.0.0',
'version.packaged': '2.0.0p1',
'version.packaged': '2021.07.14',
'version.usable_until': None}
\ No newline at end of file
......@@ -21,7 +21,6 @@ from cmk.gui.plugins.metrics import (
perfometer_info
)
#####################################################################################################################
#
# define metrics for bgp peer perfdata
......@@ -90,25 +89,25 @@ metric_info['cisco_bgp_peer_inupdateelapsedtime'] = {
'color': '43/a',
}
######################################################################################################################
#
# how to graph perdata for bgp peer
#
######################################################################################################################
graph_info['cisco_bgp_peer.prefixes_accepted']={
graph_info['cisco_bgp_peer.prefixes_accepted'] = {
'title': _('Accepted Prefixes'),
'metrics': [
('cisco_bgp_peer_acceptedprefixes', 'line'),
('cisco_bgp_peer_acceptedprefixes', 'area'),
],
'scalars': [
('cisco_bgp_peer_acceptedprefixes:crit', _('crit')),
('cisco_bgp_peer_acceptedprefixes:warn', _('warn')),
],
'range': (0, 'cisco_bgp_peer_acceptedprefixes:max'),
}
graph_info['cisco_bgp_peer.prefixes_per_second']={
graph_info['cisco_bgp_peer.prefixes_per_second'] = {
'title': _('Prefixes/s'),
'metrics': [
('cisco_bgp_peer_deniedprefixes', 'line'),
......@@ -118,8 +117,7 @@ graph_info['cisco_bgp_peer.prefixes_per_second']={
],
}
graph_info['cisco_bgp_peer.updates_in_out']={
graph_info['cisco_bgp_peer.updates_in_out'] = {
'title': _('Updates'),
'metrics': [
('cisco_bgp_peer_inupdates', 'area'),
......@@ -127,7 +125,7 @@ graph_info['cisco_bgp_peer.updates_in_out']={
]
}
graph_info['cisco_bgp_peer.messages_in_out']={
graph_info['cisco_bgp_peer.messages_in_out'] = {
'title': _('Total messages'),
'metrics': [
('cisco_bgp_peer_intotalmessages', 'area'),
......@@ -135,25 +133,28 @@ graph_info['cisco_bgp_peer.messages_in_out']={
]
}
graph_info['cisco_bgp_peer.fms_transitions_from_to']={
graph_info['cisco_bgp_peer.fms_transitions_from_to'] = {
'title': _('FSM transitions from/to established'),
'metrics': [
('cisco_bgp_peer_fsmestablishedtransitions', 'line'),
('cisco_bgp_peer_fsmestablishedtransitions', 'area'),
],
'range': (0, 'cisco_bgp_peer_fsmestablishedtransitions:max'),
}
graph_info['cisco_bgp_peer.fms_transitions_last_change']={
graph_info['cisco_bgp_peer.fms_transitions_last_change'] = {
'title': _('FSM established last change'),
'metrics': [
('cisco_bgp_peer_fsmestablishedtime', 'line'),
]
('cisco_bgp_peer_fsmestablishedtime', 'area'),
],
'range': (0, 'cisco_bgp_peer_fsmestablishedtime:max'),
}
graph_info['cisco_bgp_peer.time_since_last_update']={
graph_info['cisco_bgp_peer.time_since_last_update'] = {
'title': _('Time since last update received'),
'metrics': [
('cisco_bgp_peer_inupdateelapsedtime', 'line'),
]
('cisco_bgp_peer_inupdateelapsedtime', 'area'),
],
'range': (0, 'cisco_bgp_peer_inupdateelapsedtime:mac'),
}
######################################################################################################################
......
......@@ -17,7 +17,6 @@ from cmk.gui.valuespec import (
Dictionary,
Integer,
TextAscii,
ListOfStrings,
FixedValue,
ListChoice,
ListOf,
......@@ -32,7 +31,7 @@ from cmk.gui.plugins.wato import (
RulespecGroupCheckParametersNetworking,
)
cisco_bgp_peer_infotext_values = [
_cisco_bgp_peer_infotext_values = [
('remoteid', 'Remote router ID'),
('remoteas', 'Remote autonomous system'),
('localaddr', 'Local peer IP address'),
......@@ -59,13 +58,17 @@ def _parameter_valuespec_cisco_bgp_peer():
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,
minvalue=0,
maxvalue=4294967295,
),
),
('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'),
help=_('render long output of check plugin (multiline) as HTML table. '
'Needs \'Escape HTML codes in plugin output\' in wato --> global settings disabled or '
'add a Rule to the \'Cisco BGP peer\' service (Setup - Services - Service monitoring rules - '
'Escape HTML in service output.'),
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,
......@@ -78,17 +81,22 @@ def _parameter_valuespec_cisco_bgp_peer():
'For example: neighbor 172.17.10.10 maximum-prefix 10000 80. The threshold is in percentage '
'of the prefix limit')
)),
('peernotfound',
MonitoringState(
default_value=2,
title=_('State if peer is no not found.'),
help=_('Default monitoring state if the peer is not found in the SNMP data')
)),
('infotext_values',
ListChoice(
title=_('Add values to check info'),
help=_('Select values to add to the check output.'),
choices=cisco_bgp_peer_infotext_values,
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")'),
......@@ -100,7 +108,7 @@ def _parameter_valuespec_cisco_bgp_peer():
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'),
'be shown in the check info'),
),
MonitoringState(
default_value=2,
......@@ -115,6 +123,7 @@ def _parameter_valuespec_cisco_bgp_peer():
)),
])
rulespec_registry.register(
CheckParameterRulespecWithItem(
check_group_name='cisco_bgp_peer',
......@@ -123,4 +132,4 @@ rulespec_registry.register(
match_type='dict',
parameter_valuespec=_parameter_valuespec_cisco_bgp_peer,
title=lambda: _('Cisco BGP peer'),
))
\ 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