From f9be378cb222c68c7d036f04d8865a86ccbb6a77 Mon Sep 17 00:00:00 2001 From: Oguzhan Cicek Date: Tue, 2 Mar 2021 15:36:45 +0100 Subject: [PATCH 1/4] adds active check to monitor to remaining validity of a given CRL URL --- checkman/check_crl | 14 +++ checks/check_crl | 20 +++++ cmk/gui/plugins/wato/active_checks.py | 27 ++++++ .../skel/local/lib/nagios/plugins/check_crl | 89 +++++++++++++++++++ 4 files changed, 150 insertions(+) create mode 100644 checkman/check_crl create mode 100644 checks/check_crl create mode 100755 omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl diff --git a/checkman/check_crl b/checkman/check_crl new file mode 100644 index 00000000000..93fd41f37af --- /dev/null +++ b/checkman/check_crl @@ -0,0 +1,14 @@ +title: Check CRL expiry +agents: active +catalog: agentless +license: GPL +distribution: check_mk + +item: + The URL of the given CRL + +description: + This check displays the remaining validity of a CRL in hours. + The Check can go into warning or critical if the remaining time + is too short. + The default tresholds are 48h for warning and 24h for criticial. diff --git a/checks/check_crl b/checks/check_crl new file mode 100644 index 00000000000..88eac64d8d3 --- /dev/null +++ b/checks/check_crl @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# author: Oguzhan Cicek, OpenSource Security GmbH - oguzhan(at)os-s.de + + +def check_crl_arguments(params): + return "-u {} -w {} -c {}".format(params.get("url"), + params.get("hours")[0], + params.get("hours")[1]) + + +def check_crl_description(params): + return "CRL: {}".format(params.get("url")) + + +active_check_info["check_crl"] = { + "command_line": "check_crl $ARG1$", + "argument_function": check_crl_arguments, + "service_description": check_crl_description, + "has_perfdata": False, +} diff --git a/cmk/gui/plugins/wato/active_checks.py b/cmk/gui/plugins/wato/active_checks.py index 2ea8a7b5469..e554aec10b8 100644 --- a/cmk/gui/plugins/wato/active_checks.py +++ b/cmk/gui/plugins/wato/active_checks.py @@ -2490,3 +2490,30 @@ def _valuespec_active_checks_elasticsearch_query(): name="active_checks:elasticsearch_query", valuespec=_valuespec_active_checks_elasticsearch_query, )) + +def _valuespec_active_checks_crl(): + return Dictionary( + title=_("Check CRL expiry"), + help=_("Checks if a Certificate Revocation List is still valid"), + optional_keys=[], + elements=[ + ("hours", + Tuple(title=_("Hours left"), + help=_("These levels make the check go warning or critical whenever the " + "remaining validity of the monitored CRL is too low."), + elements=[ + Integer(title=_("warning at"), unit=u"Hours", default_value=48), + Integer(title=_("critical at"), unit=u"Hours", default_value=24), + ])), + ("url", + TextAscii(title=_('Certificate Revocation List URL'), + allow_empty=False) + )]) + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupActiveChecks, + match_type="all", + name="active_checks:check_crl", + valuespec=_valuespec_active_checks_crl, + )) diff --git a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl new file mode 100755 index 00000000000..c3f8135344f --- /dev/null +++ b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl @@ -0,0 +1,89 @@ +#!/usr/bin/python3 + +# Remy van Elst - raymii.org - 2012 +# 05.11.2012 +# Changelog: - check with hours instead of dates for more precision, +# - URL errors are now also catched as nagios exit code. + +# Michele Baldessari - Leitner Technologies - 2011 +# 23.08.2011 + +import datetime +import getopt +import os +import pprint +import subprocess +import sys +import tempfile +import urllib.request, urllib.parse, urllib.error + +def check_crl(url, warnhour, crithour): + tmpcrl = tempfile.mktemp("crl") + #request = urllib.request.urlretrieve(url, tmpcrl) + try: + urllib.request.urlretrieve(url, tmpcrl) + except: + print ("CRITICAL: CRL could not be retreived: %s" % url) + sys.exit(2) + + ret = subprocess.check_output(["/usr/bin/openssl", "crl", "-inform", "DER", "-noout", "-nextupdate", "-in", tmpcrl]) + nextupdate = ret.strip().decode('utf-8').split("=") + os.remove(tmpcrl) + eol = datetime.datetime.strptime(nextupdate[1],"%b %d %H:%M:%S %Y GMT") + today = datetime.datetime.now() + delta = eol - today + deltaseconds = delta.seconds + delta.days * 86400 + expdays = delta.days + exphours = delta.seconds // 3600 + hours = deltaseconds // 3600 + if hours > crithour and hours <= warnhour: + msg = "WARNING CRL Expires in %s hours (%s days) (on %s)" % (hours, expdays, eol) + exitcode = 1 + elif hours < crithour: + msg = "CRITICAL CRL Expires in %s hours (%s days ) (on %s)" % (hours, expdays, eol) + exitcode = 2 + else: + msg = "OK CRL Expires in %s hours (%s days) (on %s)" % (hours, expdays, eol) + exitcode = 0 + + print (msg) + sys.exit(exitcode) + +def usage(): + print ("check_crl.py -h|--help -v|--verbose -u|--url= -w|--warninghours= -c|--criticalhours=") + print ("Example, if you want to get a warning if a CRL expires in 24 hours and a critical if it expires in 12 hours:") + print ("./check_crl.py -u \"http://domain.tld/url/crl.crl\" -w 24 -c 12") + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "hu:w:c:", ["help", "url=", "warninghours=", "criticalhours="]) + except getopt.GetoptError as err: + usage() + sys.exit(2) + url = None + warningdays = None + criticaldays = None + warninghours = None + criticalhours = None + for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + elif o in ("-u", "--url"): + url = a + elif o in ("-w", "--warninghours"): + warninghours = a + elif o in ("-c", "--criticalhours"): + criticalhours = a + else: + assert False, "unhandled option" + + if url != None and warninghours != None and criticalhours != None: + check_crl(url, int(warninghours), int(criticalhours)) + else: + usage() + sys.exit(2) + + +if __name__ == "__main__": + main() \ No newline at end of file From 1be3a3358ca4bcab340fc1e5154b9789d017cace Mon Sep 17 00:00:00 2001 From: Oguzhan Cicek Date: Sat, 6 Mar 2021 16:28:26 +0100 Subject: [PATCH 2/4] -replaces the old check_crl script with a newer one. The new one detects the remaining time in minutes. Had to add a addition try-except block in line 59 to make it work. -now works with remaining minutes and not hours. --- checkman/check_crl | 5 +- checks/check_crl | 5 +- cmk/gui/plugins/wato/active_checks.py | 8 +- .../skel/local/lib/nagios/plugins/check_crl | 120 +++++++++++++----- 4 files changed, 95 insertions(+), 43 deletions(-) diff --git a/checkman/check_crl b/checkman/check_crl index 93fd41f37af..8ea8d38711b 100644 --- a/checkman/check_crl +++ b/checkman/check_crl @@ -8,7 +8,8 @@ item: The URL of the given CRL description: - This check displays the remaining validity of a CRL in hours. + This check screens the remaining validity of a CRL in minutes. The Check can go into warning or critical if the remaining time is too short. - The default tresholds are 48h for warning and 24h for criticial. + The default tresholds are 2880 minutes (48h) for warning and + 1440 minutes (24h) for criticial. diff --git a/checks/check_crl b/checks/check_crl index 88eac64d8d3..b97f341707d 100644 --- a/checks/check_crl +++ b/checks/check_crl @@ -3,9 +3,7 @@ def check_crl_arguments(params): - return "-u {} -w {} -c {}".format(params.get("url"), - params.get("hours")[0], - params.get("hours")[1]) + return "-u {} -w {} -c {}".format(params.get("url"), params.get("minutes")[0], params.get("minutes")[1]) def check_crl_description(params): @@ -18,3 +16,4 @@ active_check_info["check_crl"] = { "service_description": check_crl_description, "has_perfdata": False, } + diff --git a/cmk/gui/plugins/wato/active_checks.py b/cmk/gui/plugins/wato/active_checks.py index e554aec10b8..51675c92fc0 100644 --- a/cmk/gui/plugins/wato/active_checks.py +++ b/cmk/gui/plugins/wato/active_checks.py @@ -2497,13 +2497,13 @@ def _valuespec_active_checks_crl(): help=_("Checks if a Certificate Revocation List is still valid"), optional_keys=[], elements=[ - ("hours", - Tuple(title=_("Hours left"), + ("minutes", + Tuple(title=_("Minutes left"), help=_("These levels make the check go warning or critical whenever the " "remaining validity of the monitored CRL is too low."), elements=[ - Integer(title=_("warning at"), unit=u"Hours", default_value=48), - Integer(title=_("critical at"), unit=u"Hours", default_value=24), + Integer(title=_("warning at"), unit=u"Minutes", default_value=2880), + Integer(title=_("critical at"), unit=u"Minutes", default_value=1440), ])), ("url", TextAscii(title=_('Certificate Revocation List URL'), diff --git a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl index c3f8135344f..12df38446a3 100755 --- a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl +++ b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl @@ -1,6 +1,31 @@ #!/usr/bin/python3 +# Copyright (C) 2013 - Remy van Elst -# Remy van Elst - raymii.org - 2012 +# This program 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, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Mark Ruys - 2015-8-27 +# Changelog: - catch openssl parsing errors +# - clean up temporary file on error +# - add support for PEM CRL's +# - fix message when CRL has been expired +# - pretty print duration + +# Jeroen Nijhof +# Changelog: - fixed timezone bug by comparing GMT with GMT +# - changed hours to minutes for even more precision + +# Remy van Elst - raymii.org - 2012 # 05.11.2012 # Changelog: - check with hours instead of dates for more precision, # - URL errors are now also catched as nagios exit code. @@ -8,6 +33,7 @@ # Michele Baldessari - Leitner Technologies - 2011 # 23.08.2011 +import time import datetime import getopt import os @@ -17,73 +43,99 @@ import sys import tempfile import urllib.request, urllib.parse, urllib.error -def check_crl(url, warnhour, crithour): - tmpcrl = tempfile.mktemp("crl") +def check_crl(url, warn, crit): + tmpcrl = tempfile.mktemp(".crl") #request = urllib.request.urlretrieve(url, tmpcrl) try: urllib.request.urlretrieve(url, tmpcrl) except: - print ("CRITICAL: CRL could not be retreived: %s" % url) + print ("CRITICAL: CRL could not be retrieved: %s" % url) + os.remove(tmpcrl) sys.exit(2) - ret = subprocess.check_output(["/usr/bin/openssl", "crl", "-inform", "DER", "-noout", "-nextupdate", "-in", tmpcrl]) + try: + inform = 'DER' + crlfile = open(tmpcrl, "r") + try: + for line in crlfile: + if "BEGIN X509 CRL" in line: + inform = 'PEM' + break + except UnicodeDecodeError: + pass + crlfile.close() + + ret = subprocess.check_output(["/usr/bin/openssl", "crl", "-inform", inform, "-noout", "-nextupdate", "-in", tmpcrl], stderr=subprocess.STDOUT) + except: + print ("UNKNOWN: CRL could not be parsed: %s %s" % url) + os.remove(tmpcrl) + sys.exit(3) + nextupdate = ret.strip().decode('utf-8').split("=") os.remove(tmpcrl) - eol = datetime.datetime.strptime(nextupdate[1],"%b %d %H:%M:%S %Y GMT") - today = datetime.datetime.now() - delta = eol - today - deltaseconds = delta.seconds + delta.days * 86400 - expdays = delta.days - exphours = delta.seconds // 3600 - hours = deltaseconds // 3600 - if hours > crithour and hours <= warnhour: - msg = "WARNING CRL Expires in %s hours (%s days) (on %s)" % (hours, expdays, eol) - exitcode = 1 - elif hours < crithour: - msg = "CRITICAL CRL Expires in %s hours (%s days ) (on %s)" % (hours, expdays, eol) + eol = time.mktime(time.strptime(nextupdate[1],"%b %d %H:%M:%S %Y GMT")) + today = time.mktime(datetime.datetime.utcnow().timetuple()) + minutes = (eol - today) / 60 + if abs(minutes) < 4 * 60: + expires = minutes + unit = "minutes" + elif abs(minutes) < 2 * 24 * 60: + expires = minutes / 60 + unit = "hours" + else: + expires = minutes / (24 * 60) + unit = "days" + gmtstr = time.asctime(time.localtime(eol)) + if minutes < 0: + msg = "CRITICAL CRL expired %d %s ago (on %s GMT)" % (-expires, unit, gmtstr) exitcode = 2 + elif minutes <= crit: + msg = "CRITICAL CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) + exitcode = 2 + elif minutes <= warn: + msg = "WARNING CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) + exitcode = 1 else: - msg = "OK CRL Expires in %s hours (%s days) (on %s)" % (hours, expdays, eol) + msg = "OK CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) exitcode = 0 print (msg) sys.exit(exitcode) def usage(): - print ("check_crl.py -h|--help -v|--verbose -u|--url= -w|--warninghours= -c|--criticalhours=") - print ("Example, if you want to get a warning if a CRL expires in 24 hours and a critical if it expires in 12 hours:") - print ("./check_crl.py -u \"http://domain.tld/url/crl.crl\" -w 24 -c 12") + print ("check_crl.py -h|--help -v|--verbose -u|--url= -w|--warning= -c|--critical=") + print ("") + print ("Example, if you want to get a warning if a CRL expires in 8 hours and a critical if it expires in 6 hours:") + print ("./check_crl.py -u \"http://domain.tld/url/crl.crl\" -w 480 -c 360") def main(): try: - opts, args = getopt.getopt(sys.argv[1:], "hu:w:c:", ["help", "url=", "warninghours=", "criticalhours="]) + opts, args = getopt.getopt(sys.argv[1:], "hu:w:c:", ["help", "url=", "warning=", "critical="]) except getopt.GetoptError as err: usage() sys.exit(2) url = None - warningdays = None - criticaldays = None - warninghours = None - criticalhours = None + warning = None + critical = None for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-u", "--url"): url = a - elif o in ("-w", "--warninghours"): - warninghours = a - elif o in ("-c", "--criticalhours"): - criticalhours = a + elif o in ("-w", "--warning"): + warning = a + elif o in ("-c", "--critical"): + critical = a else: assert False, "unhandled option" - if url != None and warninghours != None and criticalhours != None: - check_crl(url, int(warninghours), int(criticalhours)) + if url != None and warning != None and critical != None: + check_crl(url, int(warning), int(critical)) else: usage() - sys.exit(2) + sys.exit(2) if __name__ == "__main__": - main() \ No newline at end of file + main() From 53c152a26769fa1d47afcfdfc00b03e9c1848ea9 Mon Sep 17 00:00:00 2001 From: Oguzhan Cicek Date: Mon, 5 Apr 2021 19:39:56 +0200 Subject: [PATCH 3/4] -fixes bug in getting variables from "params" in case they dont exist -uses valuespec Age now -uses now checkmk file headers -changes the main() call -uses argpase now --- checkman/check_crl | 6 +- checks/check_crl | 10 ++- cmk/gui/plugins/wato/active_checks.py | 29 ++++--- .../skel/local/lib/nagios/plugins/check_crl | 85 +++++++++---------- 4 files changed, 68 insertions(+), 62 deletions(-) diff --git a/checkman/check_crl b/checkman/check_crl index 8ea8d38711b..d211b945845 100644 --- a/checkman/check_crl +++ b/checkman/check_crl @@ -8,8 +8,8 @@ item: The URL of the given CRL description: - This check screens the remaining validity of a CRL in minutes. + This check screens the remaining validity of a CRL. The Check can go into warning or critical if the remaining time is too short. - The default tresholds are 2880 minutes (48h) for warning and - 1440 minutes (24h) for criticial. + The default tresholds are 7 days for warning and + 2 days for criticial. diff --git a/checks/check_crl b/checks/check_crl index b97f341707d..ff6b79258fc 100644 --- a/checks/check_crl +++ b/checks/check_crl @@ -1,13 +1,18 @@ #!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. + # author: Oguzhan Cicek, OpenSource Security GmbH - oguzhan(at)os-s.de def check_crl_arguments(params): - return "-u {} -w {} -c {}".format(params.get("url"), params.get("minutes")[0], params.get("minutes")[1]) + return "-u {} -w {} -c {}".format(params["url"], params["time"][0], params["time"][1]) def check_crl_description(params): - return "CRL: {}".format(params.get("url")) + return "CRL: {}".format(params["url"]) active_check_info["check_crl"] = { @@ -16,4 +21,3 @@ active_check_info["check_crl"] = { "service_description": check_crl_description, "has_perfdata": False, } - diff --git a/cmk/gui/plugins/wato/active_checks.py b/cmk/gui/plugins/wato/active_checks.py index 51675c92fc0..3806e4a082e 100644 --- a/cmk/gui/plugins/wato/active_checks.py +++ b/cmk/gui/plugins/wato/active_checks.py @@ -2491,24 +2491,27 @@ def _valuespec_active_checks_elasticsearch_query(): valuespec=_valuespec_active_checks_elasticsearch_query, )) + def _valuespec_active_checks_crl(): return Dictionary( title=_("Check CRL expiry"), help=_("Checks if a Certificate Revocation List is still valid"), optional_keys=[], - elements=[ - ("minutes", - Tuple(title=_("Minutes left"), - help=_("These levels make the check go warning or critical whenever the " - "remaining validity of the monitored CRL is too low."), - elements=[ - Integer(title=_("warning at"), unit=u"Minutes", default_value=2880), - Integer(title=_("critical at"), unit=u"Minutes", default_value=1440), - ])), - ("url", - TextAscii(title=_('Certificate Revocation List URL'), - allow_empty=False) - )]) + elements=[("time", + Tuple(title=_("Time left"), + help=_("These levels make the check go warning or critical whenever the " + "remaining validity of the monitored CRL is too low."), + elements=[ + Age(title=_("warning at"), + display=["days", "hours", "minutes"], + default_value=604800), + Age(title=_("critical at"), + display=["days", "hours", "minutes"], + default_value=172800) + ])), + ("url", TextAscii(title=_('Certificate Revocation List URL'), + allow_empty=False))]) + rulespec_registry.register( HostRulespec( diff --git a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl index 12df38446a3..891b16c1401 100755 --- a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl +++ b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl @@ -1,4 +1,5 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # Copyright (C) 2013 - Remy van Elst # This program is free software: you can redistribute it and/or modify @@ -33,6 +34,11 @@ # Michele Baldessari - Leitner Technologies - 2011 # 23.08.2011 +# Oguzhan Cicek - OpenSource Security GmbH - oguzhan(at)os-s.de - 2021 +# 05.04.2021 +# Changelog: - added argparse parsing +# - added handling for DER-Certificates + import time import datetime import getopt @@ -41,17 +47,24 @@ import pprint import subprocess import sys import tempfile +import typing +import argparse import urllib.request, urllib.parse, urllib.error -def check_crl(url, warn, crit): +def output_check_result(rc, s): + stxt = ['OK', 'WARN', 'CRIT', 'UNKNOWN'][rc] + output = '%s - %s' % (stxt, s) + sys.stdout.write('%s\n' % output) + +def check_crl(url: str, warn: int, crit: int): tmpcrl = tempfile.mktemp(".crl") #request = urllib.request.urlretrieve(url, tmpcrl) try: urllib.request.urlretrieve(url, tmpcrl) except: - print ("CRITICAL: CRL could not be retrieved: %s" % url) + msg = "CRL could not be retrieved: %s" % url os.remove(tmpcrl) - sys.exit(2) + return 2, msg try: inform = 'DER' @@ -67,9 +80,9 @@ def check_crl(url, warn, crit): ret = subprocess.check_output(["/usr/bin/openssl", "crl", "-inform", inform, "-noout", "-nextupdate", "-in", tmpcrl], stderr=subprocess.STDOUT) except: - print ("UNKNOWN: CRL could not be parsed: %s %s" % url) + msg = "CRL could not be parsed: %s %s" % url os.remove(tmpcrl) - sys.exit(3) + return 3, msg nextupdate = ret.strip().decode('utf-8').split("=") os.remove(tmpcrl) @@ -87,55 +100,41 @@ def check_crl(url, warn, crit): unit = "days" gmtstr = time.asctime(time.localtime(eol)) if minutes < 0: - msg = "CRITICAL CRL expired %d %s ago (on %s GMT)" % (-expires, unit, gmtstr) + msg = "CRL expired %d %s ago (on %s GMT)" % (-expires, unit, gmtstr) exitcode = 2 elif minutes <= crit: - msg = "CRITICAL CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) + msg = "CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) exitcode = 2 elif minutes <= warn: - msg = "WARNING CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) + msg = "CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) exitcode = 1 else: - msg = "OK CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) + msg = "CRL expires in %d %s (on %s GMT)" % (expires, unit, gmtstr) exitcode = 0 - print (msg) - sys.exit(exitcode) + return exitcode, msg def usage(): - print ("check_crl.py -h|--help -v|--verbose -u|--url= -w|--warning= -c|--critical=") - print ("") - print ("Example, if you want to get a warning if a CRL expires in 8 hours and a critical if it expires in 6 hours:") - print ("./check_crl.py -u \"http://domain.tld/url/crl.crl\" -w 480 -c 360") + sys.stdout.write("check_crl.py -h|--help -v|--verbose -u|--url= -w|--warning= -c|--critical=") + sys.stdout.write("") + sys.stdout.write("Example, if you want to get a warning if a CRL expires in 8 hours and a critical if it expires in 6 hours:") + sys.stdout.write("./check_crl.py -u \"http://domain.tld/url/crl.crl\" -w 480 -c 360") def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "hu:w:c:", ["help", "url=", "warning=", "critical="]) - except getopt.GetoptError as err: + parser = argparse.ArgumentParser() + parser.add_argument("--url", "-u", required=True) + parser.add_argument("--warning", "-w", required=True, type=int) + parser.add_argument("--critical", "-c", required=True, type=int) + args = parser.parse_args() + if args.url== "": usage() - sys.exit(2) - url = None - warning = None - critical = None - for o, a in opts: - if o in ("-h", "--help"): - usage() - sys.exit() - elif o in ("-u", "--url"): - url = a - elif o in ("-w", "--warning"): - warning = a - elif o in ("-c", "--critical"): - critical = a - else: - assert False, "unhandled option" - - if url != None and warning != None and critical != None: - check_crl(url, int(warning), int(critical)) - else: - usage() - sys.exit(2) - + return 3, "invalid parameter" + url = args.url + warning = int(args.warning / 60) + critical = int(args.critical / 60) + return check_crl(url, int(warning), int(critical)) if __name__ == "__main__": - main() + exitcode, info = main() + output_check_result(exitcode, info) + sys.exit(exitcode) From c046ed3cd0e8eac529555098618dfc6df7bb07c9 Mon Sep 17 00:00:00 2001 From: Oguzhan Cicek Date: Sun, 18 Apr 2021 10:10:15 +0200 Subject: [PATCH 4/4] -adds a unit test for check_crl -renames the active check from check_crl to crl --- checks/check_crl | 10 +++++++--- cmk/gui/plugins/wato/active_checks.py | 4 ++-- .../skel/local/lib/nagios/plugins/check_crl | 10 +++------- tests/unit/checks/test_check_crl.py | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 tests/unit/checks/test_check_crl.py diff --git a/checks/check_crl b/checks/check_crl index ff6b79258fc..9956456ccd1 100644 --- a/checks/check_crl +++ b/checks/check_crl @@ -8,14 +8,18 @@ def check_crl_arguments(params): - return "-u {} -w {} -c {}".format(params["url"], params["time"][0], params["time"][1]) + url = params["url"] + warn = params["time"][0] + crit = params["time"][1] + return f"-u {url} -w {warn} -c {crit}" def check_crl_description(params): - return "CRL: {}".format(params["url"]) + url = params["url"] + return f"CRL: {url}" -active_check_info["check_crl"] = { +active_check_info["crl"] = { "command_line": "check_crl $ARG1$", "argument_function": check_crl_arguments, "service_description": check_crl_description, diff --git a/cmk/gui/plugins/wato/active_checks.py b/cmk/gui/plugins/wato/active_checks.py index 3806e4a082e..cda21661b3e 100644 --- a/cmk/gui/plugins/wato/active_checks.py +++ b/cmk/gui/plugins/wato/active_checks.py @@ -2492,7 +2492,7 @@ def _valuespec_active_checks_elasticsearch_query(): )) -def _valuespec_active_checks_crl(): +def _valuespec_active_checks_crl() -> Dictionary: return Dictionary( title=_("Check CRL expiry"), help=_("Checks if a Certificate Revocation List is still valid"), @@ -2517,6 +2517,6 @@ def _valuespec_active_checks_crl(): HostRulespec( group=RulespecGroupActiveChecks, match_type="all", - name="active_checks:check_crl", + name="active_checks:crl", valuespec=_valuespec_active_checks_crl, )) diff --git a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl index 891b16c1401..7449fac7a94 100755 --- a/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl +++ b/omd/packages/nagios/skel/local/lib/nagios/plugins/check_crl @@ -51,12 +51,8 @@ import typing import argparse import urllib.request, urllib.parse, urllib.error -def output_check_result(rc, s): - stxt = ['OK', 'WARN', 'CRIT', 'UNKNOWN'][rc] - output = '%s - %s' % (stxt, s) - sys.stdout.write('%s\n' % output) -def check_crl(url: str, warn: int, crit: int): +def check_crl(url: str, warn: int, crit: int) -> (int, str): tmpcrl = tempfile.mktemp(".crl") #request = urllib.request.urlretrieve(url, tmpcrl) try: @@ -122,7 +118,7 @@ def usage(): def main(): parser = argparse.ArgumentParser() - parser.add_argument("--url", "-u", required=True) + parser.add_argument("--url", "-u", required=True, type=str) parser.add_argument("--warning", "-w", required=True, type=int) parser.add_argument("--critical", "-c", required=True, type=int) args = parser.parse_args() @@ -136,5 +132,5 @@ def main(): if __name__ == "__main__": exitcode, info = main() - output_check_result(exitcode, info) + sys.stdout.write('%s\n' % info) sys.exit(exitcode) diff --git a/tests/unit/checks/test_check_crl.py b/tests/unit/checks/test_check_crl.py new file mode 100644 index 00000000000..8fe5c23f466 --- /dev/null +++ b/tests/unit/checks/test_check_crl.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. + +import pytest # type: ignore[import] +from testlib import ActiveCheck # type: ignore[import] + +pytestmark = pytest.mark.checks + + +@pytest.mark.parametrize("params,expected_args", [ + (("foo", 222, 111, "bar", {}), ["--url=foo", "--warn=222", "--crit=111"]), +]) +def test_check_crl_argument_parsing(params, expected_args): + """Tests if all required arguments are present.""" + active_check = ActiveCheck("check_crl") + assert active_check.run_argument_function(params) == expected_args