From 4f88b098cba2c5b41730ff5867f79fc6cc12fa52 Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Thu, 2 Jun 2022 21:46:08 +0200 Subject: [PATCH] update project --- agent_based/inv_juniper_hw_modules.py | 150 ++++++++++++++++++++ inv_juniper_hw_modules.mkp | Bin 0 -> 2921 bytes packages/inv_juniper_hw_modules | 13 ++ web/plugins/views/inv_juniper_hw_modules.py | 33 +++++ web/plugins/wato/inv_juniper_hw_modules.py | 63 ++++++++ 5 files changed, 259 insertions(+) create mode 100644 agent_based/inv_juniper_hw_modules.py create mode 100644 inv_juniper_hw_modules.mkp create mode 100644 packages/inv_juniper_hw_modules create mode 100644 web/plugins/views/inv_juniper_hw_modules.py create mode 100644 web/plugins/wato/inv_juniper_hw_modules.py diff --git a/agent_based/inv_juniper_hw_modules.py b/agent_based/inv_juniper_hw_modules.py new file mode 100644 index 0000000..8b6ad2e --- /dev/null +++ b/agent_based/inv_juniper_hw_modules.py @@ -0,0 +1,150 @@ +#!/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-06-02 +# +# inventory of juniper hardware modules +# + + +import time +from typing import List, NamedTuple, Optional, Dict + +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + StringTable, + InventoryResult, +) + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + register, + SNMPTree, + TableRow, + startswith, +) + + +def parse_inv_juniper_hw_modules(string_table: List[StringTable]) -> List[Dict]: + modules = [] + + jnx_contents_entry, jnx_box_anatomy, sys_uptime = string_table + sys_uptime = int(sys_uptime[0][0]) / 100 # change to seconds + # first entry in jnx_contents_entry is the chassis without data (?) + if jnx_contents_entry[0][5:9] == ['', '', '', '0']: + box_class, box_descr, box_serial_no, box_revision, box_installed = jnx_box_anatomy[0] + jnx_contents_entry[0][5] = box_descr + jnx_contents_entry[0][6] = box_serial_no + jnx_contents_entry[0][7] = box_revision + jnx_contents_entry[0][8] = box_installed + + for container_index, l1_index, l2_index, l3_index, type_oid, descr, serial_no, revision, installed, part_no, \ + chassis_id, chassis_descr, chassis_clei_code, model in jnx_contents_entry: + + index = f'{container_index}.{l1_index}.{l2_index}.{l3_index}' + installed = time.ctime(time.time() - sys_uptime + (int(installed))) if installed != '0' else None + + module = {} + for key, value in [ + ('index', index), + ('description', descr), + ('type', type_oid), + ('serial_number', serial_no), + ('revision', revision), + # ('installed_at', installed), + ('part_no', part_no), + ('chassis_id', chassis_id), + ('chassis_descr', chassis_descr), + ('chassis_clei_code', chassis_clei_code), + ('model', model), + ]: + if value: + module.update({key: value}) + + modules.append(module) + + return modules + + +def inventory_hw_modules(params, section: List[Dict]) -> InventoryResult: + removecolumns = params.get('removecolumns', []) + allparts = params.get('allparts', False) + + path = ['hardware', 'juniper-hw-modules'] + + for module in section: + # do not add parts without serial number + if allparts is False and module.get('serial_number', None) is None: + continue + + key_columns = {'index': module['index']} + for key in key_columns.keys(): + module.pop(key) + + for entry in removecolumns: + try: + module.pop(entry) + except KeyError: + pass + + yield TableRow( + path=path, + key_columns=key_columns, + inventory_columns=module + ) + + +register.snmp_section( + name='inv_juniper_hw_modules', + parse_function=parse_inv_juniper_hw_modules, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.2636.3.1.8.1', # JUNIPER-MIB::jnxContentsEntry + oids=[ + '1', # jnxContentsContainerIndex + '2', # jnxContentsL1Index + '3', # jnxContentsL2Index + '4', # jnxContentsL3Index + '5', # jnxContentsType + '6', # jnxContentsDescr + '7', # jnxContentsSerialNo + '8', # jnxContentsRevision + '9', # jnxContentsInstalled + '10', # jnxContentsPartNo + '11', # jnxContentsChassisId + '12', # jnxContentsChassisDescr + '13', # jnxContentsChassisCleiCode + '14', # jnxContentsModel + ] + ), + SNMPTree( + base='.1.3.6.1.4.1.2636.3.1', # UNIPER-MIB::jnxBoxAnatomy + oids=[ + '1', # jnxBoxClass + '2', # jnxBoxDescr + '3', # jnxBoxSerialNo + '4', # jnxBoxRevision + '5', # jnxBoxInstalled + ] + ), + SNMPTree( + base='.1.3.6.1.2.1.1', # SNMPv2-MIB::system + oids=[ + '3', # sysUpTime + ] + ) + ], + detect=startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2636.1.1.1'), +) + +register.inventory_plugin( + name='inv_juniper_hw_modules', + inventory_function=inventory_hw_modules, + inventory_default_parameters={ + 'removecolumns': [], + 'allparts': False, + }, + inventory_ruleset_name='inv_juniper_hw_modules', +) diff --git a/inv_juniper_hw_modules.mkp b/inv_juniper_hw_modules.mkp new file mode 100644 index 0000000000000000000000000000000000000000..395b174af71436112eb6d6ff4ba5a7a6eb64816d GIT binary patch literal 2921 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 IfZw?BKR_<95&!@I literal 0 HcmV?d00001 diff --git a/packages/inv_juniper_hw_modules b/packages/inv_juniper_hw_modules new file mode 100644 index 0000000..7f722a6 --- /dev/null +++ b/packages/inv_juniper_hw_modules @@ -0,0 +1,13 @@ +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Inventory of Juniper networks hardware modules\n', + 'download_url': 'https://thl-cmk.hopto.org', + 'files': {'agent_based': ['inv_juniper_hw_modules.py'], + 'web': ['plugins/views/inv_juniper_hw_modules.py', + 'plugins/wato/inv_juniper_hw_modules.py']}, + 'name': 'inv_juniper_hw_modules', + 'num_files': 3, + 'title': 'Juniper networks hardware inventory', + 'version': '20220602.v.0.01', + 'version.min_required': '2.0.0', + 'version.packaged': '2021.09.20', + 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/views/inv_juniper_hw_modules.py b/web/plugins/views/inv_juniper_hw_modules.py new file mode 100644 index 0000000..9a7daa9 --- /dev/null +++ b/web/plugins/views/inv_juniper_hw_modules.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# import cmk.gui.utils +from cmk.gui.plugins.views import ( + inventory_displayhints, ) +from cmk.gui.i18n import _ +from cmk.gui.plugins.views.inventory import declare_invtable_view + +inventory_displayhints.update({ + '.hardware.juniper-hw-modules:': {'title': _('Modules'), + 'keyorder': ['index', 'description', 'serial_number', 'revision', 'part_no', ], + 'view': 'invmodules_of_host', + }, + '.hardware.juniper-hw-modules:*.index': {'title': _('Index'), }, + '.hardware.juniper-hw-modules:*.serial_number': {'title': _('Serial number')}, + '.hardware.juniper-hw-modules:*.description': {'title': _('Description')}, + '.hardware.juniper-hw-modules:*.revision': {'title': _('Revision'), }, + '.hardware.juniper-hw-modules:*.installed_at': {'title': _('Installed at'), }, + '.hardware.juniper-hw-modules:*.part_no': {'title': _('Part No'), }, + '.hardware.juniper-hw-modules:*.chassis_id': {'title': _('Chassis ID'), }, + '.hardware.juniper-hw-modules:*.chassis_descr': {'title': _('Chassis description')}, + '.hardware.juniper-hw-modules:*.chassis_clei_code': {'title': _('Chassis CLEI code'), }, + '.hardware.juniper-hw-modules:*.model': {'title': _('Model'), }, + '.hardware.juniper-hw-modules:*.type': {'title': _('Type (OID)'), }, +}) + +declare_invtable_view( + 'invmodules', + '.hardware.juniper-hw-modules:', + _('Juniper Hardware Modules'), + _('Juniper Hardware Modules') +) diff --git a/web/plugins/wato/inv_juniper_hw_modules.py b/web/plugins/wato/inv_juniper_hw_modules.py new file mode 100644 index 0000000..1dd1865 --- /dev/null +++ b/web/plugins/wato/inv_juniper_hw_modules.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# + + +from cmk.gui.i18n import _ +from cmk.gui.plugins.wato import ( + HostRulespec, + rulespec_registry, + RulespecGroup, +) +from cmk.gui.valuespec import ( + Dictionary, + FixedValue, + TextAscii, + ListChoice, +) + +from cmk.gui.plugins.wato.inventory import ( + RulespecGroupInventory, +) + +_removecolumns = [ + ('chassis_clei_code', 'Chassis CLEI code'), + ('chassis_descr', 'Chassis description'), + ('chassis_id', 'Chassis ID'), + # ('installed_at', 'Installed at'), + ('model', 'Model'), + ('type', 'Type (OID)'), +] + + +def _valuespec_inv_juniper_hw_modules(): + return Dictionary( + title=_('Juniper hardware inventory'), + elements=[ + ('allparts', + FixedValue( + True, + title=_('Inventory parts without serial number'), + totext=_(''), + default_value=False, + )), + ('removecolumns', + ListChoice( + title=_('List of columns to remove'), + help=_('information to remove from inventory'), + choices=_removecolumns, + default_value=[ + ], + )), + ], + ) + + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupInventory, + match_type="dict", + name="inv_parameters:inv_juniper_hw_modules", + valuespec=_valuespec_inv_juniper_hw_modules, + )) -- GitLab