From c6b42b422a5406e107616c159f77617fcadb9347 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Fri, 31 Mar 2023 09:50:15 +0200
Subject: [PATCH] update project

---
 agent_based/dell_powerconnect_psu.py | 191 +++++++++++++++++++++++++++
 checks/dell_powerconnect_psu         |   1 +
 dell_powerconnect_psu.mkp            | Bin 0 -> 3026 bytes
 gui/metrics/psu_wattage.py           |  22 +++
 packages/dell_powerconnect_psu       |  16 +++
 5 files changed, 230 insertions(+)
 create mode 100644 agent_based/dell_powerconnect_psu.py
 create mode 100644 checks/dell_powerconnect_psu
 create mode 100644 dell_powerconnect_psu.mkp
 create mode 100644 gui/metrics/psu_wattage.py
 create mode 100644 packages/dell_powerconnect_psu

diff --git a/agent_based/dell_powerconnect_psu.py b/agent_based/dell_powerconnect_psu.py
new file mode 100644
index 0000000..9e3a714
--- /dev/null
+++ b/agent_based/dell_powerconnect_psu.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
+# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
+# conditions defined in the file COPYING, which is part of this source code package.
+
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2021-08-20
+
+# 2023-03-30: Rewritten for cmk 2.x
+#             added current power consumption metric
+
+# Tested with Dell PowerConnect 5448 and 5424 models.
+# Relevant SNMP OIDs:
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.1.67109185 = INTEGER: 67109185
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.1.67109186 = INTEGER: 67109186
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.2.67109185 = STRING: "ps1_unit1"
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.2.67109186 = STRING: "ps2_unit1"
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.3.67109185 = INTEGER: 1
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.3.67109186 = INTEGER: 5
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.4.67109185 = INTEGER: 5
+# .1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1.4.67109186 = INTEGER: 4
+
+# Status codes:
+# 1 => normal,
+# 2 => warning,
+# 3 => critical,
+# 4 => shutdown,
+# 5 => notPresent,
+# 6 => notFunctioning
+
+# Supply Source Codes:
+# 1 => unknown
+# 2 => ac
+# 3 => dc
+# 4 => externalPowerSupply
+# 5 => internalRedundant
+
+# GENERAL MAPS:
+
+from typing import Dict, Optional, List, Tuple
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    Service,
+    Result,
+    check_levels,
+    State,
+    SNMPTree,
+    contains,
+    any_of,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    DiscoveryResult,
+    CheckResult,
+    StringTable,
+)
+
+dell_powerconnect_psu_status_map = {
+    "1": "normal",
+    "2": "warning",
+    "3": "critical",
+    "4": "shutdown",
+    "5": "notPresent",
+    "6": "notFunctioning",
+}
+
+dell_powerconnect_psu_supply_map = {
+    "1": "Unknown",
+    "2": "Alternating Current",
+    "3": "Direct Current",
+    "4": "External Power Supply",
+    "5": "Internal Redundant",
+}
+
+dell_powerconnect_psu_status2nagios_map = {
+    "normal": 0,
+    "warning": 1,
+    "critical": 2,
+    "shutdown": 3,
+    "notPresent": 1,
+    "notFunctioning": 2,
+}
+
+
+# sample string_table
+# [
+#  [
+#   ['Dell EMC Networking S4048 switch/router']
+#  ],
+#  [
+#   ['11', 'S4048-ON PSU 1', '1', '2', '49'],
+#   ['12', 'S4048-ON PSU 2', '1', '2', '41'],
+#   ['21', 'S4048-ON PSU 1', '1', '2', '50'],
+#   ['22', 'S4048-ON PSU 2', '1', '2', '39']
+#  ]
+# ]
+#
+
+
+def parse_dell_powerconnect_psu(string_table: List[StringTable]) -> Optional[Dict[str, Tuple[str, str, int]]]:
+    try:
+        hw_ident = string_table[0][0][0]
+    except IndexError:
+        return
+
+    section = {}
+    for device_id, name, state, supply, current_power in string_table[1]:
+        # M6220 are blade switches which report valid values only for the "Main"
+        # sensor. The other one is reported as notFunctioning, but this is wrong.
+        # Simply ignore the "System" sensor for those devices.
+        if dell_powerconnect_psu_status_map[state] != "notPresent" and (
+                "M6220" not in hw_ident or name != "System"
+        ):
+            section[f'{device_id} {name}'] = (
+                state,
+                dell_powerconnect_psu_supply_map[supply],
+                int(current_power) if current_power.isdigit() else 0,
+            )
+
+    return section
+
+
+def discovery_dell_powerconnect_psu(section: Dict[str, Tuple[str, str, int]]) -> DiscoveryResult:
+    for item in section.keys():
+        yield Service(item=item)
+
+
+def check_dell_powerconnect_psu(item, params, section: Dict[str, Tuple[str, str, int]]) -> CheckResult:
+    try:
+        state, supply, current_power = section[item]
+    except KeyError:
+        yield Result(state=State.UNKNOW, summary='ITEM not found in SNMP data')
+        return
+
+    dell_powerconnect_status = dell_powerconnect_psu_status_map[state]
+    status = dell_powerconnect_psu_status2nagios_map[dell_powerconnect_status]
+
+    yield Result(state=State(status), summary=f'State: {dell_powerconnect_status}')
+
+    if current_power > 0:  # 0 - indicates that Current power is not available for related supply
+        yield from check_levels(
+            value=current_power,
+            levels_upper=params['levels_abs_upper'],
+            levels_lower=params['levels_abs_lower'],
+            label='Power consumption',
+            render_func=lambda v: f'{v} W',
+            metric_name='power_usage',
+        )
+
+    yield Result(state=State.OK, summary=f'Source: {supply}')
+
+
+register.snmp_section(
+    name='dell_powerconnect_psu',
+    parse_function=parse_dell_powerconnect_psu,
+    fetch=[
+        SNMPTree(
+            base='.1.3.6.1.4.1.674.10895.3000.1.2.100.1',  #
+            oids=[
+                '0',  # productIdentificationDisplayName
+            ]),
+        SNMPTree(
+            base='.1.3.6.1.4.1.674.10895.3000.1.2.110.7.2.1',  #
+            oids=[
+                '1',  # envMonSupplyStatusIndex
+                '2',  # envMonSupplyStatusDescr
+                '3',  # envMonSupplyState
+                '4',  # envMonSupplySource
+                '5',  # envMonSupplyCurrentPower (assume W)
+            ]),
+    ],
+    detect=any_of(
+        contains('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.674.10895'),
+        contains('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.6027.1.3.22'),
+    )
+)
+
+register.check_plugin(
+    name='dell_powerconnect_psu',
+    service_name='Sensor %s',
+    discovery_function=discovery_dell_powerconnect_psu,
+    check_function=check_dell_powerconnect_psu,
+    check_default_parameters={
+        'levels_abs_upper': None,
+        'levels_abs_lower': None
+    },
+    check_ruleset_name='psu_wattage',
+)
diff --git a/checks/dell_powerconnect_psu b/checks/dell_powerconnect_psu
new file mode 100644
index 0000000..6dd7e54
--- /dev/null
+++ b/checks/dell_powerconnect_psu
@@ -0,0 +1 @@
+# dummy for dell_powerconnect_psu
\ No newline at end of file
diff --git a/dell_powerconnect_psu.mkp b/dell_powerconnect_psu.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..8a58a3bd0030a796501a823d76529ea34d93cba1
GIT binary patch
literal 3026
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
Cd*6)!

