From c060eace61479ca6d423b934f76818fc8bf4ee31 Mon Sep 17 00:00:00 2001
From: "Th.L" <thl-cmk@outlook.com>
Date: Wed, 24 Mar 2021 20:37:28 +0100
Subject: [PATCH] update project

---
 agent_based/cisco_asyncos_mem.py     |   6 +-
 agent_based/cisco_asyncos_raid.py    | 140 +++++++++++++++++++++++++++
 checks/cisco_asyncos_raid            |  87 -----------------
 cisco_asyncos.mkp                    | Bin 11776 -> 11910 bytes
 packages/cisco_asyncos               |   9 +-
 web/plugins/metrics/cisco_asyncos.py |  32 +++---
 6 files changed, 164 insertions(+), 110 deletions(-)
 create mode 100644 agent_based/cisco_asyncos_raid.py
 delete mode 100644 checks/cisco_asyncos_raid

diff --git a/agent_based/cisco_asyncos_mem.py b/agent_based/cisco_asyncos_mem.py
index 55f19f0..f50d747 100644
--- a/agent_based/cisco_asyncos_mem.py
+++ b/agent_based/cisco_asyncos_mem.py
@@ -19,13 +19,13 @@
 
 from typing import Mapping, Dict, List, Tuple, NamedTuple
 
-from .agent_based_api.v1.type_defs import (
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
     CheckResult,
     StringTable,
 )
 
-from .agent_based_api.v1 import (
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     register,
     Service,
     check_levels,
@@ -60,7 +60,7 @@ def check_cisco_asyncos_mem(params, section: int) -> CheckResult:
         section,
         label='Memory utilization',
         levels_upper=params.get('util', None),
-        metric_name='util',  # if params.get('output_metrics') else None,
+        metric_name='util',
         render_func=render_percent,
     )
 
