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,
+    ))