From d675d1146c263471804651550b66a1feed3deb3d Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Wed, 15 Sep 2021 22:28:37 +0200
Subject: [PATCH] update project

---
 agent_based/ospf_neighbor.py         |  85 ++++++++------
 ospf_neighbor.mkp                    | Bin 7706 -> 7799 bytes
 web/plugins/metrics/ospf_neighbor.py |  17 ++-
 web/plugins/wato/ospf_neighbor.py    | 170 +++++++++++++--------------
 4 files changed, 149 insertions(+), 123 deletions(-)

diff --git a/agent_based/ospf_neighbor.py b/agent_based/ospf_neighbor.py
index 186f5e2..3a23510 100644
--- a/agent_based/ospf_neighbor.py
+++ b/agent_based/ospf_neighbor.py
@@ -40,30 +40,41 @@
 ###############################################################################
 
 # Example Agent Output:
-# OSPF-MIB
-
-# 1.3.6.1.2.1.14.10.1.1.172.20.2.214.0 = IpAddress: 172.20.2.214
-# 1.3.6.1.2.1.14.10.1.2.172.20.2.214.0 = INTEGER: 0
-# 1.3.6.1.2.1.14.10.1.3.172.20.2.214.0 = IpAddress: 192.168.1.2
-# 1.3.6.1.2.1.14.10.1.4.172.20.2.214.0 = INTEGER: 2
-# 1.3.6.1.2.1.14.10.1.5.172.20.2.214.0 = INTEGER: 1
-# 1.3.6.1.2.1.14.10.1.6.172.20.2.214.0 = INTEGER: 8
-# 1.3.6.1.2.1.14.10.1.7.172.20.2.214.0 = Counter32: 6
-# 1.3.6.1.2.1.14.10.1.8.172.20.2.214.0 = Gauge32: 0
-# 1.3.6.1.2.1.14.10.1.9.172.20.2.214.0 = INTEGER: 1
-# 1.3.6.1.2.1.14.10.1.10.172.20.2.214.0 = INTEGER: 1
-# 1.3.6.1.2.1.14.10.1.11.172.20.2.214.0 = INTEGER: 2
+# OSPF-MIB::ospfNbrEntry
+
+# .1.3.6.1.2.1.14.10.1.1.172.17.108.52.0 = IpAddress: 172.17.108.52
+# .1.3.6.1.2.1.14.10.1.1.172.17.108.60.0 = IpAddress: 172.17.108.60
+# .1.3.6.1.2.1.14.10.1.2.172.17.108.52.0 = INTEGER: 0
+# .1.3.6.1.2.1.14.10.1.2.172.17.108.60.0 = INTEGER: 0
+# .1.3.6.1.2.1.14.10.1.3.172.17.108.52.0 = IpAddress: 10.253.128.139
+# .1.3.6.1.2.1.14.10.1.3.172.17.108.60.0 = IpAddress: 10.253.128.139
+# .1.3.6.1.2.1.14.10.1.4.172.17.108.52.0 = INTEGER: 2
+# .1.3.6.1.2.1.14.10.1.4.172.17.108.60.0 = INTEGER: 2
+# .1.3.6.1.2.1.14.10.1.5.172.17.108.52.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.5.172.17.108.60.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.6.172.17.108.52.0 = INTEGER: 8
+# .1.3.6.1.2.1.14.10.1.6.172.17.108.60.0 = INTEGER: 8
+# .1.3.6.1.2.1.14.10.1.7.172.17.108.52.0 = Counter32: 6
+# .1.3.6.1.2.1.14.10.1.7.172.17.108.60.0 = Counter32: 6
+# .1.3.6.1.2.1.14.10.1.8.172.17.108.52.0 = Gauge32: 0
+# .1.3.6.1.2.1.14.10.1.8.172.17.108.60.0 = Gauge32: 0
+# .1.3.6.1.2.1.14.10.1.9.172.17.108.52.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.9.172.17.108.60.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.10.172.17.108.52.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.10.172.17.108.60.0 = INTEGER: 1
+# .1.3.6.1.2.1.14.10.1.11.172.17.108.52.0 = INTEGER: 2
+# .1.3.6.1.2.1.14.10.1.11.172.17.108.60.0 = INTEGER: 2
 #
 # sample parsed
 # {