diff --git a/agent_based/cisco_asyncos_raid.py b/agent_based/cisco_asyncos_raid.py
new file mode 100644
index 0000000..be917e5
--- /dev/null
+++ b/agent_based/cisco_asyncos_raid.py
@@ -0,0 +1,140 @@
+#!/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-02-10
+#
+#
+# monitors status raid arrays of Cisco IronPort Appliances (ESA/SMA/WSA)
+# Tested with: C380, M380, C370, M670, S370
+#
+# 2021-03-24: rewrite for CMK 2.0
+#
+# OMD[cmk16x]:~$ snmpwalk  -v2c -c C370-MAIL localhost -m ASYNCOS-MAIL-MIB -ObentU raidTable
+# .1.3.6.1.4.1.15497.1.1.1.18.1.1.1 = INTEGER: 1
+# .1.3.6.1.4.1.15497.1.1.1.18.1.1.2 = INTEGER: 2
+# .1.3.6.1.4.1.15497.1.1.1.18.1.2.1 = INTEGER: 1
+# .1.3.6.1.4.1.15497.1.1.1.18.1.2.2 = INTEGER: 1
+# .1.3.6.1.4.1.15497.1.1.1.18.1.3.1 = STRING: Drive 0
+# .1.3.6.1.4.1.15497.1.1.1.18.1.3.2 = STRING: Drive 1
+# .1.3.6.1.4.1.15497.1.1.1.18.1.4.1 = STRING: No Errors
+# .1.3.6.1.4.1.15497.1.1.1.18.1.4.2 = STRING: No Errors
+# 
+# OMD[cmk16x]:~$ snmpwalk  -v2c -c C370-MAIL localhost -m ASYNCOS-MAIL-MIB  raidTable
+# ASYNCOS-MAIL-MIB::raidIndex.1 = INTEGER: 1
+# ASYNCOS-MAIL-MIB::raidIndex.2 = INTEGER: 2
+# ASYNCOS-MAIL-MIB::raidStatus.1 = INTEGER: driveHealthy(1)
+# ASYNCOS-MAIL-MIB::raidStatus.2 = INTEGER: driveHealthy(1)
+# ASYNCOS-MAIL-MIB::raidID.1 = STRING: Drive 0
+# ASYNCOS-MAIL-MIB::raidID.2 = STRING: Drive 1
+# ASYNCOS-MAIL-MIB::raidLastError.1 = STRING: No Errors
+# ASYNCOS-MAIL-MIB::raidLastError.2 = STRING: No Errors
+#
+from typing import Mapping, List, NamedTuple
+
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    DiscoveryResult,
+    CheckResult,
+    StringTable,
+)
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    Service,
+    Result,
+    SNMPTree,
+    contains,
+    State,
+)
+
+
+class CiscoAsyncosRaid(NamedTuple):
+    state: State
+    status_readable: str
+    lasterror: str
+
+
+def get_cmk_state(st: str) -> State:
+    states = {
+        '1': State.OK,
+        '2': State.CRIT,
+        '3': State.WARN
+    }
+    return states.get(st, State.CRIT)
+
+
+def get_status_readable(st: str) -> str:
+    states = {
+        '1': 'healthy',
+        '2': 'failure',
+        '3': 'rebuild',
+    }
+    return states.get(st, st)
+
+
+# [[
+#   ['1', 'Drive 0', 'No Errors'],
+#   ['2', 'Drive 1', 'UNKNOWN'],
+#   ['1', 'Drive 2', 'No Errors'],
+#   ['1', 'Drive 3', 'No Errors'],
+#   ['1', 'Drive 4', 'No Errors'],
+#   ['1', 'Drive 5', 'No Errors']
+#  ]]
+def parse_cisco_asyncos_raid(string_table: List[StringTable]) -> Mapping[str, CiscoAsyncosRaid]:
+    arrays = {}
+    for raidStatus, raidID, raidLastError in string_table[0]:
+        arrays.update({raidID: CiscoAsyncosRaid(
+            state=get_cmk_state(raidStatus),
+            status_readable=get_status_readable(raidStatus),
+            lasterror=raidLastError
+        )})
+    return arrays
+
+
+# {
+#  'Drive 0': CiscoAsyncosRaid(state=<State.OK: 0>, status_readable='Ok', lasterror='No Errors'),
+#  'Drive 1': CiscoAsyncosRaid(state=<State.CRIT: 2>, status_readable='failure', lasterror='UNKNOWN'),
+#  'Drive 2': CiscoAsyncosRaid(state=<State.OK: 0>, status_readable='Ok', lasterror='No Errors'),
+#  'Drive 3': CiscoAsyncosRaid(state=<State.OK: 0>, status_readable='Ok', lasterror='No Errors'),
+#  'Drive 4': CiscoAsyncosRaid(state=<State.OK: 0>, status_readable='Ok', lasterror='No Errors'),
+#  'Drive 5': CiscoAsyncosRaid(state=<State.OK: 0>, status_readable='Ok', lasterror='No Errors')
+# }
+
+def discovery_cisco_asyncos_raid(section: Mapping[str, CiscoAsyncosRaid]) -> DiscoveryResult:
+    yield from (Service(item=item) for item in section.keys())
+
+
+def check_cisco_asyncos_raid(item, section: Mapping[str, CiscoAsyncosRaid]) -> CheckResult:
+    try:
+        yield Result(state=section[item].state,
+                     summary='RAID status: %s, last error: %s' % (section[item].state, section[item].lasterror),
+                     )
+    except KeyError:
+        pass
+
+
+register.snmp_section(
+    name='cisco_asyncos_raid',
+    parse_function=parse_cisco_asyncos_raid,
+    fetch=[
+        SNMPTree(
+            base='.1.3.6.1.4.1.15497.1.1.1.18.1',  # ASYNCOS-MAIL-MIB::raidEntry
+            oids=[
+                '2',  # raidStatus
+                '3',  # raidID
+                '4',  # raidLastError
+            ]
+        ),
+    ],
+    detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
+)
+
+register.check_plugin(
+    name='cisco_asyncos_raid',
+    service_name='RAID %s',
+    discovery_function=discovery_cisco_asyncos_raid,
+    check_function=check_cisco_asyncos_raid,
+)
diff --git a/checks/cisco_asyncos_raid b/checks/cisco_asyncos_raid
deleted file mode 100644
index 1aed36d..0000000
--- a/checks/cisco_asyncos_raid
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/python
-# -*- encoding: utf-8; py-indent-offset: 4 -*-
-#
-# Author: Th.L.
-# Date: 10-02-2020
-#
-# monitors status raid arrays of Cisco IronPort Appliances (ESA/SMA/WSA)
-# Tested with: C380, M380, C370, M670, S370
-#
-#
-#
-# OMD[cmk16x]:~$ snmpwalk  -v2c -c C370-MAIL localhost -m ASYNCOS-MAIL-MIB -ObentU raidTable
-# .1.3.6.1.4.1.15497.1.1.1.18.1.1.1 = INTEGER: 1
-# .1.3.6.1.4.1.15497.1.1.1.18.1.1.2 = INTEGER: 2
-# .1.3.6.1.4.1.15497.1.1.1.18.1.2.1 = INTEGER: 1
-# .1.3.6.1.4.1.15497.1.1.1.18.1.2.2 = INTEGER: 1
-# .1.3.6.1.4.1.15497.1.1.1.18.1.3.1 = STRING: Drive 0
-# .1.3.6.1.4.1.15497.1.1.1.18.1.3.2 = STRING: Drive 1
-# .1.3.6.1.4.1.15497.1.1.1.18.1.4.1 = STRING: No Errors
-# .1.3.6.1.4.1.15497.1.1.1.18.1.4.2 = STRING: No Errors
-# 
-# OMD[cmk16x]:~$ snmpwalk  -v2c -c C370-MAIL localhost -m ASYNCOS-MAIL-MIB  raidTable
-# ASYNCOS-MAIL-MIB::raidIndex.1 = INTEGER: 1
-# ASYNCOS-MAIL-MIB::raidIndex.2 = INTEGER: 2
-# ASYNCOS-MAIL-MIB::raidStatus.1 = INTEGER: driveHealthy(1)
-# ASYNCOS-MAIL-MIB::raidStatus.2 = INTEGER: driveHealthy(1)
-# ASYNCOS-MAIL-MIB::raidID.1 = STRING: Drive 0
-# ASYNCOS-MAIL-MIB::raidID.2 = STRING: Drive 1
-# ASYNCOS-MAIL-MIB::raidLastError.1 = STRING: No Errors
-# ASYNCOS-MAIL-MIB::raidLastError.2 = STRING: No Errors
-#
-
-
-def inventory_cisco_asyncos_raid(info, has_item, has_params=False):
-    if info:
-        params = None
-        if has_params:
-            params = {}
-        for line in info:
-            if has_item:
-                status, name, lasterror = line
-                item = name
-                yield item, params
-
-
-def check_cisco_asyncos_raid_states(states):
-    # Now we only known the OK states and health states
-    # but we can expand if we know more
-    map_states = {
-        'status': {
-            '1': (0, 'healthy'),
-            '2': (2, 'failure'),
-            '3': (1, 'rebuild'),
-        },
-    }
-    states_evaluated = {}
-    for what, text in states:
-        states_evaluated.setdefault(text, map_states[text.lower()].get(what.lower(), (2, 'not %s' % what.lower())))
-
-    return states_evaluated
-
-
-def check_cisco_asyncos_raid(item, _no_params, info):
-    for line in info:
-        status, name, lasterror = line
-        if item == name:
-            for text, (state, state_readable) in check_cisco_asyncos_raid_states([(status, 'Status')]).items():
-                yield state, '%s: %s' % (text, state_readable)
-            if lasterror.lower() != 'no errors':
-                yield 0, 'Last error: %s' % lasterror
-
-
-check_info['cisco_asyncos_raid'] = {
-    'inventory_function': lambda info: inventory_cisco_asyncos_raid(info, True),
-    'check_function': check_cisco_asyncos_raid,
-    'service_description': 'RAID %s',
-    'snmp_info': (
-        '.1.3.6.1.4.1.15497.1.1.1.18.1',  # ASYNCOS-MAIL-MIB::raidEntry
-        [
-            '2',  # raidStatus
-            '3',  # raidID
-            '4',  # raidLastError
-        ]),
-    'snmp_scan_function':  lambda oid: oid('.1.3.6.1.2.1.1.1.0').find('AsyncOS') != -1,
-    # 'snmp_scan_function': scan_cisco_asyncos,
-    # 'includes': ['cisco_asyncos.include'],
-}
\ No newline at end of file
diff --git a/cisco_asyncos.mkp b/cisco_asyncos.mkp
index 7ffc3e968140298a7b31323b262f25092a18aae7..ba5d874055af624ee806e377b40b58afb5b5c37b 100644
GIT binary patch
literal 11910
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

