From 7319187b6fd93eb5c134820ebf5018b2e0f3eb52 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Tue, 10 May 2022 19:26:55 +0200
Subject: [PATCH] update project

---
 agent_based/inv_juniper_bgp_peer.py   | 135 ++++++++++++++++++++++
 agent_based/juniper_bgp_peer.py       | 160 ++++++++++++++++++++++++++
 agent_based/utils/juniper_bgp_peer.py |  62 ++++++++++
 juniper_bgp_peer.mkp                  | Bin 0 -> 3608 bytes
 packages/juniper_bgp_peer             |  20 ++++
 5 files changed, 377 insertions(+)
 create mode 100644 agent_based/inv_juniper_bgp_peer.py
 create mode 100644 agent_based/juniper_bgp_peer.py
 create mode 100644 agent_based/utils/juniper_bgp_peer.py
 create mode 100644 juniper_bgp_peer.mkp
 create mode 100644 packages/juniper_bgp_peer

diff --git a/agent_based/inv_juniper_bgp_peer.py b/agent_based/inv_juniper_bgp_peer.py
new file mode 100644
index 0000000..8fec6ae
--- /dev/null
+++ b/agent_based/inv_juniper_bgp_peer.py
@@ -0,0 +1,135 @@
+#!/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  : 2020-04-29
+#
+# inventory of Juniper BGP Peers (IPv4 and IPv6)
+#
+# THX to Jeff Fern jeff[dash]cmk[at]fcse[dot]co[dot]uk for testing and providing feedback to make this addon happen
+#
+# 2022-04-30: code cleanup/streamlining
+#
+
+
+from typing import List
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    SNMPTree,
+    OIDBytes,
+    startswith,
+    OIDEnd,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    StringByteTable,
+)
+from cmk.base.plugins.agent_based.utils.bgp_peer import (
+    InvBgpPeer,
+    bgp_error_as_string,
+    bgp_error_code_as_hex,
+    bgp_render_ip_address,
+    get_bgp_type,
+)
+from cmk.base.plugins.agent_based.utils.juniper_bgp_peer import (
+    juniper_afi_safi_mapping,
+)
+
+
+def parse_inv_juniper_bgp_peer(string_table: List[StringByteTable]):
+    peers, address_families, local_identifier = string_table
+
+    bgp_peers = []
+
+    try:
+        local_id = local_identifier[0][0]
+    except (ValueError, IndexError):
+        local_id = 'N/A'
+
+    peer_families = {}
+    for entry in address_families:
+        index, afi, safi = entry[0].split('.')
+        if peer_families.get(index):
+            peer_families[index] = peer_families[index] + [juniper_afi_safi_mapping(afi, safi)]
+        else:
+            peer_families[index] = [juniper_afi_safi_mapping(afi, safi)]
+
+    for entry in peers:
+        oid_end, remote_id, state, negotiated_version, local_addr_type, local_addr, local_as, remote_addr_type, \
+        remote_addr, remote_as, peer_index, routing_instance, fsm_established_time, fsm_established_trans, \
+        last_error_received = entry
+
+        # assuming IPv4 address format
+        remote_id = '.'.join([str(m) for m in remote_id])
+
+        bgp_peer: InvBgpPeer = {
+            'remote_addr': bgp_render_ip_address(remote_addr_type, remote_addr),
+            'remote_id': remote_id,
+            'version': negotiated_version,
+            'local_addr': bgp_render_ip_address(local_addr_type, local_addr),
+            'remote_as': remote_as,
+            'local_as': local_as,
+            'local_id': local_id,
+            'bgp_type': get_bgp_type(local_as, remote_as),
+            'fsm_established_time': int(fsm_established_time),
+            '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_received),
+            'last_error': bgp_error_as_string(last_error_received),
+            'status_columns': {},
+            'address_family': ', '.join(peer_families.get(peer_index, []))
+        }
+
+        bgp_peers.append(bgp_peer)
+
+    return bgp_peers
+
+
+register.snmp_section(
+    name='inv_juniper_bgp_peer',
+    parse_function=parse_inv_juniper_bgp_peer,
+    parsed_section_name='inv_bgp_peer',
+    supersedes=['inv_bgp_peer'],
+    fetch=[
+        SNMPTree(
+            base='.1.3.6.1.4.1.2636.5.1.1.2',  # BGP4-V2-MIB-JUNIPER::jnxBgpM2Peer
+            oids=[
+                OIDEnd(),
+                OIDBytes('1.1.1.1'),  # jnxBgpM2PeerIdentifier
+                '1.1.1.2',  # jnxBgpM2PeerState
+                # '1.1.1.3',  # jnxBgpM2PeerStatus
+                '1.1.1.4',  # jnxBgpM2PeerConfiguredVersion
+                # '1.1.1.5',  # jnxBgpM2PeerNegotiatedVersion --> is Null '0' :-(
+                '1.1.1.6',  # jnxBgpM2PeerLocalAddrType
+                OIDBytes('1.1.1.7'),  # jnxBgpM2PeerLocalAddr
+                # '1.1.1.8',  # jnxBgpM2PeerLocalPort
+                '1.1.1.9',  # jnxBgpM2PeerLocalAs
+                '1.1.1.10',  # jnxBgpM2PeerRemoteAddrType
+                OIDBytes('1.1.1.11'),  # jnxBgpM2PeerRemoteAddr
+                # '1.1.1.12',  # jnxBgpM2PeerRemotePort
+                '1.1.1.13',  # jnxBgpM2PeerRemoteAs
+                '1.1.1.14',  # jnxBgpM2PeerIndex
+                '1.1.1.15',  # jnxBgpM2PeerRoutingInstance
+                '4.1.1.1',  # jnxBgpM2PeerFsmEstablishedTime
+                '6.1.1.5',  # jnxBgpM2PeerFsmEstablishedTrans
+                OIDBytes('2.1.1.1'),  # jnxBgpM2PeerLastErrorReceived
+            ]
+        ),
+        SNMPTree(
+            base='.1.3.6.1.4.1.2636.5.1.1.2.6.2.1',  # BGP4-V2-MIB-JUNIPER::jnxBgpM2PrefixCountersEntry
+            oids=[
+                OIDEnd(),  # index.afi.safi
+                # '1',  # jnxBgpM2PrefixCountersAfi
+                # '2',  # jnxBgpM2PrefixCountersSafi
+            ]
+        ),
+        SNMPTree(
+            base='.1.3.6.1.4.1.2636.5.1.1.1',  # BGP4-V2-MIB-JUNIPER::nxBgpM2BaseScalars
+            oids=[
+                '6',  # jnxBgpM2LocalIdentifier
+            ]
+        )
+    ],
+    detect=startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2636.1.1.1'),
+),
diff --git a/agent_based/juniper_bgp_peer.py b/agent_based/juniper_bgp_peer.py
new file mode 100644
index 0000000..091b82c
--- /dev/null
+++ b/agent_based/juniper_bgp_peer.py
@@ -0,0 +1,160 @@
+#!/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  : 2022-04-27
+#
+# Monitor status of Juniper BGP Peers (IPv4 and IPv6)
+#
+# THX to Jeff Fern jeff[dash]cmk[at]fcse[dot]co[dot]uk for testing and providing feedback to make this addon happen
+#
+# 2022-04-30: code cleanup/streamlining
+# 2022-05-09: added item to BgpPeer class, this is used in the discovery function
+#
+
+import copy
+from typing import List, Dict, Optional, Tuple
+from dataclasses import dataclass
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    SNMPTree,
+    startswith,
+    OIDEnd,
+    OIDBytes,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    StringByteTable,
+)
+
+from cmk.base.plugins.agent_based.utils.bgp_peer import (
+    BgpPeer,
+    bgp_get_peer_entry,
+    bgp_render_ip_address,
+)
+
+from cmk.base.plugins.agent_based.utils.juniper_bgp_peer import (
+    juniper_afi_safi_mapping,
+)
+
+
+@dataclass
+class JuniperPrefixes:
+    afi: str
+    safi: str
+    accepted_prefixes: int
+    metric_count: List[Tuple[str, int]]
+    metric_rate: List[Tuple[str, int]]
+
+
+def parse_juniper_bgp_peer(string_table: List[StringByteTable]) -> Optional[Dict[str, BgpPeer]]:
+    jnxBgpM2Peer, jnxBgpM2PrefixCountersEntry = string_table
+    peer_table = {}
+    peer_prefixes = {}
+
+    for entry in jnxBgpM2PrefixCountersEntry:
+        oid_end, in_prefixes, in_prefixes_accepted, in_prefixes_rejected, out_prefixes, in_prefixes_active = entry
+        index, afi, safi = oid_end.split('.')  # peer index, afi, safi
+        prefixes = JuniperPrefixes(
+            afi=afi,
+            safi=safi,
+            accepted_prefixes=int(in_prefixes_accepted),
+            metric_rate=[],
+            metric_count=[
+                ('in_prefixes', int(in_prefixes)),
+                # ('in_prefixes_accepted', int(in_prefixes_accepted)),
+                ('in_prefixes_rejected', int(in_prefixes_rejected)),
+                ('out_prefixes', int(out_prefixes)),
+                ('in_prefixes_active', int(in_prefixes_active)),
+            ],
+        )
+
+        if peer_prefixes.get(index):
+            peer_prefixes[index].append(prefixes)
+        else:
+            peer_prefixes[index] = [prefixes]
+
+    for entry in jnxBgpM2Peer:
+        # extract values and adjust format
+        oid_end = entry[0]
+        entry.pop(0)
+        PeerRemoteAddrType = entry[0]
+        entry.pop(0)
+        PeerIndex = entry[0]
+        entry.pop(0)
+        PeerRoutingInstance = entry[0]
+        entry.pop(0)
+
+        remote_address = bgp_render_ip_address(PeerRemoteAddrType, entry[0])
+        entry[0] = remote_address
+
+        bgp_peer = bgp_get_peer_entry(entry)
+
+        prefixes = peer_prefixes.get(PeerIndex, [])
+        for address_family in prefixes:
+            address_family_str = juniper_afi_safi_mapping(address_family.afi, address_family.safi)
+            item = f'{remote_address} {address_family_str}'
+            # ToDo: add vrf name
+            routing_instance = ''
+            if PeerRoutingInstance != '0':
+                routing_instance = f'VR {PeerRoutingInstance}'
+                item = f'{item} {routing_instance}'
+            peer_table[item] = copy.deepcopy(bgp_peer[remote_address])
+            peer_table[item].accepted_prefixes = address_family.accepted_prefixes
+            peer_table[item].metric_count += address_family.metric_count
+            peer_table[item].metric_rate += address_family.metric_rate
+            peer_table[item].item['address_family'] = address_family_str
+            peer_table[item].item['routing_instance'] = routing_instance
+    return peer_table
+
+
+register.snmp_section(
+    name='juniper_bgp_peer',
+    parse_function=parse_juniper_bgp_peer,
+    parsed_section_name='bgp_peer',
+    supersedes=['bgp_peer'],
+    fetch=[
+        SNMPTree(
+            base='.1.3.6.1.4.1.2636.5.1.1.2',  # BGP4-V2-MIB-JUNIPER::jnxBgpM2Peer
+            oids=[
+                OIDEnd(),
+                '1.1.1.10',  # jnxBgpM2PeerRemoteAddrType
+                '1.1.1.14',  # jnxBgpM2PeerIndex
+                '1.1.1.15',  # jnxBgpM2PeerRoutingInstance
+                # needs to be in this order to match bgp_peer
+                OIDBytes('1.1.1.11'),  # jnxBgpM2PeerRemoteAddr
+                '1.1.1.2',  # jnxBgpM2PeerState
+                '1.1.1.3',  # jnxBgpM2PeerStatus (admin status(?))
+                '6.1.1.1',  # jnxBgpM2PeerInUpdates
+                '6.1.1.2',  # jnxBgpM2PeerOutUpdates
+                '6.1.1.3',  # jnxBgpM2PeerInTotalMessages
+                '6.1.1.4',  # jnxBgpM2PeerOutTotalMessages
+                '6.1.1.5',  # jnxBgpM2PeerFsmEstablishedTrans
+                '4.1.1.1',  # jnxBgpM2PeerFsmEstablishedTime
+                '4.1.1.2',  # jnxBgpM2PeerInUpdatesElapsedTime
+            ]
+        ),
+        SNMPTree(
+            base='.1.3.6.1.4.1.2636.5.1.1.2.6.2.1',  # BGP4-V2-MIB-JUNIPER::jnxBgpM2PrefixCountersEntry
+            oids=[
+                OIDEnd(),  # index.afi.safi
+                # '1',  # jnxBgpM2PrefixCountersAfi
+                # '2',  # jnxBgpM2PrefixCountersSafi
+                '7',  # jnxBgpM2PrefixInPrefixes
+                '8',  # jnxBgpM2PrefixInPrefixesAccepted
+                '9',  # jnxBgpM2PrefixInPrefixesRejected
+                '10',  # jnxBgpM2PrefixOutPrefixes
+                '11',  # jnxBgpM2PrefixInPrefixesActive
+            ]
+        ),
+    ],
+    detect=startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2636.1.1.1'),
+),
+
+# jnxBgpM2CfgPeerAdminStatus
+# 1.3.6.1.4.1.2636.5.1.1.2.8.1.1.1
+# stop(1)
+# start(2)
diff --git a/agent_based/utils/juniper_bgp_peer.py b/agent_based/utils/juniper_bgp_peer.py
new file mode 100644
index 0000000..612201f
--- /dev/null
+++ b/agent_based/utils/juniper_bgp_peer.py
@@ -0,0 +1,62 @@
+#!/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  : 2022-04-29
+#
+# include file, will be used with juniper_bgp_peer and inv_juniper_bgp_peer
+#
+#
+from typing import List
+import ipaddress
+
+
+def juniper_address_type(st: str):
+    names = {
+        '0': 'unknown',
+        '1': 'ipv4',
+        '2': 'ipv6',
+        '3': 'ipv4z',
+        '4': 'ipv6z',
+        '16': 'dns'
+    }
+    return names.get(st, st)
+
+
+def juniper_address_family(st: str):
+    names = {
+        '0': 'unknown',
+        '1': 'ipv4',
+        '2': 'ipv6',
+        '3': 'ipv4z',
+        '4': 'ipv6z',
+        '16': 'dns'
+    }
+    return names.get(st, st)
+
+
+def juniper_afi_safi_mapping(afi: str, safi: str) -> str:
+    names = {
+        (1, 1): 'IPv4 unicast',
+        (1, 2): 'IPv4 multicast',
+        (1, 128): 'L3VPN IPv4 unicast',
+        (1, 129): 'L3VPN IPv4 multicast',
+        (2, 1): 'IPv6 unicast',
+        (2, 2): 'IPv6 multicast',
+        (25, 65): 'BGP-VPLS/BGP-L2VPN',
+        (2, 128): 'L3VPN IPv6 unicast',
+        (2, 129): 'L3VPN IPv6 multicast',
+        (1, 132): 'RT-Constrain',
+        (1, 133): 'Flow-spec',
+        (1, 134): 'Flow-spec',
+        (3, 128): 'CLNS VPN',
+        (1, 5): 'NG-MVPN IPv4',
+        (2, 5): 'NG-MVPN IPv6',
+        (1, 66): 'MDT-SAFI',
+        (1, 4): 'labeled IPv4',
+        (2, 4): 'labeled IPv6 (6PE)',
+    }
+    return names.get((int(afi), int(safi)), f'AFI {afi} SAFI {safi}')
diff --git a/juniper_bgp_peer.mkp b/juniper_bgp_peer.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..deb13e7c84ba8a765353f2d94ef355c8ec59a9e5
GIT binary patch
literal 3608
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
W)5+!ie~A&i<s^q6ixPwr5d0s4n*4wO