literal 0
HcmV?d00001

diff --git a/gui/metrics/psu_wattage.py b/gui/metrics/psu_wattage.py
new file mode 100644
index 0000000..eeda089
--- /dev/null
+++ b/gui/metrics/psu_wattage.py
@@ -0,0 +1,22 @@
+#!/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  : 2023-03-30
+#
+
+from cmk.gui.plugins.metrics.utils import (
+    perfometer_info,
+)
+
+perfometer_info.append(
+    {
+        'type': 'logarithmic',
+        'metric': 'power_usage',
+        'half_value': 200.0,
+        'exponent': 2,
+    }
+)
diff --git a/packages/dell_powerconnect_psu b/packages/dell_powerconnect_psu
new file mode 100644
index 0000000..d670335
--- /dev/null
+++ b/packages/dell_powerconnect_psu
@@ -0,0 +1,16 @@
+{'author': 'thl-cmk[at]outlook[dot]com',
+ 'description': 'Rewrite of CMKs dell_powerconnect_psu check for CMK2.1\n'
+                '\n'
+                '- fixes missing PSUs if there are different PSUs with the '
+                'same name\n'
+                '- adds current power usage as perfdata \n',
+ 'download_url': 'https://thl-cmk.hopto.org',
+ 'files': {'agent_based': ['dell_powerconnect_psu.py'],
+           'checks': ['dell_powerconnect_psu'],
+           'gui': ['metrics/psu_wattage.py']},
+ 'name': 'dell_powerconnect_psu',
+ 'title': 'Dell Power connect PSU',
+ 'version': '20230330.v0.0.2',
+ 'version.min_required': '2.1.0',
+ 'version.packaged': '2.1.0p21',
+ 'version.usable_until': None}
\ No newline at end of file
-- 
GitLab