literal 11776
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
Q9st1#@Gd8VwSj~E557=#?f?J)

diff --git a/packages/cisco_asyncos b/packages/cisco_asyncos
index 7d32dda..c319a77 100644
--- a/packages/cisco_asyncos
+++ b/packages/cisco_asyncos
@@ -19,19 +19,20 @@
                 'ignore features\n'
                 '\n'
                 '- 2021-03-21: rewrite cisco_asyncos_cpu, cisco_asyncos_mem, '
-                'cisco_asyncos_temp for CMK 2.0\n',
+                'cisco_asyncos_temp for CMK 2.0\n'
+                '- 2021-03-24: rewrite cisco_asyncos_raid\n',
  'download_url': 'https://thl-cmk.hopto.org',
  'files': {'agent_based': ['cisco_asyncos_cpu.py',
                            'cisco_asyncos_mem.py',
                            'cisco_asyncos_temp.py',
                            'cisco_asyncos_fan.py',
-                           'cisco_asyncos_power.py'],
+                           'cisco_asyncos_power.py',
+                           'cisco_asyncos_raid.py'],
            'checks': ['cisco_asyncos_bandwidth',
                       'cisco_asyncos_cache',
                       'cisco_asyncos_conn',
                       'cisco_asyncos_license',
                       'cisco_asyncos_queue',
-                      'cisco_asyncos_raid',
                       'cisco_asyncos_update',
                       'cisco_asyncos_dns',
                       'cisco_asyncos_messageage',
@@ -43,7 +44,7 @@
  'name': 'cisco_asyncos',
  'num_files': 19,
  'title': 'Cisco AsyncOS (IronPort) checks',
- 'version': '20200514_v0.1.4',
+ 'version': '20210324_v0.2.0',
  'version.min_required': '2.0.0',
  'version.packaged': '2.0.0p1',
  'version.usable_until': None}
