diff --git a/agent_based/inv_juniper_hw_modules.py b/agent_based/inv_juniper_hw_modules.py new file mode 100644 index 0000000000000000000000000000000000000000..8b6ad2e41ebfc3507be0edcb4541abe8d4d6b7d6 --- /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 Binary files /dev/null and b/inv_juniper_hw_modules.mkp differ diff --git a/packages/inv_juniper_hw_modules b/packages/inv_juniper_hw_modules new file mode 100644 index 0000000000000000000000000000000000000000..7f722a6b2b03bf6befb447b2232748ad5cfcd7e7 --- /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 0000000000000000000000000000000000000000..9a7daa9192432f2af06ab3252e85a38a74860247 --- /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 0000000000000000000000000000000000000000..1dd1865eeebf90c5e4ca0d990e36ef6a28c1eb78 --- /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, + ))