literal 0
HcmV?d00001

diff --git a/packages/juniper_bgp_peer b/packages/juniper_bgp_peer
new file mode 100644
index 0000000..dd8fe81
--- /dev/null
+++ b/packages/juniper_bgp_peer
@@ -0,0 +1,20 @@
+{'author': 'thl-cmk[at]outlook[dot]com',
+ 'description': 'Monitors Juniper BGP peers BGP4-V2-MIB-JUNIPER). \n'
+                '\n'
+                '- creates one service for each peer/address family  (IPv4 and '
+                'IPv6)\n'
+                '\n'
+                'NOTE: to use this plugin you must also install my bgp_peer" '
+                'plugin '
+                '(https://thl-cmk.hopto.org/gitlab/checkmk/vendor-independent/bgp_peer)\n',
+ 'download_url': 'https://thl-cmk.hopto.org',
+ 'files': {'agent_based': ['juniper_bgp_peer.py',
+                           'inv_juniper_bgp_peer.py',
+                           'utils/juniper_bgp_peer.py']},
+ 'name': 'juniper_bgp_peer',
+ 'num_files': 3,
+ 'title': 'Juniper BGP peer',
+ 'version': '20220509.v.0.0.4',
+ 'version.min_required': '2.0.0',
+ 'version.packaged': '2021.09.20',
+ 'version.usable_until': None}
\ No newline at end of file
-- 
GitLab