diff --git a/agent_based/cisco_flash.py b/agent_based/cisco_flash.py new file mode 100644 index 0000000000000000000000000000000000000000..9f6e0ebe2ad0a2de145fec326a6c54a052f7352f --- /dev/null +++ b/agent_based/cisco_flash.py @@ -0,0 +1,256 @@ +#!/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 : 2019-10-28 +# +# Monitor status of Cisco flash file systems +# +# 2019-10-28: initial release +# 2019-11-04: added wato for cisco_flash +# 2021-07-31: rewritten for CMK 2.0 +# +# snmpwalk sample +# +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.2.1.1 = INTEGER: 1 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.2.2.1 = INTEGER: 1 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.3.1.1 = INTEGER: 1 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.3.2.1 = INTEGER: 1 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.4.1.1 = Gauge32: 2908606464 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.4.2.1 = Gauge32: 4294967295 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.5.1.1 = Gauge32: 1756741632 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.5.2.1 = Gauge32: 4294967295 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.6.1.1 = Gauge32: 624 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.6.2.1 = Gauge32: 0 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.7.1.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.7.2.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.8.1.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.8.2.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.9.1.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.9.2.1 = INTEGER: 3 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.10.1.1 = STRING: "bootflash" +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.10.2.1 = STRING: "usb0" +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.11.1.1 = INTEGER: 2 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.11.2.1 = INTEGER: 2 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.12.1.1 = INTEGER: 63 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.12.2.1 = INTEGER: 63 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.13.1.1 = Counter64: 2908606464 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.13.2.1 = Counter64: 16424566784 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.14.1.1 = Counter64: 1756741632 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.14.2.1 = Counter64: 16424558592 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.15.1.1 = INTEGER: 10 +# .1.3.6.1.4.1.9.9.10.1.1.4.1.1.15.2.1 = INTEGER: 10 +# +# sample info +# +# [ +# [u'1.1', u'2908606464', u'1758527488', u'446', u'3', u'bootflash', u'2', u'2908606464', u'1758527488', u'10'], +# [u'2.1', u'4294967295', u'4294967295', u'0', u'3', u'usb0', u'2', u'16423845888', u'7506280448', u'10'] +# ] +# +# + +from dataclasses import dataclass +from typing import Optional, Dict +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, + SNMPTree, + contains, + check_levels, + OIDEnd, + Result, + render, + State, + Metric, + all_of, + exists, +) + + +@dataclass +class Partition: + size: Optional[int] = None + freespace: Optional[int] = None + usedspace: Optional[int] = None + index: Optional[int] = None + flashindex: Optional[int] = None + neederasure: Optional[bool] = None + lowspacenotifythreshold: Optional[int] = None + filecount: Optional[int] = None + + +_partneederasure = { + '1': True, + '2': False, +} + + +########################################################################### +# +# DATA Parser function +# +########################################################################### + + +def parse_cisco_flash(string_table: StringTable) -> Dict[str, Partition]: + partitions: Dict[str, Partition] = {} + + for cflPartition in string_table: + cflpartOID_END, cflpartSize, cflpartFreeSpace, cflpartFileCount, cflpartName, cflpartNeedErasure, \ + cflpartSizeExtended, cflpartFreeSpaceExtended, cflpartLowSpaceNotifThreshold = cflPartition + + cflDevIndex, cflPartIndex = cflpartOID_END.split('.') + + cflpartFreeSpace = int(cflpartFreeSpace) if cflpartFreeSpace.isdigit() else None + cflpartFreeSpaceExtended = int(cflpartFreeSpaceExtended) if cflpartFreeSpaceExtended.isdigit() else None + cflpartSize = int(cflpartSize) if cflpartSize.isdigit() else None + cflpartSizeExtended = int(cflpartSizeExtended) if cflpartSizeExtended.isdigit() else None + + freespace = cflpartFreeSpaceExtended if cflpartFreeSpaceExtended else cflpartFreeSpace + size = cflpartSizeExtended if cflpartSizeExtended else cflpartSize + + if size > 0: + partitions.update({ + cflpartName: Partition( + index=int(cflPartIndex) if cflPartIndex.isdigit() else None, + flashindex=int(cflDevIndex) if cflDevIndex.isdigit() else None, + size=size, + freespace=freespace, + usedspace=size - freespace, + filecount=int(cflpartFileCount) if cflpartFileCount.isdigit() else None, + neederasure=_partneederasure.get(cflpartNeedErasure, None), + lowspacenotifythreshold=int( + cflpartLowSpaceNotifThreshold) if cflpartLowSpaceNotifThreshold.isdigit() else None + )}) + + return partitions + + +########################################################################### +# +# INVENTORY function +# +########################################################################### + + +def discovery_cisco_flash(section: Dict[str, Partition]) -> DiscoveryResult: + for key in section: + yield Service(item=key) + + +########################################################################### +# +# CHECK function +# +########################################################################### + + +def check_cisco_flash(item, params, section: Dict[str, Partition]) -> CheckResult: + try: + partition = section[item] + except KeyError: + return + + if partition.lowspacenotifythreshold: + spacewarn = partition.size - ((partition.size / 100) * partition.lowspacenotifythreshold) + else: + spacewarn = partition.size + + yield from check_levels( + value=partition.usedspace, + label='Space used', + metric_name='cisco_flash_partusedspace', + render_func=render.disksize, + levels_upper=(spacewarn, partition.size - 10), + boundaries=(0, partition.size), + ) + + percentused = 100 * partition.usedspace / partition.size + + yield from check_levels( + value=percentused, + label='Percent', + levels_upper=params['levels_upper_percent'], + render_func=render.percent, + boundaries=(0, 100), + metric_name='cisco_flash_percent_used' + ) + + if partition.neederasure: + yield Result(state=State.WARN, notice='Partition needs erasure') + + yield Metric( + value=partition.filecount, + name='cisco_flash_partfilecount', + boundaries=(0, None) + ) + + for key, value in [ + ('Device index', partition.flashindex), + ('Partition index', partition.index), + ('Partition need erasure', partition.neederasure), + ('Partition low space notify threshold', partition.lowspacenotifythreshold), + ]: + if value: + yield Result(state=State.OK, notice=f'{key}: {value}') + + size = max(partition.size, 1) # for size = 0 --> div/0 + size = size / 1000 / 1000 + usedspace = partition.usedspace / 1000 / 1000 + freespace = partition.freespace / 1000 / 1000 + + yield Result(state=State.OK, notice=f'Used: {usedspace:.2f} of {size:.2f} MB, {freespace:.2f} MB free') + + if partition.filecount: + yield Result(state=State.OK, summary=f'File count: {partition.filecount}') + + +########################################################################### +# +# SNMP section +# +########################################################################### + + +register.snmp_section( + name='cisco_flash', + parse_function=parse_cisco_flash, + fetch=SNMPTree( + base='.1.3.6.1.4.1.9.9.10.1.1.4.1.1', # + oids=[ + OIDEnd(), + '4', # ciscoFlashPartitionSize + '5', # ciscoFlashPartitionFreeSpace + '6', # ciscoFlashPartitionFileCount + '10', # ciscoFlashPartitionName + '11', # ciscoFlashPartitionNeedErasure + '13', # ciscoFlashPartitionSizeExtended + '14', # ciscoFlashPartitionFreeSpaceExtended + '15', # ciscoFlashPartitionLowSpaceNotifThreshold + ] + ), + detect=all_of( + contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr + exists('.1.3.6.1.4.1.9.9.10.1.1.4.1.1.10.*'), # CISCO-FLASH-MIB::ciscoFlashDevicesSupported + )) + +register.check_plugin( + name='cisco_flash', + service_name='Flash partition %s', + discovery_function=discovery_cisco_flash, + check_function=check_cisco_flash, + check_default_parameters={ + 'levels_upper_percent': (85, 90), + }, + check_ruleset_name='cisco_flash', +) diff --git a/agent_based/inv_cisco_flash.py b/agent_based/inv_cisco_flash.py new file mode 100644 index 0000000000000000000000000000000000000000..2a23f76eb6f07d6654ec5d0b995f098ab5a41282 --- /dev/null +++ b/agent_based/inv_cisco_flash.py @@ -0,0 +1,352 @@ +#!/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 : 2019-10-22 +# +# invetory of cisco flash devices +# +# 2019-10-22 : initial release +# 2021-07-31: rewritten for CMK 2.0 +# +# + +from typing import List, Dict, Any +from dataclasses import dataclass +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 ( + OIDEnd, +) + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + register, + SNMPTree, + TableRow, + exists, + all_of, + contains, +) + + +@dataclass +class Section: + flash_devices: List[Dict[str, Any]] + flash_chips: List[Dict[str, Any]] + flash_partitions: List[Dict[str, Any]] + + +_DevProgrammingJumper = { + '1': 'installed', + '2': 'not installed', + '3': 'unknown', +} + +_DevRemovable = { + '1': True, + '2': False, +} + +_PartStatus = { + '1': 'Read Only', + '2': 'run from flash', + '3': 'Read Write', +} + +_PartChecksumAlgorithm = { + '1': 'simple Checksum', + '2': 'undefined', + '3': 'simple CRC', +} + +_PartUpgradeMethod = { + '1': 'unkown', + '2': 'rxboot Flash Load Helper', + '3': 'direct', +} + +_PartNeedErasure = { + '1': True, + '2': False, +} + + +def parse_inv_cisco_flash(string_table: List[StringTable]) -> Section: + cflDevices, cflChips, cflPartitions = string_table + + flash_devices = [] + for cflDevice in cflDevices: + clfOID_END, cflDevSize, cflDevMinPartitionSize, cflDevMaxPartitions, cflDevPartitions, cflDevChipCount, \ + cflDevName, cflDevDescr, cflDevController, cflDevProgrammingJumper, cflDevInitTime, cflDevRemovable, \ + cflDevPhyEntIndex, cflDevNameExtended, cflDevSizeExtended, cflDevMinPartitionSizeExtended = cflDevice + + cflDevSize = int(cflDevSize) if cflDevSize.isdigit() else None + cflDevSizeExtended = int(cflDevSizeExtended) if cflDevSizeExtended.isdigit() else None + cflDevMinPartitionSize = int(cflDevMinPartitionSize) if cflDevMinPartitionSize.isdigit() else None + cflDevMinPartitionSizeExtended = int( + cflDevMinPartitionSizeExtended) if cflDevMinPartitionSizeExtended.isdigit() else None + + # change sizes to MB + size = cflDevSizeExtended if cflDevSizeExtended else cflDevSize + size = size / 1024 / 1024 if size else None + + minpartitionsize = cflDevMinPartitionSizeExtended if cflDevMinPartitionSizeExtended else cflDevMinPartitionSize + minpartitionsize = minpartitionsize / 1024 / 1024 if minpartitionsize else None + + flash_device = {} + for key, value in [ + ('index', clfOID_END), + ('name', cflDevName), + ('description', cflDevDescr), + ('controller', cflDevController), + ('programmingjumper', _DevProgrammingJumper.get(cflDevProgrammingJumper)), + ('inittime', cflDevInitTime), + ('removable', _DevRemovable.get(cflDevRemovable)), + ('nameextended', cflDevNameExtended), + ('physentindex', cflDevPhyEntIndex), + ('size', size), + ('minpartitionsize', minpartitionsize), + ('maxprtitions', cflDevMaxPartitions), + ('partitions', cflDevPartitions), + ('chipcount', cflDevChipCount), + ]: + if value: + flash_device.update({key: value}) + flash_devices.append(flash_device) + + flash_chips = [] + + for cflChip in cflChips: + cflOID_END, cflChipCode, cflChipDescr, cflChipWriteRetries, cflChipEraseRetries, cflChipMaxWriteRetries, \ + cflChipMaxEraseRetries = cflChip + + cflDevIndex, cflChipIndex = cflOID_END.split('.') + + flash_chip = {} + for key, value in [ + ('index', cflChipIndex), + ('flashindex', cflDevIndex), + ('code', cflChipCode), + ('description', cflChipDescr), + ('writeretries', cflChipWriteRetries), + ('eraseretries', cflChipEraseRetries), + ('maxwriteretries', cflChipMaxWriteRetries), + ('maxeraseretries', cflChipMaxEraseRetries), + ]: + if value: + flash_chip.update({key: value}) + + flash_chips.append(flash_chip) + + flash_partitions = [] + for cflPartition in cflPartitions: + cflpartOID_END, cflpartStartChip, cflpartEndChip, cflpartSize, cflpartFreeSpace, cflpartFileCount, \ + cflpartChecksumAlgorithm, cflpartStatus, cflpartUpgradeMethod, cflpartName, cflpartNeedErasure, \ + cflpartFileNameLength, cflpartSizeExtended, cflpartFreeSpaceExtended, \ + cflpartLowSpaceNotifThreshold = cflPartition + + cflDevIndex, cflPartIndex = cflpartOID_END.split('.') + + cflpartSize = int(cflpartSize) if cflpartSize.isdigit() else None + cflpartFreeSpace = int(cflpartFreeSpace) if cflpartFreeSpace.isdigit() else None + cflpartSizeExtended = int(cflpartSizeExtended) if cflpartSizeExtended.isdigit() else None + cflpartFreeSpaceExtended = int(cflpartFreeSpaceExtended) if cflpartFreeSpaceExtended.isdigit() else None + + # change sizes to MB + size = cflpartSizeExtended if cflpartSizeExtended else cflpartSize + size = size / 1024 / 1024 if size else None + + freespace = cflpartFreeSpaceExtended if cflpartFreeSpaceExtended else cflpartFreeSpace + freespace = freespace / 1024 / 1024 if freespace else None + + flash_partition = {} + for key, value in [ + ('index', cflPartIndex), + ('flashindex', cflDevIndex), + ('startchip', cflpartStartChip), + ('endchip', cflpartEndChip), + ('filecount', cflpartFileCount), + ('crcsumalgo', _PartChecksumAlgorithm.get(cflpartChecksumAlgorithm)), + ('status', _PartStatus.get(cflpartStatus)), + ('upgrademethod', _PartUpgradeMethod.get(cflpartUpgradeMethod)), + ('name', cflpartName), + ('neederasure', _PartNeedErasure.get(cflpartNeedErasure)), + ('filenamelength', cflpartFileNameLength), + ('lowspacenotifythreshold', cflpartLowSpaceNotifThreshold), + ('size', size), + ('freespace', freespace), + ]: + if value: + flash_partition.update({key: value}) + + flash_partitions.append(flash_partition) + + return Section( + flash_devices=flash_devices, + flash_chips=flash_chips, + flash_partitions=flash_partitions + ) + + +def inventory_cisco_flash(params, section: Section) -> InventoryResult: + flash_devices = section.flash_devices + flash_chips = section.flash_chips + flash_partitions = section.flash_partitions + + # inventory of cisco flash devices + removecolumns = [] + disabled = False + # + if params: + disabled = params.get('cflDeviceDisable', disabled) + # get list of columns to remove from inventory + removecolumns = params.get('cflDeviceRemovecolumns', removecolumns) + + if not disabled: + + path = ['hardware', 'components', 'flash', 'devices'] + + for flash_device in flash_devices: + key_columns = {'index': flash_device['index'], } + flash_device.pop('index') + for key in flash_device.keys(): + if key in removecolumns: + flash_device.pop(key) + + yield TableRow( + path=path, + key_columns=key_columns, + inventory_columns=flash_device + ) + + # inventory of cisco flash chips + + removecolumns = [] + disabled = False + + if params: + disabled = params.get('cflChipDisable', disabled) + # get list of columns to remove from inventory + removecolumns = params.get('cflChipRemovecolumns', removecolumns) + + if not disabled: + path = ['hardware', 'components', 'flash', 'chips'] + + for flash_chip in flash_chips: + key_columns = {'index': flash_chip['index'], 'flashindex': flash_chip['flashindex']} + flash_chip.pop('index') + flash_chip.pop('flashindex') + for key in flash_chip.keys(): + if key in removecolumns: + flash_chip.pop(key) + + yield TableRow( + path=path, + key_columns=key_columns, + inventory_columns=flash_chip + ) + + # inventory of cisco flash partitions + + removecolumns = [] + disabled = False + + if params: + disabled = params.get('cflPartitionDisable', disabled) + # get list of columns to remove from inventory + removecolumns = params.get('cflPartitionRemovecolumns', removecolumns) + + if not disabled: + path = ['hardware', 'components', 'flash', 'partitions'] + + for flash_partition in flash_partitions: + key_columns = {'index': flash_partition['index'], 'flashindex': flash_partition['flashindex']} + flash_partition.pop('index') + flash_partition.pop('flashindex') + for key in flash_partition.keys(): + if key in removecolumns: + flash_partition.pop(key) + + yield TableRow( + path=path, + key_columns=key_columns, + inventory_columns=flash_partition + ) + + +register.snmp_section( + name='inv_cisco_flash', + parse_function=parse_inv_cisco_flash, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.9.9.10.1.1.2.1', # + oids=[ + OIDEnd(), # ifIndex + '2', # ciscoFlashDeviceSize + '3', # ciscoFlashDeviceMinPartitionSize + '4', # ciscoFlashDeviceMaxPartitions + '5', # ciscoFlashDevicePartitions + '6', # ciscoFlashDeviceChipCount + '7', # ciscoFlashDeviceName + '8', # ciscoFlashDeviceDescr + '9', # ciscoFlashDeviceController + '11', # ciscoFlashDeviceProgrammingJumper + '12', # ciscoFlashDeviceInitTime + '13', # ciscoFlashDeviceRemovable + '14', # ciscoFlashPhyEntIndex + '15', # ciscoFlashDeviceNameExtended + '16', # ciscoFlashDeviceSizeExtended + '17', # ciscoFlashDeviceMinPartitionSizeExtended + ] + ), + SNMPTree( + base='.1.3.6.1.4.1.9.9.10.1.1.3.1.1', # + oids=[ + OIDEnd(), # ifIndex + '2', # ciscoFlashChipCode + '3', # ciscoFlashChipDescr + '4', # ciscoFlashChipWriteRetries + '5', # ciscoFlashChipEraseRetries + '6', # ciscoFlashChipMaxWriteRetries + '7', # ciscoFlashChipMaxEraseRetries + ] + ), + SNMPTree( + base='.1.3.6.1.4.1.9.9.10.1.1.4.1.1', # + oids=[ + OIDEnd(), # ifIndex + '2', # ciscoFlashPartitionStartChip + '3', # ciscoFlashPartitionEndChip + '4', # ciscoFlashPartitionSize + '5', # ciscoFlashPartitionFreeSpace + '6', # ciscoFlashPartitionFileCount + '7', # ciscoFlashPartitionChecksumAlgorithm + '8', # ciscoFlashPartitionStatus + '9', # ciscoFlashPartitionUpgradeMethod + '10', # ciscoFlashPartitionName + '11', # ciscoFlashPartitionNeedErasure + '12', # ciscoFlashPartitionFileNameLength + '13', # ciscoFlashPartitionSizeExtended + '14', # ciscoFlashPartitionFreeSpaceExtended + '15', # ciscoFlashPartitionLowSpaceNotifThreshold + ] + ), + ], + detect=all_of( + contains('.1.3.6.1.2.1.1.1.0', 'cisco'), + exists('.1.3.6.1.4.1.9.9.10.1.1.1.*'), # CISCO-FLASH-MIB::ciscoFlashDevicesSupported + ) +) + +register.inventory_plugin( + name='inv_cisco_flash', + inventory_function=inventory_cisco_flash, + inventory_default_parameters={}, + inventory_ruleset_name='inv_cisco_flash', +) diff --git a/cisco_flash.mkp b/cisco_flash.mkp index 03216bd3d176ddaac49f9f0f7a47d8f3cefc7450..21fecb02981367afda43d078598a16f17dda2ee0 100644 Binary files a/cisco_flash.mkp and b/cisco_flash.mkp differ diff --git a/packages/cisco_flash b/packages/cisco_flash index 4389a03f8f3c23d2e1e3947a308b4e694ae96b06..6b51347dc80caa464ff1e8f7dfe027a0b9778d0d 100644 --- a/packages/cisco_flash +++ b/packages/cisco_flash @@ -1,15 +1,21 @@ -{'author': u'Th.L. (thl-cmk[at]outlook[dot]com)', - 'description': u'Cisco flash plugins:\n - snmp_cisco_flash: inventory plugin for Cisco flash memory\n - cisco_flash: check for Cisco partitions\n\n- 2020-05-13: added support for CMK1.6x\n', +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Cisco flash plugins:\n' + ' - inv_cisco_flash: inventory plugin for Cisco flash memory\n' + ' - cisco_flash: check for Cisco partitions\n' + '\n' + '- 2020-05-13: added support for CMK1.6x\n' + '- 2021-07-31: rewritten for CMK 2.0\n', 'download_url': 'https://thl-cmk.hopto.org', - 'files': {'checks': ['cisco_flash'], - 'inventory': ['snmp_cisco_flash'], + 'files': {'agent_based': ['cisco_flash.py', 'inv_cisco_flash.py'], + 'checkman': ['cisco_flash'], 'web': ['plugins/metrics/cisco_flash.py', 'plugins/views/inv_cisco_flash.py', 'plugins/wato/cisco_flash.py', 'plugins/wato/inv_cisco_flash.py']}, 'name': 'cisco_flash', - 'num_files': 6, - 'title': u'Cisco flash plugins', - 'version': '20200513v.0.2c', - 'version.min_required': '1.4.0p35', - 'version.packaged': '1.6.0p8'} \ No newline at end of file + 'num_files': 7, + 'title': 'Cisco flash plugins', + 'version': '20210731v.0.3', + 'version.min_required': '2.0.0', + 'version.packaged': '2021.07.14', + 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/metrics/cisco_flash.py b/web/plugins/metrics/cisco_flash.py index 28a3bbe2bdaf180fe310009a37f2d166d289dbb8..2c1805f8187b20fd2905b6aacc174a31db2745a3 100644 --- a/web/plugins/metrics/cisco_flash.py +++ b/web/plugins/metrics/cisco_flash.py @@ -1,56 +1,47 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # -# Cisco flash metrics plugin -# -# Author: Th.L. +# License: GNU General Public License v2 + +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org # Date : 2019-10-28 # +# Cisco flash metrics plugin # - -##################################################################################################################### -# -# define units for perfdata +# change log +# 2019-10-28: initial release +# 2021-07-31: rewritten for CMK 2.0 # -##################################################################################################################### +from cmk.gui.i18n import _ -##################################################################################################################### -# -# define metrics for perfdata -# -##################################################################################################################### +from cmk.gui.plugins.metrics import ( + metric_info, + graph_info, + perfometer_info + +) metric_info['cisco_flash_partusedspace'] = { 'title': _('Sapce used'), 'unit': 'bytes', + 'color': '36/a', +} + +metric_info['cisco_flash_percent_used'] = { + 'title': _('Percent used'), + 'unit': '%', 'color': '26/a', } + metric_info['cisco_flash_partfilecount'] = { 'title': _('# of files'), 'unit': 'count', 'color': '21/a', } - -###################################################################################################################### -# -# map perfdata to metric, not really necessary but makes sure to use the right metrics -# -###################################################################################################################### - -check_metrics['check_mk-cisco_flash'] = { - 'partusedspace': {'name': 'cisco_flash_partusedspace', 'scale': MB}, - 'partfilecount': {'name': 'cisco_flash_partfilecount', }, -} - -###################################################################################################################### -# -# how to graph perdata -# -###################################################################################################################### - -graph_info.append({ +graph_info['cisco_flash_space_used'] = { 'title': _('Space used'), 'metrics': [ ('cisco_flash_partusedspace', 'area'), @@ -60,32 +51,36 @@ graph_info.append({ ('cisco_flash_partusedspace:warn', _('warn')), ], "range": (0, "cisco_flash_partusedspace:max"), -}) +} + +graph_info['cisco_flash_percent_used'] = { + 'title': _('Percent used'), + 'metrics': [ + ('cisco_flash_percent_used', 'area'), + ], + 'scalars': [ + ('cisco_flash_percent_used:crit', _('crit')), + ('cisco_flash_percent_used:warn', _('warn')), + ], + "range": (0, 100), +} -graph_info.append({ +graph_info['cisco_flash_files_on_partition'] = { 'title': _('# of files on partition'), 'metrics': [ ('cisco_flash_partfilecount', 'area'), ], -}) - -###################################################################################################################### -# -# define perf-o-meter -# -###################################################################################################################### +} perfometer_info.append(('stacked', [ { - 'type': 'logarithmic', - 'metric': 'cisco_flash_partusedspace', - 'half_value': 2592000.0, - 'exponent': 2, + 'type': 'linear', + 'segments': ['cisco_flash_percent_used'], + 'total': 100, }, { 'type': 'linear', - 'segments': ['cisco_flash_partfilecount', - ], + 'segments': ['cisco_flash_partfilecount'], 'total': 100000, } ])) diff --git a/web/plugins/views/inv_cisco_flash.py b/web/plugins/views/inv_cisco_flash.py index 631c20bd6fe8acd445c07eb4e8f614c66864c8ed..2738b898f5e7baf6687f6d2d52057551039e58c6 100644 --- a/web/plugins/views/inv_cisco_flash.py +++ b/web/plugins/views/inv_cisco_flash.py @@ -1,53 +1,53 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- -try: - from cmk.gui.plugins.views.inventory import ( - declare_invtable_view, - render_inv_dicttable, - ) -except: - pass + +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.components.flash.devices:': {'title': _('Flash devices'), 'render': render_inv_dicttable, - 'keyorder': ['index', 'name', 'description', 'size', ], - 'view': 'invflashdevices_of_host', - }, + '.hardware.components.flash.devices:': { + 'title': _('Flash devices'), + 'keyorder': ['index', 'name', 'description', 'size', ], + 'view': 'invflashdevices_of_host', + }, - '.hardware.components.flash.devices:*.index' : {'title': _('Index'), }, - '.hardware.components.flash.devices:*.size' : {'title': _('Size (MB)'), }, - '.hardware.components.flash.devices:*.minpartitionsize' : {'title': _('min. partition size (MB)'), }, - '.hardware.components.flash.devices:*.maxprtitions' : {'title': _('max. partitions'), }, - '.hardware.components.flash.devices:*.chipcount' : {'title': _('Chip count'), }, - '.hardware.components.flash.devices:*.name' : {'title': _('Name'), }, - '.hardware.components.flash.devices:*.description' : {'title': _('Description'), }, - '.hardware.components.flash.devices:*.controller' : {'title': _('Controller'), }, + '.hardware.components.flash.devices:*.index': {'title': _('Index'), }, + '.hardware.components.flash.devices:*.size': {'title': _('Size (MB)'), }, + '.hardware.components.flash.devices:*.minpartitionsize': {'title': _('min. partition size (MB)'), }, + '.hardware.components.flash.devices:*.maxprtitions': {'title': _('max. partitions'), }, + '.hardware.components.flash.devices:*.chipcount': {'title': _('Chip count'), }, + '.hardware.components.flash.devices:*.name': {'title': _('Name'), }, + '.hardware.components.flash.devices:*.description': {'title': _('Description'), }, + '.hardware.components.flash.devices:*.controller': {'title': _('Controller'), }, '.hardware.components.flash.devices:*.programmingjumper': {'title': _('Programming jumper'), }, - '.hardware.components.flash.devices:*.inittime' : {'title': _('Init time'), }, - '.hardware.components.flash.devices:*.removable' : {'title': _('Removable'), }, - '.hardware.components.flash.devices:*.physentindex' : {'title': _('Phys entity index'), }, - '.hardware.components.flash.devices:*.nameextended' : {'title': _('Name extended'), }, - + '.hardware.components.flash.devices:*.inittime': {'title': _('Init time'), }, + '.hardware.components.flash.devices:*.removable': {'title': _('Removable'), }, + '.hardware.components.flash.devices:*.physentindex': {'title': _('Phys entity index'), }, + '.hardware.components.flash.devices:*.nameextended': {'title': _('Name extended'), }, - '.hardware.components.flash.chips:': {'title': _('Flash chips'), 'render' : render_inv_dicttable, - 'keyorder': ['flashindex', 'index', 'description', ], - 'view': 'invflashchips_of_host', - }, + '.hardware.components.flash.chips:': { + 'title': _('Flash chips'), + 'keyorder': ['flashindex', 'index', 'description', ], + 'view': 'invflashchips_of_host', + }, - '.hardware.components.flash.chips:*.index' : {'title': _('Index'), }, - '.hardware.components.flash.chips:*.flashindex' : {'title': _('Device index'), }, - '.hardware.components.flash.chips:*.code' : {'title': _('Code'), }, - '.hardware.components.flash.chips:*.description' : {'title': _('Description'), }, - '.hardware.components.flash.chips:*.writeretries' : {'title': _('Write retries'), }, - '.hardware.components.flash.chips:*.eraseretries' : {'title': _('Erase retries'), }, + '.hardware.components.flash.chips:*.index': {'title': _('Index'), }, + '.hardware.components.flash.chips:*.flashindex': {'title': _('Device index'), }, + '.hardware.components.flash.chips:*.code': {'title': _('Code'), }, + '.hardware.components.flash.chips:*.description': {'title': _('Description'), }, + '.hardware.components.flash.chips:*.writeretries': {'title': _('Write retries'), }, + '.hardware.components.flash.chips:*.eraseretries': {'title': _('Erase retries'), }, '.hardware.components.flash.chips:*.maxwriteretries': {'title': _('max. write retries'), }, '.hardware.components.flash.chips:*.maxeraseretries': {'title': _('max. erasure retries'), }, - '.hardware.components.flash.partitions:': {'title': _('Flash partitions'), 'render' : render_inv_dicttable, - 'keyorder': ['flashindex', 'index', 'name', 'size', 'freespace', 'filecount', ], - 'view': 'invflashpartitions_of_host', - }, + '.hardware.components.flash.partitions:': { + 'title': _('Flash partitions'), + 'keyorder': ['flashindex', 'index', 'name', 'size', 'freespace', 'filecount', ], + 'view': 'invflashpartitions_of_host', + }, '.hardware.components.flash.partitions:*.index': {'title': _('Index'), }, '.hardware.components.flash.partitions:*.flashindex': {'title': _('Device index'), }, @@ -67,4 +67,5 @@ inventory_displayhints.update({ declare_invtable_view('invflashdevices', '.hardware.components.flash.devices:', _('Flash devices'), _('Flash devices')) declare_invtable_view('invflashchips', '.hardware.components.flash.chips:', _('Flash chips'), _('Flash chips')) -declare_invtable_view('invflashpartitions', '.hardware.components.flash.partitions:', _('Flash partitions'), _('Flash partitions')) +declare_invtable_view('invflashpartitions', '.hardware.components.flash.partitions:', _('Flash partitions'), + _('Flash partitions')) diff --git a/web/plugins/wato/cisco_flash.py b/web/plugins/wato/cisco_flash.py index fa7636494d00211d3720842b01a96719eb239fd2..e64ce866a7c8d56f0a6e2b8eb7140768c5588c24 100644 --- a/web/plugins/wato/cisco_flash.py +++ b/web/plugins/wato/cisco_flash.py @@ -1,45 +1,56 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- - +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # -# Check_MK cisco_flash WATO plugin +# License: GNU General Public License v2 + +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2019-11-04 # -# Author: Th.L. -# Date: 2019-11-04 # +# Check_MK cisco_flash WATO plugin # +# 2019-11-04: initial release +# 2021-07-31: rewritten for CMK 2.0 # # +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + TextAscii, + Tuple, +) + +from cmk.gui.plugins.wato import ( + CheckParameterRulespecWithItem, + rulespec_registry, + RulespecGroupCheckParametersNetworking, +) -register_check_parameters( - subgroup_networking, - 'cisco_flash', - _('Cisco Flash'), - Dictionary( - help=_(''), + +def _parameter_valuespec_cisco_flash(): + return Dictionary( elements=[ - ('warn_level_percent', - Integer( - title=_('Warning if above percentage of used space'), - label=_('Warning if above percentage of used space'), - help=_('Warning if above percentage of used space'), - default_value=85, - allow_empty=False, - minvalue=1, - maxvalue=100 - )), - ('crit_level_percent', - Integer( - title=_('Critical if above percentage of used space'), - label=_('Critical if above percentage of used space'), - help=_('Critical if above percentage of used space'), - default_value=90, - allow_empty=False, - minvalue=1, - maxvalue=100 + ('levels_upper_percent', + Tuple( + title=_('Levels for usage in %'), + elements=[ + Integer(title=_('Warning at'), unit='%', default_value=85, minvalue=0, maxvalue=100), + Integer(title=_('Critical at'), unit='%', default_value=90, minvalue=0, maxvalue=100) + ], + )), ], - ), - TextAscii(title=_('Cisco flash')), - match_type='dict', -) + ) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='cisco_flash', + group=RulespecGroupCheckParametersNetworking, + item_spec=lambda: TextAscii(title=_('Partition specific configuration'), ), + match_type='dict', + parameter_valuespec=_parameter_valuespec_cisco_flash, + title=lambda: _('Cisco flash'), + )) diff --git a/web/plugins/wato/inv_cisco_flash.py b/web/plugins/wato/inv_cisco_flash.py index c4f9d83e8c8f572d84f1556a8712fd898e3dcc3c..fbb73ba2377c6f8784b6ed11f1751633de3b85d4 100644 --- a/web/plugins/wato/inv_cisco_flash.py +++ b/web/plugins/wato/inv_cisco_flash.py @@ -1,14 +1,38 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 -cflDeviceRemovecolumns = [ -# ('index', 'Index'), -# ('size', 'Size (MB)'), -# ('minpartitionsize', 'min. partition size (MB)'), +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2019-10-28 +# +# Cisco flash metrics plugin +# +# change log +# 2019-10-28: initial release +# 2021-07-31: rewritten for CMK 2.0 + + +from cmk.gui.i18n import _ +from cmk.gui.plugins.wato import ( + HostRulespec, + rulespec_registry, +) +from cmk.gui.valuespec import ( + Dictionary, + FixedValue, + ListChoice, +) + +from cmk.gui.plugins.wato.inventory import ( + RulespecGroupInventory, +) + +_inv_cisco_flash_cflDeviceRemovecolumns = [ + ('minpartitionsize', 'min. partition size (MB)'), ('maxprtitions', 'max. partitions'), ('chipcount', 'Chip count'), -# ('name', 'Name'), -# ('description', 'Description'), ('controller', 'Controller'), ('programmingjumper', 'Programming jumper'), ('inittime', 'Init time'), @@ -16,28 +40,20 @@ cflDeviceRemovecolumns = [ ('physentindex', 'Phys entity index'), ('nameextended', 'Name extended'), ] -cflPartitionRemovecolumns = [ -# ('index', 'Index'), -# ('flashindex', 'Device index'), + +_inv_cisco_flash_cflPartitionRemovecolumns = [ ('startchip', 'Start chip'), ('endchip', 'End chip'), -# ('size', 'Size (MB)'), -# ('freespace', 'Free space (MB)'), -# ('filecount', 'File count'), ('crcsumalgo', 'Checksumm algorithm'), ('status', 'Status'), ('upgrademethod', 'Upgrade method'), -# ('name', 'Name'), ('neederasure', 'Need erasure'), ('filenamelength', 'File name length'), ('lowspacenotifythreshold', 'Low space notify threshold (%)'), ] -cflChipRemovecolumns = [ -# ('index', 'Index'), -# ('flashindex', 'Device index'), +_inv_cisco_flash_cflChipRemovecolumns = [ ('code', 'Code'), -# ('description', 'Description'), ('writeretries', 'Write retries'), ('eraseretries', 'Erase retries'), ('maxwriteretries', 'max. write retries'), @@ -45,83 +61,70 @@ cflChipRemovecolumns = [ ] -register_rule('inventory', 'inv_parameters:inv_cisco_flash', - Dictionary( - title=_('Cisco flash inventory'), - elements=[ - ('cflDeviceDisable', - FixedValue( - True, - title=_('disable Flash device inventory'), - )), - ('cflPartitionDisable', - FixedValue( - True, - title=_('disable Flash partition inventory'), - )), - ('cflChipDisable', - FixedValue( - True, - title=_('disable Flash chips inventory'), - )), - ('cflDeviceRemovecolumns', - ListChoice( - title=_('list of columns to remove from flash devices'), - label=_('list of columns to remove from flash devices'), - help=_('information to remove from inventory'), - choices=cflDeviceRemovecolumns, - default_value=[ - # 'size', - # 'minpartitionsize', - # 'maxprtitions', - 'chipcount', - 'controller', - 'programmingjumper', - 'inittime', - # 'removable', - 'physentindex', - 'nameextended', - ], - )), - ('cflPartitionRemovecolumns', - ListChoice( - title=_('list of columns to remove from flash partitions'), - label=_('list of columns to remove from flash partitions'), - help=_('information to remove from inventory'), - choices=cflPartitionRemovecolumns, - default_value=[ - # 'index', - # 'flashindex', - 'startchip', - 'endchip', - #'size', - #'freespace', - # 'filecount', - # 'crcsumalgo', - # 'status', - # 'upgrademethod', - # 'name', - # 'neederasure', - # 'filenamelength', - # 'lowspacenotifythreshold', +def _valuespec_inv_cisco_flash(): + return Dictionary( + title=_('Cisco flash inventory'), + elements=[ + ('cflDeviceDisable', + FixedValue( + True, + title=_('disable Flash device inventory'), + )), + ('cflPartitionDisable', + FixedValue( + True, + title=_('disable Flash partition inventory'), + )), + ('cflChipDisable', + FixedValue( + True, + title=_('disable Flash chips inventory'), + )), + ('cflDeviceRemovecolumns', + ListChoice( + title=_('list of columns to remove from flash devices'), + help=_('information to remove from inventory'), + choices=_inv_cisco_flash_cflDeviceRemovecolumns, + default_value=[ + 'chipcount', + 'controller', + 'programmingjumper', + 'inittime', + 'physentindex', + 'nameextended', + ], + )), + ('cflPartitionRemovecolumns', + ListChoice( + title=_('list of columns to remove from flash partitions'), + help=_('information to remove from inventory'), + choices=_inv_cisco_flash_cflPartitionRemovecolumns, + default_value=[ + 'startchip', + 'endchip', + ], + )), + ('cflChipRemovecolumns', + ListChoice( + title=_('list of columns to remove from flash chips'), + help=_('information to remove from inventory'), + choices=_inv_cisco_flash_cflChipRemovecolumns, + default_value=[ + 'code', + 'writeretries', + 'eraseretries', + 'maxwriteretries', + 'maxeraseretries' + ], + )), + ], + ) + - ], - )), - ('cflChipRemovecolumns', - ListChoice( - title=_('list of columns to remove from flash chips'), - label=_('list of columns to remove from flash chips'), - help=_('information to remove from inventory'), - choices=cflChipRemovecolumns, - default_value=[ - 'code', - 'writeretries', - 'eraseretries', - 'maxwriteretries', - 'maxeraseretries' - ], - )), - ], - ), - match='dict', - ) +rulespec_registry.register( + HostRulespec( + group=RulespecGroupInventory, + match_type='dict', + name='inv_parameters:inv_cisco_flash', + valuespec=_valuespec_inv_cisco_flash, + ))