From 5a21b8bc5a8ec6defa1662e39dcfffda4d4ee00a Mon Sep 17 00:00:00 2001
From: OMD site cmk16x <thl-cmk@outlook.com>
Date: Mon, 6 Mar 2023 15:05:55 +0100
Subject: [PATCH] update project

---
 agent_based/cisco_asyncos_bandwidth.py  |  27 +++++++------
 agent_based/cisco_asyncos_cache.py      |  27 +++++++------
 agent_based/cisco_asyncos_conn.py       |  23 ++++++-----
 agent_based/cisco_asyncos_dns.py        |  21 +++++-----
 agent_based/cisco_asyncos_messageage.py |  19 ++++-----
 agent_based/cisco_asyncos_queue.py      |  23 ++++++-----
 agent_based/cisco_asyncos_resources.py  |  19 ++++-----
 agent_based/cisco_asyncos_temp.py       |  12 +++---
 cisco_asyncos.mkp                       | Bin 11454 -> 10670 bytes
 gui/wato/cisco_asyncos_feature_keys.py  |  50 +++++++++++++++++++++++
 gui/wato/cisco_asyncos_license.py       |  51 ++++++++++++++++++++++++
 gui/wato/cisco_asyncos_queue.py         |  41 +++++++++++++++++++
 gui/wato/cisco_asyncos_updates.py       |  49 +++++++++++++++++++++++
 packages/cisco_asyncos                  |  15 ++++---
 14 files changed, 288 insertions(+), 89 deletions(-)
 create mode 100644 gui/wato/cisco_asyncos_feature_keys.py
 create mode 100644 gui/wato/cisco_asyncos_license.py
 create mode 100644 gui/wato/cisco_asyncos_queue.py
 create mode 100644 gui/wato/cisco_asyncos_updates.py

diff --git a/agent_based/cisco_asyncos_bandwidth.py b/agent_based/cisco_asyncos_bandwidth.py
index 0e4eccd..4d73994 100644
--- a/agent_based/cisco_asyncos_bandwidth.py
+++ b/agent_based/cisco_asyncos_bandwidth.py
@@ -9,8 +9,10 @@
 #
 # only use full for Cisco WSA appliances
 #
+# 2023-03-06: fixed: IndexError in parse function
+#
 
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -36,13 +38,16 @@ class CiscoAsyncosBandwidth(NamedTuple):
     bandwidth_day: int
 
 
-# [[['0', '0', '247']]]
-def parse_cisco_asyncos_bandwidth(string_table: List[StringTable]) -> CiscoAsyncosBandwidth:
-    return CiscoAsyncosBandwidth(
-        bandwidth_now=int(string_table[0][0][0]),
-        bandwidth_hour=int(string_table[0][0][1]),
-        bandwidth_day = int(string_table[0][0][2]),
-    )
+# [['0', '0', '247']]
+def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> Optional[CiscoAsyncosBandwidth]:
+    try:
+        return CiscoAsyncosBandwidth(
+            bandwidth_now=int(string_table[0][0]),
+            bandwidth_hour=int(string_table[0][1]),
+            bandwidth_day = int(string_table[0][2]),
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_bandwidth(section: CiscoAsyncosBandwidth) -> DiscoveryResult:
@@ -82,16 +87,14 @@ def check_cisco_asyncos_bandwidth(params, section: CiscoAsyncosBandwidth) -> Che
 register.snmp_section(
     name='cisco_asyncos_bandwidth',
     parse_function=parse_cisco_asyncos_bandwidth,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.2.3.7.4',  # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentBandWTotPerf
             oids=[
                 '1',  # cacheBwidthTotalNow
                 '3',  # cacheBwidthTotal1hrMean
                 '5',  # cacheBwidthTotal1dayMean
             ]
-        ),
-    ],
+    ),
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_cache.py b/agent_based/cisco_asyncos_cache.py
index dda48c6..bf53571 100644
--- a/agent_based/cisco_asyncos_cache.py
+++ b/agent_based/cisco_asyncos_cache.py
@@ -10,7 +10,7 @@
 # only use full for Cisco WSA appliances
 #
 
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -38,15 +38,18 @@ class CiscoAsyncosCache(NamedTuple):
     cache_total_resptime: int
 
 