-#  '172.17.108.52': {'helperage': '', 'prio': '1', 'permanence': 'dynamic', 'helperstatus': '', 'options': '2',
-#                    'state': '8', 'hellosup': 'false', 'helperexitreason': '', 'events': 6, 'rtrid': '10.250.128.130'},
-#  '172.17.108.60': {'helperage': '', 'prio': '1', 'permanence': 'dynamic', 'helperstatus': '', 'options': '2',
-#                    'state': '8', 'hellosup': 'false', 'helperexitreason': '', 'events': 6, 'rtrid': '10.253.128.101'},
-#  '172.17.108.58': {'helperage': '', 'prio': '1', 'permanence': 'dynamic', 'helperstatus': '', 'options': '2',
-#                    'state': '8', 'hellosup': 'false', 'helperexitreason': '', 'events': 12, 'rtrid': '172.17.0.2'},
-#  '172.17.108.49': {'helperage': '', 'prio': '1', 'permanence': 'dynamic', 'helperstatus': '', 'options': '2',
-#                    'state': '8', 'hellosup': 'false', 'helperexitreason': '', 'events': 9, 'rtrid': '172.17.0.2'}
+#  '172.17.108.52': OspfNeighbor(
+#       rtrid='10.253.128.139', options='not a stub area', prio='1', state='8', events=6,
+#       permanence='dynamic', hellosup='false', helperstatus='', helperage='', helperexitreason=''
+#      ),
+#  '172.17.108.60': OspfNeighbor(
+#       rtrid='10.253.128.139', options='not a stub area', prio='1', state='8', events=6,
+#       permanence='dynamic', hellosup='false', helperstatus='', helperage='', helperexitreason=''
+#      )
 # }
 #
 
@@ -93,6 +104,7 @@ class OspfNeighbor:
     prio: str
     state: str
     events: int
+    lsretransqlen: int
     permanence: str
     hellosup: str
     helperstatus: str
@@ -158,7 +170,7 @@ def parse_ospf_neighbor(string_table: StringTable) -> Dict[str, OspfNeighbor]:
             return options
 
     parsed = {}
-    for ip, rtrid, options, prio, state, events, permanence, hellosup, helperstatus, helperage, \
+    for ip, rtrid, options, prio, state, events, lsretransqlen, permanence, hellosup, helperstatus, helperage, \
         helperexitreason in string_table:
         parsed[ip] = OspfNeighbor(
             rtrid=rtrid,
@@ -166,6 +178,7 @@ def parse_ospf_neighbor(string_table: StringTable) -> Dict[str, OspfNeighbor]:
             prio=prio,
             state=state,
             events=int(events),
+            lsretransqlen=int(lsretransqlen),
             permanence=ospf_nbr_permanence(str(permanence)),
             hellosup=ospf_nbr_hellosuppressed(hellosup),
             helperstatus=ospf_nbr_helperstatus(helperstatus),
@@ -204,7 +217,7 @@ def check_ospf_neighbor(item, params, section: Dict[str, OspfNeighbor]) -> Check
         '8': 0,  # full
     }
 
-    not_found_state = params['state_not_found', 3]
+    not_found_state = params['state_not_found']
 
     for neighbour, neighbourAlias, neighbourNotFoundState in params.get('peer_list', []):
         if item == neighbour:
@@ -221,9 +234,10 @@ def check_ospf_neighbor(item, params, section: Dict[str, OspfNeighbor]) -> Check
 
     neighborstate.update(params.get('neighborstate', neighborstate))  # update neighborstatus with params
 
-    yield Result(state=State(neighborstate.get(neighbor.state, 3)), summary=f'Status {ospf_nbr_state(neighbor.state)}')
+    yield Result(state=State(neighborstate.get(neighbor.state, 3)), summary=f'Status: {ospf_nbr_state(neighbor.state)}')
 
     yield Metric(value=neighbor.events, name='ospf_neighbor_ospf_events')