\ No newline at end of file
diff --git a/web/plugins/metrics/cisco_asyncos.py b/web/plugins/metrics/cisco_asyncos.py
index 7bfd522..ee23130 100644
--- a/web/plugins/metrics/cisco_asyncos.py
+++ b/web/plugins/metrics/cisco_asyncos.py
@@ -1,18 +1,18 @@
-#!/usr/bin/python
-# -*- encoding: utf-8; py-indent-offset: 4 -*-
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
 #
 # Cisco AsyncOS metrics plugin
 #
 # Author: Th.L.
 # Date  : 2020-03-08
 #
+from cmk.gui.i18n import _
 
-#####################################################################################################################
-#
-# define units for cisco_ise perfdata
-#
-#####################################################################################################################
-
+from cmk.gui.plugins.metrics import (
+    metric_info,
+    graph_info,
+    perfometer_info,
+)
 
 
 #####################################################################################################################
@@ -87,22 +87,22 @@ check_metrics['check_mk-cisco_asyncos_mem'] = {
 #
 ######################################################################################################################
 
-graph_info.append({
+graph_info['cisco_async_dns'] ={
     'title': _('AsyncOS DNS requests'),
     'metrics': [
         ('cisco_asyncos_dns_pendingdnsrequests', '-area'),
         ('cisco_asyncos_dns_outstandingdnsrequests', 'area'),
     ],
-})
+}
 
-graph_info.append({
+graph_info['cisco_async_messageage']={
     'title': _('AsyncOS oldest message age'),
     'metrics': [
         ('cisco_asyncos_messageage_oldestmessageage', 'area'),
     ],
-})
+}
 
-graph_info.append({
+graph_info['cisco_asyncos_queue']={
     'title': _('AsyncOS E-Mail work queue'),
     'metrics': [
         ('cisco_asyncos_queue_work_queue', 'area'),
@@ -111,9 +111,9 @@ graph_info.append({
         ('cisco_asyncos_queue_work_queue:crit', _('crit')),
         ('cisco_asyncos_queue_work_queue:warn', _('warn')),
     ],
-})
+}
 
-graph_info.append({
+graph_info['cisco_asyncos_mem']={
     'title': _('AsyncOS Memory used'),
     'metrics': [
         ('cisco_asyncos_mem_mem_used', 'area'),
@@ -122,7 +122,7 @@ graph_info.append({
         ('cisco_asyncos_mem_mem_used:crit', _('crit')),
         ('cisco_asyncos_mem_mem_used:warn', _('warn')),
     ],
-})
+}
 
 ######################################################################################################################
 #
-- 
GitLab