diff --git a/agent_based/bgp_peer.py b/agent_based/bgp_peer.py index a36a35ff619a173e1ea04e05aa7e092b1052ca89..58c4bbec6137a7f30f214a351d0573a69523a3c8 100644 --- a/agent_based/bgp_peer.py +++ b/agent_based/bgp_peer.py @@ -5,7 +5,7 @@ # Author: thl-cmk[at]outlook[dot]com # URL : https://thl-cmk.hopto.org -# Date : 2021-10-25 +# Date : 2021-08-20 # based on the BGP peer plugin by Thomas Wollner (tw@wollner-net.de) # @@ -23,7 +23,8 @@ # 2022-05-11: changed bgp_get_peer_entry to get proper parameters instead of Nontransparent list # added remote_as to BgpPeerItem # 2022-09-05: added missing wato parameters to register.check_plugin check_default_parameters -# +# 2022-09-10: made more reliable on limited data (fsm_established_time and admin_state) (THX to martin[dot]pechstein[at]posteo[dot]de) +# 2022-09-11: optimized internal flow: > alias > not found > admin down > peer state > ... # Example Agent Output: # BGP4-MIB @@ -129,19 +130,23 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: yield Result(state=State(peer_not_found_state), summary='Item not found in SNMP data') return - if not peer.admin_state == 2: # not start - yield Result(state=State(params['admindown']), notice=f'Admin state: {peer.peer_statestr}') - else: - if peer.peer_state == 6: # established - yield from check_levels( - value=peer.fsm_established_time, - label='Uptime', - levels_lower=params['minuptime'], - render_func=render.timespan, - metric_name='bgp_peer_fsmestablishedtime', - ) + if peer.admin_state == 1: # shutdown + yield Result(state=State(params['admindown']), summary=f'Admin state: {peer.peer_statestr}') + return + + yield Result(state=State(neighborstate.get(str(peer.peer_state))), notice=f'Peer state: {peer.peer_statestr}') + + if not peer.peer_state == 6: # not established + return - yield Result(state=State(neighborstate.get(str(peer.peer_state))), notice=f'Peer state: {peer.peer_statestr}') + if peer.fsm_established_time: # fms_time not None + yield from check_levels( + value=peer.fsm_established_time, + label='Uptime', + levels_lower=params['minuptime'], + render_func=render.timespan, + metric_name='bgp_peer_fsmestablishedtime', + ) if peer.peer_unavail_reason != 0: # huawei peer unavailable state yield Result(state=State.CRIT, notice=F'Peer unavailable reason: {peer.peer_unavail_reason_str}') @@ -152,39 +157,37 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: notice='Prefix limit/warn threshold not configured on the device.', ) - if peer.admin_state == 2: # no perfdata if admin shutdown - acceptedprefixes = peer.accepted_prefixes - prefixadminlimit = peer.prefix_admin_limit - prefixthreshold = peer.prefix_threshold - warnthreshold = None - - if prefixadminlimit is not None and prefixthreshold is not None: - warnthreshold = int( - prefixadminlimit / 100.0 * prefixthreshold) # use float (100.0) to get xx.xx in division - if acceptedprefixes is not None and peer.peer_state == 6: # peer established and prefixes accepted - yield from check_levels( - value=acceptedprefixes, - metric_name='bgp_peer_acceptedprefixes', - levels_upper=params.get('accepted_prefixes_upper_levels', (warnthreshold, prefixadminlimit)), - levels_lower=params.get('accepted_prefixes_lower_levels'), - label='Prefixes accepted', - render_func=lambda v: f'{v}' - ) - - now_time = time.time() - value_store = get_value_store() - - for entry in peer.metric_rate: - key, value = entry - try: - value = get_rate(value_store, f'{key}', now_time, value, raise_overflow=True) - except GetRateError: - value = 0 - yield Metric(name=f'bgp_peer_{key}', value=value, boundaries=(0, None)) - - for entry in peer.metric_count: - key, value = entry - yield Metric(name=f'bgp_peer_{key}', value=value, boundaries=(0, None)) + acceptedprefixes = peer.accepted_prefixes + prefixadminlimit = peer.prefix_admin_limit + prefixthreshold = peer.prefix_threshold + warnthreshold = None + + if prefixadminlimit is not None and prefixthreshold is not None: + warnthreshold = int(prefixadminlimit / 100.0 * prefixthreshold) # use float (100.0) to get xx.xx in division + if acceptedprefixes is not None and peer.peer_state == 6: # peer established and prefixes accepted + yield from check_levels( + value=acceptedprefixes, + metric_name='bgp_peer_acceptedprefixes', + levels_upper=params.get('accepted_prefixes_upper_levels', (warnthreshold, prefixadminlimit)), + levels_lower=params.get('accepted_prefixes_lower_levels'), + label='Prefixes accepted', + render_func=lambda v: f'{v}' + ) + + now_time = time.time() + value_store = get_value_store() + + for entry in peer.metric_rate: + key, value = entry + try: + value = get_rate(value_store, f'{key}', now_time, value, raise_overflow=True) + except GetRateError: + value = 0 + yield Metric(name=f'bgp_peer_{key}', value=value, boundaries=(0, None)) + + for entry in peer.metric_count: + key, value = entry + yield Metric(name=f'bgp_peer_{key}', value=value, boundaries=(0, None)) register.snmp_section( diff --git a/agent_based/inv_bgp_peer.py b/agent_based/inv_bgp_peer.py index d273b4bc6738eb6eebb6c69c7b36d029858894d5..0262c145f9bc9c4bfbe53b14ef7a9127cde91a05 100644 --- a/agent_based/inv_bgp_peer.py +++ b/agent_based/inv_bgp_peer.py @@ -60,7 +60,7 @@ def parse_inv_bgp_peer(string_table: List[StringByteTable]): 'local_as': local_as, 'local_id': local_id, 'bgp_type': get_bgp_type(local_as, remote_as), - 'fsm_established_time': int(fsm_established_time), + 'fsm_established_time': int(fsm_established_time) if fsm_established_time.isdigit() else None, 'peer_state': 1 if state == '6' else 2, # adjust to match if_oper_status for inventory painter 'last_error_code': bgp_error_code_as_hex(last_error), 'last_error': bgp_error_as_string(last_error), diff --git a/agent_based/utils/bgp_peer.py b/agent_based/utils/bgp_peer.py index 691c144fa2bf5c2e07bcf85f1d4cff99812d83b8..803d1c2a884914018de60c639ccf58646b22556c 100644 --- a/agent_based/utils/bgp_peer.py +++ b/agent_based/utils/bgp_peer.py @@ -18,6 +18,10 @@ # 2022-05-12: merged bgp_get_ip_address_from_oid with bgp_render_ip_address # changed IPv6 address format to lower case as required by rfc5952 section-4.3 (this affects IPv6 items) +# +# https://ftp.ripe.net/ripe/asnames/asn.txt AS Name List +# + import requests import json import ipaddress @@ -36,12 +40,12 @@ class BgpPeerItem(TypedDict): class BgpPeer: peer_state: int peer_statestr: str - admin_state: int admin_statestr: str - fsm_established_time: int metric_rate: List[Tuple[str, int]] metric_count: List[Tuple[str, int]] item: BgpPeerItem + admin_state: Optional[int] + fsm_established_time: Optional[int] device_admin_limit: Optional[bool] prefix_admin_limit: Optional[int] prefix_threshold: Optional[int] @@ -60,12 +64,12 @@ class InvBgpPeer(TypedDict): local_as: str local_id: str bgp_type: str - fsm_established_time: int peer_state: int last_error_code: str last_error: str status_columns: Dict[str, str] address_family: Optional[str] + fsm_established_time: Optional[int] def sec2hr(seconds): @@ -116,7 +120,11 @@ def bgp_error_code_as_hex(error_code: List[int]): def bgp_error_as_string(error_code: List[int]): # byte1, byte2 = ByteToHex(bytestring).split() - main_code, sub_code = error_code + try: + main_code, sub_code = error_code + except ValueError: + return 'Unknown' + names = {} names[0] = {0: 'NO ERROR'} names[1] = { @@ -206,9 +214,9 @@ def bgp_get_peer_entry( remote_addr: str, remote_as: str, peer_state: str, - admin_state: str, fsm_established_transitions: str, - fsm_established_time: str, + fsm_established_time: Optional[str], + admin_state: Optional[str], in_updates: Optional[str], out_updates: Optional[str], in_messages: Optional[str], @@ -219,9 +227,9 @@ def bgp_get_peer_entry( bgp_peer = BgpPeer( peer_state=int(peer_state), peer_statestr=bgp_peerstate(int(peer_state)), - admin_state=int(admin_state), - admin_statestr=bgp_adminstate(int(admin_state)), - fsm_established_time=int(fsm_established_time), + admin_state=int(admin_state) if admin_state.isdigit() else None, + admin_statestr=bgp_adminstate(int(admin_state) if admin_state.isdigit() else None), + fsm_established_time=int(fsm_established_time) if fsm_established_time.isdigit() else None, metric_count=[], metric_rate=[], item={ diff --git a/bgp_peer.mkp b/bgp_peer.mkp index ea9e93bd0e0f285d3b61e0748cd6da3133a1a9c8..d0b078c448371845ebd4ce3f5c2e79fd972788c5 100644 Binary files a/bgp_peer.mkp and b/bgp_peer.mkp differ diff --git a/packages/bgp_peer b/packages/bgp_peer index cedf2084d5f5b33e2ad8a2add5f9b9cb41da43e0..1bb1006e6df22d5f720bcc980fb76e922498b94a 100644 --- a/packages/bgp_peer +++ b/packages/bgp_peer @@ -20,7 +20,7 @@ 'name': 'bgp_peer', 'num_files': 8, 'title': 'BGP Peer State Check', - 'version': '220906.v1.8a', + 'version': '20220911.v1.8b', 'version.min_required': '2.0.0', 'version.packaged': '2021.09.20', 'version.usable_until': None} \ No newline at end of file