-# [[['0', '0', '0', '0', '0']]]
-def parse_cisco_asyncos_cache(string_table: List[StringTable]) -> CiscoAsyncosCache:
-    return CiscoAsyncosCache(
-        cache_hits_now=int(string_table[0][0][0]),
-        cache_misses_now=int(string_table[0][0][1]),
-        cache_hit_resptime_now=int(string_table[0][0][2]),
-        cache_miss_resptime_now=int(string_table[0][0][3]),
-        cache_total_resptime=int(string_table[0][0][4]),
-    )
+# [['0', '0', '0', '0', '0']]
+def parse_cisco_asyncos_cache(string_table: StringTable) -> Optional[CiscoAsyncosCache]:
+    try:
+        return CiscoAsyncosCache(
+           cache_hits_now=int(string_table[0][0]),
+           cache_misses_now=int(string_table[0][1]),
+           cache_hit_resptime_now=int(string_table[0][2]),
+           cache_miss_resptime_now=int(string_table[0][3]),
+           cache_total_resptime=int(string_table[0][4]),
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_cache(section: CiscoAsyncosCache) -> DiscoveryResult:
@@ -68,8 +71,7 @@ def check_cisco_asyncos_cache(params, section: CiscoAsyncosCache) -> CheckResult
 register.snmp_section(
     name='cisco_asyncos_cache',
     parse_function=parse_cisco_asyncos_cache,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.2.3.7',  # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentPerf
             oids=[
                 '5.1',  # cacheHitsNow
@@ -79,7 +81,6 @@ register.snmp_section(
                 '9.1',  # cacheTotalRespTimeNow
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_conn.py b/agent_based/cisco_asyncos_conn.py
index c5da832..f5436cd 100644
--- a/agent_based/cisco_asyncos_conn.py
+++ b/agent_based/cisco_asyncos_conn.py
@@ -9,7 +9,7 @@
 #
 # only use full for Cisco WSA appliances
 #
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -35,13 +35,16 @@ class CiscoAsyncosConn(NamedTuple):
     cacheClientMaxConns: int
 
 
-# [[['0', '5', '66277']]]
-def parse_cisco_asyncos_conn(string_table: List[StringTable]) -> CiscoAsyncosConn:
-    return CiscoAsyncosConn(
-        cacheClientIdleConns=int(string_table[0][0][0]),
-        cacheClientTotalConns=int(string_table[0][0][1]),
-        cacheClientMaxConns=int(string_table[0][0][2]),
-    )
+# [['0', '5', '66277']]
+def parse_cisco_asyncos_conn(string_table: StringTable) -> Optional[CiscoAsyncosConn]:
+    try:
+        return CiscoAsyncosConn(
+            cacheClientIdleConns=int(string_table[0][0]),
+            cacheClientTotalConns=int(string_table[0][1]),
+            cacheClientMaxConns=int(string_table[0][2]),
+        )
+    except IndexError:
+        return  
 
 
 def discovery_cisco_asyncos_conn(section: CiscoAsyncosConn) -> DiscoveryResult:
@@ -61,8 +64,7 @@ def check_cisco_asyncos_conn(params, section: CiscoAsyncosConn) -> CheckResult:
 register.snmp_section(
     name='cisco_asyncos_conn',
     parse_function=parse_cisco_asyncos_conn,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.2.3.2',  # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyClientSidePerf
             oids=[
                 '7',  # cacheClientIdleConns
@@ -70,7 +72,6 @@ register.snmp_section(
                 '9',  # cacheClientMaxConns
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_dns.py b/agent_based/cisco_asyncos_dns.py
index 664d265..534f79a 100644
--- a/agent_based/cisco_asyncos_dns.py
+++ b/agent_based/cisco_asyncos_dns.py
@@ -19,7 +19,7 @@
 # ASYNCOS-MAIL-MIB::pendingDNSRequests.0 = Gauge32: 0
 #
 #
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -44,12 +44,15 @@ class CiscoAsyncosDns(NamedTuple):
     pendingDNSRequests: int
 
 
-# [[['0', '0']]]
-def parse_cisco_asyncos_dns(string_table: List[StringTable]) -> CiscoAsyncosDns:
-    return CiscoAsyncosDns(
-        outstandingDNSRequests=int(string_table[0][0][0]),
-        pendingDNSRequests=int(string_table[0][0][1]),
-    )
+# [['0', '0']]
+def parse_cisco_asyncos_dns(string_table: StringTable) -> Optional[CiscoAsyncosDns]:
+    try:
+        return CiscoAsyncosDns(
+            outstandingDNSRequests=int(string_table[0][0]),
+            pendingDNSRequests=int(string_table[0][1]),
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_dns(section: CiscoAsyncosDns) -> DiscoveryResult:
@@ -68,15 +71,13 @@ def check_cisco_asyncos_dns(params, section: CiscoAsyncosDns) -> CheckResult:
 register.snmp_section(
     name='cisco_asyncos_dns',
     parse_function=parse_cisco_asyncos_dns,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.1.1',  # ASYNCOS-MAIL-MIB
             oids=[
                 '15',  # outstandingDNSRequests
                 '16',  # pendingDNSRequests
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_messageage.py b/agent_based/cisco_asyncos_messageage.py
index d078942..91383d7 100644
--- a/agent_based/cisco_asyncos_messageage.py
+++ b/agent_based/cisco_asyncos_messageage.py
@@ -17,7 +17,7 @@
 # ASYNCOS-MAIL-MIB::oldestMessageAge.0 = Gauge32: 259706
 #
 
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -41,11 +41,14 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
 class CiscoAsyncosMessageage(NamedTuple):
     messageage: int
 
-# [[['259297']]]
-def parse_cisco_asyncos_messageage(string_table: List[StringTable]) -> CiscoAsyncosMessageage:
-    return CiscoAsyncosMessageage(
-        messageage=int(string_table[0][0][0]),
-    )
+# [['259297']]
+def parse_cisco_asyncos_messageage(string_table: StringTable) -> Optional[CiscoAsyncosMessageage]:
+    try:
+        return CiscoAsyncosMessageage(
+            messageage=int(string_table[0][0]),
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_messageage(section: CiscoAsyncosMessageage) -> DiscoveryResult:
@@ -65,14 +68,12 @@ def check_cisco_asyncos_messageage(params, section: CiscoAsyncosMessageage) -> C
 register.snmp_section(
     name='cisco_asyncos_messageage',
     parse_function=parse_cisco_asyncos_messageage,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.1.1',  # ASYNCOS-MAIL-MIB
             oids=[
                 '14',  # oldestMessageAge
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_queue.py b/agent_based/cisco_asyncos_queue.py
index 32a67a2..b4a7988 100644
--- a/agent_based/cisco_asyncos_queue.py
+++ b/agent_based/cisco_asyncos_queue.py
@@ -12,7 +12,7 @@
 # 2021-03-24: rewrite for CMK 2.0
 #
 
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -56,13 +56,16 @@ def get_cmk_state(st: str) -> State:
     return states.get(st, State.CRIT)
 
 
-# [[['1', '1']]]
-def parse_cisco_asyncos_messageage(string_table: List[StringTable]) -> CiscoAsyncosQueue:
-    return CiscoAsyncosQueue(
-        state=get_cmk_state(string_table[0][0][0]),
-        status_readable=get_status_readable(string_table[0][0][0]),
-        workQueueMessages=int(string_table[0][0][1])
-    )
+# [['1', '1']]
+def parse_cisco_asyncos_messageage(string_table: StringTable) -> Optional[CiscoAsyncosQueue]:
+    try:
+        return CiscoAsyncosQueue(
+            state=get_cmk_state(string_table[0][0]),
+            status_readable=get_status_readable(string_table[0][0]),
+            workQueueMessages=int(string_table[0][1])
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_queue(section: CiscoAsyncosQueue) -> DiscoveryResult:
@@ -82,15 +85,13 @@ def check_cisco_asyncos_queue(params, section: CiscoAsyncosQueue) -> CheckResult
 register.snmp_section(
     name='cisco_asyncos_queue',
     parse_function=parse_cisco_asyncos_messageage,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.1.1',  # ASYNCOS-MAIL-MIB
             oids=[
                 '5',  # queueAvailabilityStatus
                 '11'  # workQueueMessages
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_resources.py b/agent_based/cisco_asyncos_resources.py
index 0f4cda0..c6041a2 100644
--- a/agent_based/cisco_asyncos_resources.py
+++ b/agent_based/cisco_asyncos_resources.py
@@ -17,7 +17,7 @@
 # ASYNCOS-MAIL-MIB::resourceConservationReason.0 = INTEGER: noResourceConservation(1)
 #
 #
-from typing import Mapping, List, NamedTuple
+from typing import Mapping, List, NamedTuple, Optional
 
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -62,11 +62,14 @@ class CiscoAsyncosResources(NamedTuple):
     status_readable: str
 
 
-def parse_cisco_asyncos_bandwidth(string_table: List[StringTable]) -> CiscoAsyncosResources:
-    return CiscoAsyncosResources(
-        state=get_cmk_state(string_table[0][0][0]),
-        status_readable=get_status_readable(string_table[0][0][0])
-    )
+def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> Optional[CiscoAsyncosResources]:
+    try:
+        return CiscoAsyncosResources(
+            state=get_cmk_state(string_table[0][0]),
+            status_readable=get_status_readable(string_table[0][0])
+        )
+    except IndexError:
+        return
 
 
 def discovery_cisco_asyncos_resources(section: CiscoAsyncosResources) -> DiscoveryResult:
@@ -80,14 +83,12 @@ def check_cisco_asyncos_resources(section: CiscoAsyncosResources) -> CheckResult
 register.snmp_section(
     name='cisco_asyncos_resources',
     parse_function=parse_cisco_asyncos_bandwidth,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.1.1',  # ASYNCOS-MAIL-MIB
             oids=[
                 '6',  # resourceConservationReason
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/agent_based/cisco_asyncos_temp.py b/agent_based/cisco_asyncos_temp.py
index d2d0fe1..bb38d10 100644
--- a/agent_based/cisco_asyncos_temp.py
+++ b/agent_based/cisco_asyncos_temp.py
@@ -36,6 +36,7 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     check_levels,
     SNMPTree,
     contains,
+    get_value_store,
 )
 
 from cmk.base.plugins.agent_based.utils.temperature import (
@@ -45,11 +46,11 @@ from cmk.base.plugins.agent_based.utils.temperature import (
 
 
 #
-# [[['22', 'FP_TEMP_SENSOR']]]
+# [['22', 'FP_TEMP_SENSOR']]
 #
-def parse_cisco_asyncos_temp(string_table: List[StringTable]) -> dict:
+def parse_cisco_asyncos_temp(string_table: StringTable) -> dict:
     sensors = {}
-    for sensor in string_table[0]:
+    for sensor in string_table:
         try:
             value, item = sensor
             item = item.replace('_', ' ')
@@ -70,6 +71,7 @@ def check_cisco_asyncos_temp(item, params: TempParamType, section) -> CheckResul
             section[item],
             params=params,
             unique_name='check_cisco_asyncos_temp.%s' % item,
+            value_store=get_value_store(),
         )
     except KeyError:
         pass
@@ -78,15 +80,13 @@ def check_cisco_asyncos_temp(item, params: TempParamType, section) -> CheckResul
 register.snmp_section(
     name='cisco_asyncos_temp',
     parse_function=parse_cisco_asyncos_temp,
-    fetch=[
-        SNMPTree(
+    fetch= SNMPTree(
             base='.1.3.6.1.4.1.15497.1.1.1.9.1',  # ASYNCOS-MAIL-MIB::temperatureEntry
             oids=[
                 '2',  # degreesCelsius
                 '3',  # temperatureName
             ]
         ),
-    ],
     detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'),
 )
 
diff --git a/cisco_asyncos.mkp b/cisco_asyncos.mkp
index 3102a3f16c6c7ba54cb850112f5f2df6cb36ff9b..60bcf605212b7552bb0db41df2d304ff042462d5 100644
GIT binary patch
literal 10670
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
VS_l5$Xexpr>bJR_L8U-L{XZKJ^2GoE

literal 11454
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
WK>ELW7twM+Xwp|Q?hx&e5dQ<YyRxJJ

diff --git a/gui/wato/cisco_asyncos_feature_keys.py b/gui/wato/cisco_asyncos_feature_keys.py
new file mode 100644
index 0000000..8b38a99
--- /dev/null
+++ b/gui/wato/cisco_asyncos_feature_keys.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    TextAscii,
+    ListOfStrings,
+    Tuple,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+)
+
+
+def _parameter_valuespec_cisco_asyncos_feature_keys():
+    return Dictionary(elements=[
+        ('features_ignore',
+         ListOfStrings(
+             title=_('feature keys features to ignore'),
+             orientation='vertical',
+             allow_empty=False,
+             help=_('there will be no warning/critical if this features are expired'
+                    'Examples: McAfee, IronPort Email Encryption, Data Loss Prevention, etc.'),
+         )
+         ),
+        ('expire',
+         Tuple(
+             title=_('Levels for feature key expiration in days'),
+             elements=[
+                 Integer(title=_('Warning'), default_value=30, unit=_('days before expiration')),
+                 Integer(title=_('Critical'), default_value=7, unit=_('days before expiration')),
+             ])),
+    ])
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='cisco_asyncos_feature_keys',
+        group=RulespecGroupCheckParametersNetworking,
+        item_spec=lambda: TextAscii(title=_('Cisco AsyncOS feature keys'), ),
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_cisco_asyncos_feature_keys,
+        title=lambda: _('Cisco AsyncOS feature keys'),
+    ))
diff --git a/gui/wato/cisco_asyncos_license.py b/gui/wato/cisco_asyncos_license.py
new file mode 100644
index 0000000..fb7cbca
--- /dev/null
+++ b/gui/wato/cisco_asyncos_license.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    TextAscii,
+    ListOfStrings,
+    Tuple,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+)
+
+
+def _parameter_valuespec_cisco_asyncos_license():
+    return Dictionary(elements=[
+        ('features_ignore',
+         ListOfStrings(
+             title=_('License features to ignore'),
+             orientation='vertical',
+             allow_empty=False,
+             # valuespec=Integer(minvalue=1, maxvalue=99),
+             help=_('there will be no warning/critical if this features are expired'
+                    'Examples: McAfee, IronPort Email Encryption, Data Loss Prevention, etc.'),
+         )
+         ),
+        ('expire',
+         Tuple(
+             title=_('Levels for licence expiration in days'),
+             elements=[
+                 Integer(title=_('Warning'), default_value=30, unit=_('days before expiration')),
+                 Integer(title=_('Critical'), default_value=7, unit=_('days before expiration')),
+             ])),
+    ])
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='cisco_asyncos_license',
+        group=RulespecGroupCheckParametersNetworking,
+        item_spec=lambda: TextAscii(title=_('Cisco AsyncOS license'), ),
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_cisco_asyncos_license,
+        title=lambda: _('Cisco AsyncOS license'),
+    ))
diff --git a/gui/wato/cisco_asyncos_queue.py b/gui/wato/cisco_asyncos_queue.py
new file mode 100644
index 0000000..66d0258
--- /dev/null
+++ b/gui/wato/cisco_asyncos_queue.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    TextAscii,
+    ListOfStrings,
+    Tuple,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+)
+
+
+def _parameter_valuespec_cisco_asyncos_queue():
+    return Dictionary(elements=[
+        ('levels',
+         Tuple(
+             title=_('Levels for nuber of messages in work queue'),
+             elements=[
+                 Integer(title=_('Warning'), default_value=50, unit=_('# of messages')),
+                 Integer(title=_('Critical'), default_value=100, unit=_('# of messages')),
+             ])),
+    ])
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='cisco_asyncos_queue',
+        group=RulespecGroupCheckParametersNetworking,
+        item_spec=lambda: TextAscii(title=_('Cisco AsyncOS queue'), ),
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_cisco_asyncos_queue,
+        title=lambda: _('Cisco AsyncOS queue'),
+    ))
diff --git a/gui/wato/cisco_asyncos_updates.py b/gui/wato/cisco_asyncos_updates.py
new file mode 100644
index 0000000..4f25b4d
--- /dev/null
+++ b/gui/wato/cisco_asyncos_updates.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    TextAscii,
+    ListOfStrings,
+    Tuple,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+)
+
+
+def _parameter_valuespec_cisco_asyncos_updates():
+    return Dictionary(elements=[
+        ('features_ignore',
+         ListOfStrings(
+             title=_('Update features to ignore'),
+             orientation='vertical',
+             help=_('there will be no warning/critical if this features are not updated'
+                    'Examples: geo_countries, timezones, etc.'),
+         )
+         ),
+        ('failedLevel',
+         Tuple(
+             title=_('Levels for failed attempts'),
+             elements=[
+                 Integer(title=_('Warning'), default_value=5, unit=_('# of failed attempts')),
+                 Integer(title=_('Critical'), default_value=10, unit=_('# of failed attempts')),
+             ])),
+    ])
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='cisco_asyncos_updates',
+        group=RulespecGroupCheckParametersNetworking,
+        item_spec=lambda: TextAscii(title=_('Cisco AsyncOS updates'), ),
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_cisco_asyncos_updates,
+        title=lambda: _('Cisco AsyncOS updates'),
+    ))
diff --git a/packages/cisco_asyncos b/packages/cisco_asyncos
index ab2cde2..40f7910 100644
--- a/packages/cisco_asyncos
+++ b/packages/cisco_asyncos
@@ -39,14 +39,13 @@
                            'cisco_asyncos_resources.py',
                            'cisco_asyncos_feature_keys.py',
                            'cisco_asyncos_updates.py'],
-           'web': ['plugins/wato/cisco_asyncos_queue.py',
-                   'plugins/metrics/cisco_asyncos.py',
-                   'plugins/wato/cisco_asyncos_feature_keys.py',
-                   'plugins/wato/cisco_asyncos_updates.py']},
+           'gui': ['wato/cisco_asyncos_feature_keys.py',
+                   'wato/cisco_asyncos_license.py',
+                   'wato/cisco_asyncos_queue.py',
+                   'wato/cisco_asyncos_updates.py']},
  'name': 'cisco_asyncos',
- 'num_files': 19,
  'title': 'Cisco AsyncOS (IronPort) checks',
- 'version': '20210324_v0.2.0',
- 'version.min_required': '2.0.0',
- 'version.packaged': '2.0.0p1',
+ 'version': '20230306.v0.3.0',
+ 'version.min_required': '2.1.0',
+ 'version.packaged': '2.1.0p22',
  'version.usable_until': None}
\ No newline at end of file
-- 
GitLab