From d45e92de5f84f1848bc02349bd3da1a6e92e3f8a Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Sun, 14 Nov 2021 21:34:24 +0100 Subject: [PATCH] update project --- agent_based/cisco_bgp_peer.py | 79 +++++++++++++++++++++++++++++++++- cisco_bgp_peer.mkp | Bin 4828 -> 5321 bytes 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/agent_based/cisco_bgp_peer.py b/agent_based/cisco_bgp_peer.py index 9bd148d..ec95440 100644 --- a/agent_based/cisco_bgp_peer.py +++ b/agent_based/cisco_bgp_peer.py @@ -47,8 +47,9 @@ # 2021-11-13: fix for mixed peers (with and without prefixes on one host) # 2021-11-14: merged check function with bgp_peer # merged parse function with bgp_peer +# added basic support for VRFs (cbgpPeer3Entry) -from typing import List, Dict +from typing import List, Dict, Optional from cmk.base.plugins.agent_based.agent_based_api.v1 import ( register, @@ -57,9 +58,11 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( contains, all_of, OIDEnd, + OIDBytes, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, + StringByteTable, ) from cmk.base.plugins.agent_based.utils.bgp_peer import ( @@ -178,6 +181,80 @@ register.snmp_section( ), ) +########################################################################### +# +# cisco_bgp_peer (CISCO-BGP4-MIB:cbgpPeer3Entry) +# +########################################################################### + + +# ToDo: add support for non ipv6, needs sample +def parse_cisco_bgp_peer_3(string_table: StringByteTable) -> Optional[Dict[str, BgpPeer]]: + peer_table = {} + for entry in string_table: + if entry[0] == '1': # IPv4 address + entry[1] = '.'.join(f'{m}' for m in entry[1]) + if entry[2] != 'default': + entry[1] += f' vrf {entry[2]}' + entry.pop(2) # remove vrf name + entry.pop(0) # remove remote address type + bgp_peer = bgp_get_peer_entry(entry) + if bgp_peer: + peer_table.update(bgp_peer) + return peer_table + + +register.snmp_section( + name='cisco_bgp_peer_3', + parse_function=parse_cisco_bgp_peer_3, + parsed_section_name='bgp_peer', + supersedes=['bgp_peer', 'cisco_bgp_peer'], + fetch= SNMPTree( + base='.1.3.6.1.4.1.9.9.187.1.2.9.1', # CISCO-BGP4-MIB::cbgpPeer3Entry + oids=[ + '2', # cbgpPeer3Type + OIDBytes('3'), # cbgpPeer3RemoteAddr + '4', # cbgpPeer3VrfName + '5', # cbgpPeer3State + '6', # cbgpPeer3AdminStatus + '15', # cbgpPeer3InUpdates + '16', # cbgpPeer3OutUpdates + '17', # cbgpPeer3InTotalMessages + '18', # cbgpPeer3OutTotalMessages + '20', # cbgpPeer3FsmEstablishedTransitions + '21', # cbgpPeer3FsmEstablishedTime + '29', # cbgpPeer3InUpdateElapsedTime + ] + ), + detect=all_of( + contains('.1.3.6.1.2.1.1.1.0', 'Cisco'), + exists('.1.3.6.1.4.1.9.9.187.1.2.9.1.3.*') + ), +) + +# '1', # cbgpPeer3VrfId +# '3', # cbgpPeer3RemoteAddr +# '4', # cbgpPeer3VrfName +# '5', # cbgpPeer3State +# '6', # cbgpPeer3AdminStatus +# '7', # cbgpPeer3NegotiatedVersion +# '8', # cbgpPeer3LocalAddr +# '9', # cbgpPeer3LocalPort +# '10', # cbgpPeer3LocalAs +# '11', # cbgpPeer3LocalIdentifier +# '12', # cbgpPeer3RemotePort +# '13', # cbgpPeer3RemoteAs +# '14', # cbgpPeer3RemoteIdentifier +# '19', # cbgpPeer3LastError +# '22', # cbgpPeer3ConnectRetryInterval +# '23', # cbgpPeer3HoldTime +# '24', # cbgpPeer3KeepAlive +# '25', # cbgpPeer3HoldTimeConfigured +# '26', # cbgpPeer3KeepAliveConfigured +# '27', # cbgpPeer3MinASOriginationInterval +# '28', # cbgpPeer3MinRouteAdvertisementInterval +# '30', # cbgpPeer3LastErrorTxt +# '31', # cbgpPeer3PrevState ########################################################################### # diff --git a/cisco_bgp_peer.mkp b/cisco_bgp_peer.mkp index dc782b296198ca17d24f9300c1934aa7d14b90a3..0f061c46252e7782ccaa6f84ea5bddb7657b1b3c 100644 GIT binary patch literal 5321 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 C2tQ;1 literal 4828 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 -- GitLab