diff --git a/agent_based/cisco_asyncos_license.py b/agent_based/cisco_asyncos_license.py new file mode 100644 index 0000000000000000000000000000000000000000..3d8bc5aa8e55fc35df297b971a87eebd36e68bea --- /dev/null +++ b/agent_based/cisco_asyncos_license.py @@ -0,0 +1,236 @@ +#!/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 : 2020-02-10 +# +# monitors license status of Cisco IronPort Appliances (ESA/SMA/WSA) +# Tested with: C380, M380, C370, M670, S370 +# +# 2021-03-25: rewrite for CMK2.0 +# +# sample snmpwalk: +# +# OMD[cmk16x]:~$ snmpwalk -v2c -c public localhost -m ASYNCOS-MAIL-MIB -ObentU keyExpirationTable +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.1 = INTEGER: 1 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.2 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.3 = INTEGER: 3 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.4 = INTEGER: 4 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.5 = INTEGER: 5 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.6 = INTEGER: 6 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.7 = INTEGER: 7 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.8 = INTEGER: 8 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.9 = INTEGER: 9 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.10 = INTEGER: 10 +# .1.3.6.1.4.1.15497.1.1.1.12.1.1.11 = INTEGER: 11 +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.1 = STRING: Bounce Verification +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.2 = STRING: Data Loss Prevention +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.3 = STRING: External Threat Feeds +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.4 = STRING: File Analysis +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.5 = STRING: File Reputation +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.6 = STRING: Incoming Mail Handling +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.7 = STRING: IronPort Anti-Spam +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.8 = STRING: IronPort Email Encryption +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.9 = STRING: McAfee +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.10 = STRING: Outbreak Filters +# .1.3.6.1.4.1.15497.1.1.1.12.1.2.11 = STRING: Sophos Anti-Virus +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.1 = INTEGER: 1 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.2 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.3 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.4 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.5 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.6 = INTEGER: 1 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.7 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.8 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.9 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.10 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.3.11 = INTEGER: 2 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.1 = Gauge32: 0 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.2 = Gauge32: 0 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.3 = Gauge32: 32542740 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.4 = Gauge32: 32542804 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.5 = Gauge32: 32542804 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.6 = Gauge32: 0 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.7 = Gauge32: 32542740 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.8 = Gauge32: 0 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.9 = Gauge32: 1463722 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.10 = Gauge32: 32542740 +# .1.3.6.1.4.1.15497.1.1.1.12.1.4.11 = Gauge32: 32542740 +# +# OMD[cmk16x]:~$ snmpwalk -v2c -c public localhost -m ASYNCOS-MAIL-MIB keyExpirationTable +# ASYNCOS-MAIL-MIB::keyExpirationIndex.1 = INTEGER: 1 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.2 = INTEGER: 2 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.3 = INTEGER: 3 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.4 = INTEGER: 4 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.5 = INTEGER: 5 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.6 = INTEGER: 6 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.7 = INTEGER: 7 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.8 = INTEGER: 8 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.9 = INTEGER: 9 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.10 = INTEGER: 10 +# ASYNCOS-MAIL-MIB::keyExpirationIndex.11 = INTEGER: 11 +# ASYNCOS-MAIL-MIB::keyDescription.1 = STRING: Bounce Verification +# ASYNCOS-MAIL-MIB::keyDescription.2 = STRING: Data Loss Prevention +# ASYNCOS-MAIL-MIB::keyDescription.3 = STRING: External Threat Feeds +# ASYNCOS-MAIL-MIB::keyDescription.4 = STRING: File Analysis +# ASYNCOS-MAIL-MIB::keyDescription.5 = STRING: File Reputation +# ASYNCOS-MAIL-MIB::keyDescription.6 = STRING: Incoming Mail Handling +# ASYNCOS-MAIL-MIB::keyDescription.7 = STRING: IronPort Anti-Spam +# ASYNCOS-MAIL-MIB::keyDescription.8 = STRING: IronPort Email Encryption +# ASYNCOS-MAIL-MIB::keyDescription.9 = STRING: McAfee +# ASYNCOS-MAIL-MIB::keyDescription.10 = STRING: Outbreak Filters +# ASYNCOS-MAIL-MIB::keyDescription.11 = STRING: Sophos Anti-Virus +# ASYNCOS-MAIL-MIB::keyIsPerpetual.1 = INTEGER: true(1) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.2 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.3 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.4 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.5 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.6 = INTEGER: true(1) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.7 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.8 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.9 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.10 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keyIsPerpetual.11 = INTEGER: false(2) +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.1 = Gauge32: 0 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.2 = Gauge32: 0 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.3 = Gauge32: 32542740 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.4 = Gauge32: 32542804 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.5 = Gauge32: 32542804 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.6 = Gauge32: 0 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.7 = Gauge32: 32542740 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.8 = Gauge32: 0 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.9 = Gauge32: 1463722 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.10 = Gauge32: 32542740 +# ASYNCOS-MAIL-MIB::keySecondsUntilExpire.11 = Gauge32: 32542740 +# + +import time +from typing import Mapping, List, NamedTuple + +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, + check_levels, + Result, + SNMPTree, + contains, + State, + render, +) + + +def get_isperpetual(isperpetual): + s_status = { + '1': True, + '2': False + } + return s_status.get(isperpetual, False) + + +class CiscoAsyncosLicense(NamedTuple): + perpetual: bool + secondsuntilexpire: int + daysuntilexpire: int + expiredate: str + + +# [[ +# ['Bounce Verification', '1', '0'], +# ['Data Loss Prevention', '2', '0'], +# ['External Threat Feeds', '2', '32542740'], +# ['File Analysis', '2', '32542804'], +# ['File Reputation', '2', '32542804'], +# ['Incoming Mail Handling', '1', '0'], +# ['IronPort Anti-Spam', '2', '32542740'], +# ['IronPort Email Encryption', '2', '0'], +# ['McAfee', '2', '1463722'], +# ['Outbreak Filters', '2', '32542740'], +# ['Sophos Anti-Virus', '2', '32542740'] +# ]] +def parse_cisco_asyncos_license(string_table: List[StringTable]) -> Mapping[str, CiscoAsyncosLicense]: + licenses = {} + for license, isperpetual, secondsuntilexpire in string_table[0]: + licenses.update({license: CiscoAsyncosLicense( + perpetual=get_isperpetual(isperpetual), + secondsuntilexpire=int(secondsuntilexpire), + daysuntilexpire=int(secondsuntilexpire) // 3600 // 24, + expiredate=time.strftime("%d %b %Y", time.localtime(time.time() + int(secondsuntilexpire))) + )}) + return licenses + + +# { +# 'Bounce Verification': CiscoAsyncosLicense(perpetual=True, secondsuntilexpire=0, daysuntilexpire=0, expiredate='25 Mar 2021'), +# 'Data Loss Prevention': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=0, daysuntilexpire=0, expiredate='25 Mar 2021'), +# 'External Threat Feeds': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542740, daysuntilexpire=376, expiredate='06 Apr 2022'), +# 'File Analysis': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542804, daysuntilexpire=376, expiredate='06 Apr 2022'), +# 'File Reputation': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542804, daysuntilexpire=376, expiredate='06 Apr 2022'), +# 'Incoming Mail Handling': CiscoAsyncosLicense(perpetual=True, secondsuntilexpire=0, daysuntilexpire=0, expiredate='25 Mar 2021'), +# 'IronPort Anti-Spam': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542740, daysuntilexpire=376, expiredate='06 Apr 2022'), +# 'IronPort Email Encryption': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=0, daysuntilexpire=0, expiredate='25 Mar 2021'), +# 'McAfee': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=1463722, daysuntilexpire=16, expiredate='11 Apr 2021'), +# 'Outbreak Filters': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542740, daysuntilexpire=376, expiredate='06 Apr 2022'), +# 'Sophos Anti-Virus': CiscoAsyncosLicense(perpetual=False, secondsuntilexpire=32542740, daysuntilexpire=376, expiredate='06 Apr 2022') +# } + +def discovery_cisco_asyncos_license(section: Mapping[str, CiscoAsyncosLicense]) -> DiscoveryResult: + yield Service() + +# Parameters({'expire': (400, 360), 'features_ignore': ['Data Loss Prevention']}) +def check_cisco_asyncos_license(params, section: Mapping[str, CiscoAsyncosLicense]) -> CheckResult: + features_ignore = params.get('features_ignore', []) + warn, crit = params.get('expire') + ignore_count = 0 + for license in section.keys(): + if section[license].perpetual: + yield Result(state=State.OK, notice='%s is perpetual (will not expire)' % license) + elif license in features_ignore: + yield Result(state=State.OK, notice='%s will expire at %s (%s days). Feature ignored!' % (license, section[license].expiredate, section[license].daysuntilexpire)) + ignore_count += 1 + elif section[license].secondsuntilexpire == 0: + yield Result(state=State.CRIT, notice='%s has expired or is not licensed' % license) + else: + if section[license].daysuntilexpire < crit: + state = State.CRIT + elif section[license].daysuntilexpire < warn: + state = State.WARN + else: + state = State.OK + + yield Result(state=state, notice='%s will expire at %s (%s days)' % (license, section[license].expiredate, section[license].daysuntilexpire)) + + yield Result(state=State.OK, summary='%d/%d Features found/ignored' % (len(section.keys()), ignore_count)) + +register.snmp_section( + name='cisco_asyncos_license', + parse_function=parse_cisco_asyncos_license, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1.12.1', # ASYNCOS-MAIL-MIB::keyExpirationEntry + oids=[ + '2', # keyDescription + '3', # keyIsPerpetual + '4', # keySecondsUntilExpire + ] + ), + ], + detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), +) + +register.check_plugin( + name='cisco_asyncos_license', + service_name='License', + discovery_function=discovery_cisco_asyncos_license, + check_function=check_cisco_asyncos_license, + check_default_parameters={'expire': (30, 7)}, + check_ruleset_name='cisco_asyncos_license', +) diff --git a/agent_based/cisco_asyncos_resources.py b/agent_based/cisco_asyncos_resources.py new file mode 100644 index 0000000000000000000000000000000000000000..0f4cda0ba9c5f5ffa641fcc2318af5af468bde98 --- /dev/null +++ b/agent_based/cisco_asyncos_resources.py @@ -0,0 +1,99 @@ +#!/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 : 2020-03-08 +# +# monitors status Cisco IronPort Appliances (ESA) system resources +# Tested with: C380, C370 +# +# 2021-03-25: rewrite for CMK2.0 +# +# .1.3.6.1.4.1.15497.1.1.1.6.0 = INTEGER: 1 +# +# ASYNCOS-MAIL-MIB::resourceConservationReason.0 = INTEGER: noResourceConservation(1) +# +# +from typing import Mapping, List, NamedTuple + +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, + check_levels, + Result, + SNMPTree, + contains, + State, + render, +) + + +def get_status_readable(st: str) -> str: + states = { + '1': 'none', + '2': 'memory shortage', + '3': 'queue space shortage', + '4': 'queue Full', + } + return states.get(st, st) + + +def get_cmk_state(st: str) -> State: + states = { + '1': State.OK, + '2': State.WARN, + '3': State.WARN, + '4': State.CRIT, + } + return states.get(st, State.CRIT) + + +class CiscoAsyncosResources(NamedTuple): + state: State + 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 discovery_cisco_asyncos_resources(section: CiscoAsyncosResources) -> DiscoveryResult: + yield Service() + + +def check_cisco_asyncos_resources(section: CiscoAsyncosResources) -> CheckResult: + yield Result(state=section.state, notice='Resource conservation %s' % section.status_readable) + + +register.snmp_section( + name='cisco_asyncos_resources', + parse_function=parse_cisco_asyncos_bandwidth, + 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'), +) + +register.check_plugin( + name='cisco_asyncos_resources', + service_name='Resources', + discovery_function=discovery_cisco_asyncos_resources, + check_function=check_cisco_asyncos_resources, +) diff --git a/checks/cisco_asyncos_resources b/checks/cisco_asyncos_resources deleted file mode 100644 index 761a5bbfc8b1b37d01bcead341875183602632c0..0000000000000000000000000000000000000000 --- a/checks/cisco_asyncos_resources +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- -# -# Author: Th.L. -# Date: 08-03-2020 -# -# monitors status Cisco IronPort Appliances (ESA) system resources -# Tested with: C380, C370 -# -# check_mk is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation in version 2. check_mk is distributed -# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- -# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. See the GNU General Public License for more de- -# tails. You should have received a copy of the GNU General Public -# License along with GNU Make; see the file COPYING. If not, write -# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -# Boston, MA 02110-1301 USA. -# -# .1.3.6.1.4.1.15497.1.1.1.6.0 = INTEGER: 1 -# -# ASYNCOS-MAIL-MIB::resourceConservationReason.0 = INTEGER: noResourceConservation(1) -# -# sample info -# [[u'1', u'1']] -# - - -def inventory_cisco_asyncos_resources(info): - if len(info[0]) == 1: - return [(None, None)] - - -def check_cisco_asyncos_resources(_no_item, _no_params, info): - if len(info[0]) == 1: - recsourceStatus = info[0][0] - recsourceStatus = int(recsourceStatus) - - if recsourceStatus == 1: - yield 0, 'no resource conservation' - elif recsourceStatus ==2: - yield 1, 'Resource conservation: memory shortage' - elif recsourceStatus ==3: - yield 1, 'Resource conservation: queue space shortage' - elif recsourceStatus == 4: - yield 2, 'Resource conservation: queue Full' - - -check_info['cisco_asyncos_resources'] = { - 'inventory_function': inventory_cisco_asyncos_resources, - 'check_function': check_cisco_asyncos_resources, - 'service_description': 'Resources', - 'has_perfdata': False, - 'snmp_info': ( - '.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB - [ - '6', # resourceConservationReason - ]), - 'snmp_scan_function': lambda oid: oid('.1.3.6.1.2.1.1.1.0').find('AsyncOS') != -1, - # 'snmp_scan_function': scan_cisco_asyncos, - # 'includes': ['cisco_asyncos.include'], -} diff --git a/cisco_asyncos.mkp b/cisco_asyncos.mkp index d957f13594041c7efc82b37b452320063c94c037..048e9c6c3a99532a19865e7e3de65e825043c284 100644 Binary files a/cisco_asyncos.mkp and b/cisco_asyncos.mkp differ diff --git a/packages/cisco_asyncos b/packages/cisco_asyncos index 513ab34391ad3f1d2c98d6644cfc3b3d6550d291..96321b665aec7202204d5d85e86e6d1f0a0f8b4d 100644 --- a/packages/cisco_asyncos +++ b/packages/cisco_asyncos @@ -35,10 +35,10 @@ 'cisco_asyncos_conn.py', 'cisco_asyncos_dns.py', 'cisco_asyncos_messageage.py', - 'cisco_asyncos_queue.py'], - 'checks': ['cisco_asyncos_license', - 'cisco_asyncos_update', - 'cisco_asyncos_resources'], + 'cisco_asyncos_queue.py', + 'cisco_asyncos_resources.py', + 'cisco_asyncos_license.py'], + 'checks': ['cisco_asyncos_update'], 'web': ['plugins/wato/cisco_asyncos_license.py', 'plugins/wato/cisco_asyncos_queue.py', 'plugins/wato/cisco_asyncos_update.py', diff --git a/web/plugins/wato/cisco_asyncos_license.py b/web/plugins/wato/cisco_asyncos_license.py index 95fd5ef285406577ec1745977ab041f5b1ada685..bd4accbb849d41c04feb1596cb5b45058d4b4e11 100644 --- a/web/plugins/wato/cisco_asyncos_license.py +++ b/web/plugins/wato/cisco_asyncos_license.py @@ -1,31 +1,51 @@ -#!/usr/bin/python -# -*- encoding: utf-8; py-indent-offset: 4 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # # -register_check_parameters( - subgroup_applications, - 'cisco_asyncos_license', - _('Cisco AsyncOS license'), - Dictionary( - # help=_(''), - elements=[ - ('features_ignore', - ListOfStrings( - title=_('license features to ignore'), - orientation='vertical', - 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')), - ])), - ], - ), - None, - match_type='dict', +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + TextAscii, + ListOfStrings, + Tuple, ) + +from cmk.gui.plugins.wato 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'), + ))