+    yield Metric(value=neighbor.lsretransqlen, name='ospf_neighbor_ospf_retransmission_queue_length')
 
     for text, value in [
         ('options', neighbor.options),
@@ -244,17 +258,18 @@ register.snmp_section(
     fetch=SNMPTree(
         base='.1.3.6.1.2.1.14.10.1',  # OSPF-MIB::ospfNbrEntry
         oids=[
-            '1',  # 'ospfNbrIpAddr'
-            '3',  # 'ospfNbrRtrId'
-            '4',  # 'ospfNbrOptions'
-            '5',  # 'ospfNbrPriority'
-            '6',  # 'ospfNbrState
-            '7',  # 'ospfNbrEvents'
-            '10',  # 'ospfNbrPermanence'
-            '11',  # 'ospfNbrHelloSuppressed'
-            '12',  # 'ospfNbrRestartHelperStatus'
-            '13',  # 'ospfNbrRestartHelperAge'
-            '14',  # 'ospfNbrRestartHelperExitReason'
+            '1',  # ospfNbrIpAddr
+            '3',  # ospfNbrRtrId
+            '4',  # ospfNbrOptions
+            '5',  # ospfNbrPriority
+            '6',  # ospfNbrStat
+            '7',  # ospfNbrEvents
+            '8',  # ospfNbrLSRetransQLen
+            '10',  # ospfNbrPermanence
+            '11',  # ospfNbrHelloSuppressed
+            '12',  # ospfNbrRestartHelperStatus
+            '13',  # ospfNbrRestartHelperAge
+            '14',  # ospfNbrRestartHelperExitReason
         ]
     ),
     detect=exists('.1.3.6.1.2.1.14.10.1.1.*')
diff --git a/ospf_neighbor.mkp b/ospf_neighbor.mkp
index 825399809418c202d2535f282c00a9c8f9b7debe..bb13a13727b2dbf2cb47615687ef6363353c9f83 100644
GIT binary patch
delta 7763
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
ZSCj4?ACu4y2n<<Y{tx0R-WLGK004ND6~6!g

delta 7658
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
YhxJvH{SGG${vhT50FTHZumH#a0M(N4wEzGB

diff --git a/web/plugins/metrics/ospf_neighbor.py b/web/plugins/metrics/ospf_neighbor.py
index 5ed4d45..b82044f 100644
--- a/web/plugins/metrics/ospf_neighbor.py
+++ b/web/plugins/metrics/ospf_neighbor.py
@@ -23,9 +23,16 @@ from cmk.gui.plugins.metrics import (
 metric_info['ospf_neighbor_ospf_events'] = {
     'title': _('Events'),
     'unit': 'count',
-    'color': '26/a',
+    'color': '16/a',
 }
 
+metric_info['ospf_neighbor_ospf_retransmission_queue_length'] = {
+    'title': _('Retransmission queue length'),
+    'unit': 'count',
+    'color': '36/a',
+}
+
+
 ######################################################################################################################
 #
 # how to graph perdata for OSPF neighbor
@@ -39,6 +46,12 @@ graph_info['ospf_neighbor_ospf_events'] = {
     ],
 }
 
+graph_info['ospf_neighbor_ospf_retransmission_queue_length'] = {
+    'title': _('OSPF neighbor Retransmission queue length'),
+    'metrics': [
+        ('ospf_neighbor_ospf_retransmission_queue_length', 'area'),
+    ],
+}
 ######################################################################################################################
 #
 # define perf-o-meter for OSPF neighbor events
@@ -48,5 +61,5 @@ graph_info['ospf_neighbor_ospf_events'] = {
 perfometer_info.append({
     'type': 'linear',
     'segments': ['ospf_neighbor_ospf_events'],
-    'total': 100,
+    # 'total': 100,
 })
diff --git a/web/plugins/wato/ospf_neighbor.py b/web/plugins/wato/ospf_neighbor.py
index 16c9b98..634ab3a 100644
--- a/web/plugins/wato/ospf_neighbor.py
+++ b/web/plugins/wato/ospf_neighbor.py
@@ -18,7 +18,6 @@ from cmk.gui.valuespec import (
     Tuple,
     TextUnicode,
     MonitoringState,
-    Transform,
 )
 
 from cmk.gui.plugins.wato import (
@@ -29,92 +28,91 @@ from cmk.gui.plugins.wato import (
 
 
 def _parameter_valuespec_ospf_neighbor():
-    return Transform(
-        Dictionary(
-            elements=[
-                ('state_not_found',
-                 MonitoringState(
-                     title=_('State to report if neighbor not found'),
-                     help=_('Monitoring state if the neighbor not found in the SNMP data.'),
-                     default_value=3,
-                 )),
-                ('neighborstate',
-                 Dictionary(
-                     title=_('State to report for OSPF neighbor state'),
+    return Dictionary(
+        elements=[
+            ('state_not_found',
+             MonitoringState(
+                 title=_('State to report if neighbor not found'),
+                 help=_('Monitoring state if the neighbor not found in the SNMP data.'),
+                 default_value=3,
+             )),
+            ('neighborstate',
+             Dictionary(
+                 title=_('State to report for OSPF neighbor state'),
+                 elements=[
+                     ('1',
+                      MonitoringState(
+                          title=_('1 - down'),
+                          default_value=2,
+                      )),
+                     ('2',
+                      MonitoringState(
+                          title=_('2 - attempt'),
+                          default_value=1,
+                      )),
+                     ('3',
+                      MonitoringState(
+                          title=_('3 - init'),
+                          default_value=1,
+                      )),
+                     ('4',
+                      MonitoringState(
+                          title=_('4 - twoWay'),
+                          default_value=0,
+                      )),
+                     ('5',
+                      MonitoringState(
+                          title=_('5 - exchangeStart'),
+                          default_value=1,
+                      )),
+                     ('6',
+                      MonitoringState(
+                          title=_('6 - exchange'),
+                          default_value=1,
+                      )),
+                     ('7',
+                      MonitoringState(
+                          title=_('7 - loading'),
+                          default_value=1,
+                      )),
+                     ('8',
+                      MonitoringState(
+                          title=_('8 - full'),
+                          default_value=0,
+                      )),
+                 ])
+             ),
+            ('peer_list',
+             ListOf(
+                 Tuple(
+                     title=('OSPF Neighbors'),
                      elements=[
-                         ('1',
-                          MonitoringState(
-                              title=_('1 - down'),
-                              default_value=2,
-                          )),
-                         ('2',
-                          MonitoringState(
-                              title=_('2 - attempt'),
-                              default_value=1,
-                          )),
-                         ('3',
-                          MonitoringState(
-                              title=_('3 - init'),
-                              default_value=1,
-                          )),
-                         ('4',
-                          MonitoringState(
-                              title=_('4 - twoWay'),
-                              default_value=0,
-                          )),
-                         ('5',
-                          MonitoringState(
-                              title=_('5 - exchangeStart'),
-                              default_value=1,
-                          )),
-                         ('6',
-                          MonitoringState(
-                              title=_('6 - exchange'),
-                              default_value=1,
-                          )),
-                         ('7',
-                          MonitoringState(
-                              title=_('7 - loading'),
-                              default_value=1,
-                          )),
-                         ('8',
-                          MonitoringState(
-                              title=_('8 - full'),
-                              default_value=0,
-                          )),
-                     ])
-                 ),
-                ('peer_list',
-                 ListOf(
-                     Tuple(
-                         title=('OSPF Neighbors'),
-                         elements=[
-                             TextUnicode(
-                                 title=_('OSPF Neighbor IP address'),
-                                 help=_(
-                                     'The configured value must match a OSPF Neighbor item reported by the monitored '
-                                     'device. For example: "10.10.10.10"'),
-                                 allow_empty=False,
-                             ),
-                             TextUnicode(
-                                 title=_('OSPF Neighbor Alias'),
-                                 help=_('You can configure an individual alias here for the OSPF Neighbor matching '
-                                        'the text configured in the "OSPF Neighbor IP address" field. The alias will '
-                                        'be shown in the infotext'),
-                                 allow_empty=False,
-                             ),
-                             MonitoringState(
-                                 default_value=2,
-                                 title=_('State if not found'),
-                                 help=_('You can configure an individual state if the OSPF Neighbor matching the text '
-                                        'configured in the "OSPF Neighbor IP address" field is not found')
-                             )]),
-                     add_label=_('Add OSPF Neighbor'),
-                     movable=False,
-                     title=_('OSPF Neighbor specific configuration'),
-                 )),
-            ],
-        ))
+                         TextUnicode(
+                             title=_('OSPF Neighbor IP address'),
+                             help=_(
+                                 'The configured value must match a OSPF Neighbor item reported by the monitored '
+                                 'device. For example: "10.10.10.10"'),
+                             allow_empty=False,
+                         ),
+                         TextUnicode(
+                             title=_('OSPF Neighbor Alias'),
+                             help=_('You can configure an individual alias here for the OSPF Neighbor matching '
+                                    'the text configured in the "OSPF Neighbor IP address" field. The alias will '
+                                    'be shown in the infotext'),
+                             allow_empty=False,
+                         ),
+                         MonitoringState(
+                             default_value=2,
+                             title=_('State if not found'),
+                             help=_('You can configure an individual state if the OSPF Neighbor matching the text '
+                                    'configured in the "OSPF Neighbor IP address" field is not found')
+                         )]),
+                 add_label=_('Add OSPF Neighbor'),
+                 movable=False,
+                 title=_('OSPF Neighbor specific configuration'),
+             )),
+        ],
+    )
 
 
 rulespec_registry.register(
-- 
GitLab