From e4633696717705360f1c3ee48f7a4cb3f2eacdf4 Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 10 Aug 2017 10:28:02 +0200 Subject: [PATCH 1/6] added insecure argument for the ssl connections --- check_http_json.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/check_http_json.py b/check_http_json.py index dac67ec..c723b9f 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -11,6 +11,7 @@ import httplib, urllib, urllib2, base64 import json import argparse import sys +import ssl from pprint import pprint from urllib2 import HTTPError from urllib2 import URLError @@ -269,6 +270,7 @@ def parseArgs(): # parser.add_argument('-v', '--verbose', action='store_true', help='Verbose Output') parser.add_argument('-d', '--debug', action='store_true', help='Debug mode.') parser.add_argument('-s', '--ssl', action='store_true', help='HTTPS mode.') + parser.add_argument('-k', '--insecure', action='store_true', help='do not check server SSL certificate') parser.add_argument('-H', '--host', dest='host', required=True, help='Host.') parser.add_argument('-P', '--port', dest='port', help='TCP port') parser.add_argument('-p', '--path', dest='path', help='Path.') @@ -404,6 +406,11 @@ if __name__ == "__main__": if args.port: url += ":%s" % args.port if args.path: url += "/%s" % args.path debugPrint(args.debug, "url:%s" % url) + if args.insecure: + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + else: + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + context.verify_mode = ssl.CERT_OPTIONAL # Attempt to reach the endpoint try: req = urllib2.Request(url) @@ -416,13 +423,13 @@ if __name__ == "__main__": for header in headers: req.add_header(header, headers[header]) if args.timeout and args.data: - response = urllib2.urlopen(req, timeout=args.timeout, data=args.data) + response = urllib2.urlopen(req, timeout=args.timeout, data=args.data, context=context) elif args.timeout: - response = urllib2.urlopen(req, timeout=args.timeout) + response = urllib2.urlopen(req, timeout=args.timeout, context=context) elif args.data: - response = urllib2.urlopen(req, data=args.data) + response = urllib2.urlopen(req, data=args.data, context=context) else: - response = urllib2.urlopen(req) + response = urllib2.urlopen(req, context=context) except HTTPError as e: nagios.append_unknown("HTTPError[%s], url:%s" % (str(e.code), url)) except URLError as e: From 965626543965ca3dada49d26204ca6777af656ec Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 10 Aug 2017 10:29:45 +0200 Subject: [PATCH 2/6] print current value in the icinga message --- check_http_json.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/check_http_json.py b/check_http_json.py index c723b9f..8717a31 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -182,19 +182,19 @@ class JsonRuleProcessor: end = vals[1] if(start == '~'): if (invert and self.helper.lte(key, end)): - failure += " Value for key %s was less than or equal to %s." % (alias, end) + failure += " Value (%s) for key %s was less than or equal to %s." % (self.helper.get(key), alias, end) elif (not invert and self.helper.gt(key, end)): - failure += " Value for key %s was greater than %s." % (alias, end) + failure += " Value (%s) for key %s was greater than %s." % (self.helper.get(key), alias, end) elif(end == 'infinity'): if (invert and self.helper.gte(key, start)): - failure += " Value for key %s was greater than or equal to %s." % (alias, start) + failure += " Value (%s) for key %s was greater than or equal to %s." % (self.helper.get(key), alias, start) elif (not invert and self.helper.lt(key, start)): - failure += " Value for key %s was less than %s." % (alias, start) + failure += " Value (%s) for key %s was less than %s." % (self.helper.get(key), alias, start) else: if (invert and self.helper.gte(key, start) and self.helper.lte(key, end)): - failure += " Value for key %s was inside the range %s:%s." % (alias, start, end) + failure += " Value (%s) for key %s was inside the range %s:%s." % (self.helper.get(key), alias, start, end) elif (not invert and (self.helper.lt(key, start) or self.helper.gt(key, end))): - failure += " Value for key %s was outside the range %s:%s." % (alias, start, end) + failure += " Value (%s) for key %s was outside the range %s:%s." % (self.helper.get(key), alias, start, end) return failure def checkThresholds(self, threshold_list): From 1e707a4b6ad4d7a651f4a2e836f1e03878a756b4 Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 10 Aug 2017 15:05:53 +0200 Subject: [PATCH 3/6] add repo and upstream info --- check_http_json.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/check_http_json.py b/check_http_json.py index 8717a31..81dde37 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -5,6 +5,9 @@ Check HTTP JSON Nagios Plugin Generic Nagios plugin which checks json values from a given endpoint against argument specified rules and determines the status and performance data for that service. +Git repo found at: ssh://git@app01.stash.office.infra.cgn.travian.info:7999/sys/icinga_check_http_json.git +Branch: tg +Upstream: https://github.com/drewkerrigan/nagios-http-json """ import httplib, urllib, urllib2, base64 From 89f42c15a01adab28cc0651dec7c0b15da36ab47 Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 10 Aug 2017 15:41:35 +0200 Subject: [PATCH 4/6] use python2.7 because on centos 6 (icinga) the default python is 2.6 and doesn;t have the required ssl libraries --- check_http_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check_http_json.py b/check_http_json.py index 81dde37..1f5c0ba 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python2.7 """ Check HTTP JSON Nagios Plugin From d164a1250cdb13491d5084b2d31d7d32e2808567 Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Wed, 10 Jan 2018 10:23:34 +0100 Subject: [PATCH 5/6] add key,value non equality check, the opposite of the -q and -Q --- check_http_json.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/check_http_json.py b/check_http_json.py index 1f5c0ba..5c72386 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -168,6 +168,15 @@ class JsonRuleProcessor: failure += " Value for key %s did not match %s." % (alias, v) return failure + def checkNonEquality(self, equality_list): + failure = '' + for kv in equality_list: + k, v = kv.split(',') + key, alias = _getKeyAlias(k) + if (self.helper.equals(key, v) == True): + failure += " Value for key %s matches %s." % (alias, v) + return failure + def checkThreshold(self, key, alias, r): failure = '' invert = False @@ -214,6 +223,8 @@ class JsonRuleProcessor: failure += self.checkThresholds(self.rules.key_threshold_warning) if self.rules.key_value_list != None: failure += self.checkEquality(self.rules.key_value_list) + if self.rules.key_value_list_not != None: + failure += self.checkNonEquality(self.rules.key_value_list_not) if self.rules.key_list != None: failure += self.checkExists(self.rules.key_list) return failure @@ -224,6 +235,8 @@ class JsonRuleProcessor: failure += self.checkThresholds(self.rules.key_threshold_critical) if self.rules.key_value_list_critical != None: failure += self.checkEquality(self.rules.key_value_list_critical) + if self.rules.key_value_list_not_critical != None: + failure += self.checkNonEquality(self.rules.key_value_list_not_critical) if self.rules.key_list_critical != None: failure += self.checkExists(self.rules.key_list_critical) return failure @@ -296,6 +309,11 @@ def parseArgs(): Multiple key values can be delimited with colon (key,value1:value2). Return warning if equality check fails') parser.add_argument('-Q', '--key_equals_critical', dest='key_value_list_critical', nargs='*', help='Same as -q but return critical if equality check fails.') + parser.add_argument('-y', '--key_not_equals', dest='key_value_list_not', nargs='*', + help='Checks equality of these keys and values (key[>alias],value key2,value2) to determine status.\ + Multiple key values can be delimited with colon (key,value1:value2). Return warning if equality check succeeds') + parser.add_argument('-Y', '--key_not_equals_critical', dest='key_value_list_not_critical', nargs='*', + help='Same as -q but return critical if equality check succeeds.') parser.add_argument('-m', '--key_metric', dest='metric_list', nargs='*', help='Gathers the values of these keys (key[>alias],UnitOfMeasure,WarnRange,CriticalRange,Min,Max) for Nagios performance data.\ More information about Range format and units of measure for nagios can be found at nagios-plugins.org/doc/guidelines.html\ @@ -315,7 +333,7 @@ if __name__ == "__main__" and len(sys.argv) >= 2 and sys.argv[1] == 'UnitTest': class RulesHelper: separator = '.' debug = False - key_threshold_warning,key_value_list,key_list,key_threshold_critical,key_value_list_critical,key_list_critical,metric_list = None, None, None, None, None, None, None + key_threshold_warning,key_value_list,key_value_list_not,key_list,key_threshold_critical,key_value_list_critical,key_value_list_not_critical,key_list_critical,metric_list = None, None, None, None, None, None, None, None, None def dash_m(self, data): self.metric_list = data; return self def dash_e(self, data): @@ -326,6 +344,10 @@ if __name__ == "__main__" and len(sys.argv) >= 2 and sys.argv[1] == 'UnitTest': self.key_value_list = data; return self def dash_Q(self, data): self.key_value_list_critical = data; return self + def dash_y(self, data): + self.key_value_list_not = data; return self + def dash_Y(self, data): + self.key_value_list_not_critical = data; return self def dash_w(self, data): self.key_threshold_warning = data; return self def dash_c(self, data): @@ -354,6 +376,10 @@ if __name__ == "__main__" and len(sys.argv) >= 2 and sys.argv[1] == 'UnitTest': self.check_data(RulesHelper().dash_q(['metric,6']), '{"metric": 5}', WARNING_CODE) self.check_data(RulesHelper().dash_Q(['metric,6']), '{"metric": 5}', CRITICAL_CODE) self.check_data(RulesHelper().dash_q(['metric,5']), '{"metric": 5}', OK_CODE) + def test_non_equality(self): + self.check_data(RulesHelper().dash_y(['metric,6']), '{"metric": 6}', WARNING_CODE) + self.check_data(RulesHelper().dash_Y(['metric,6']), '{"metric": 6}', CRITICAL_CODE) + self.check_data(RulesHelper().dash_y(['metric,5']), '{"metric": 6}', OK_CODE) def test_warning_thresholds(self): self.check_data(RulesHelper().dash_w(['metric,5']), '{"metric": 5}', OK_CODE) self.check_data(RulesHelper().dash_w(['metric,5:']), '{"metric": 5}', OK_CODE) From 67136a4a2bf4ad3479e35034ca10e9dff7ccc1b8 Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 15 Feb 2018 17:04:04 +0100 Subject: [PATCH 6/6] add client ssl cert support --- check_http_json.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/check_http_json.py b/check_http_json.py index 5c72386..ccc8b5f 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -287,6 +287,9 @@ def parseArgs(): parser.add_argument('-d', '--debug', action='store_true', help='Debug mode.') parser.add_argument('-s', '--ssl', action='store_true', help='HTTPS mode.') parser.add_argument('-k', '--insecure', action='store_true', help='do not check server SSL certificate') + parser.add_argument('--cacert', required=('-s' in sys.argv or '--ssl' in sys.argv) and not ('-k' in sys.argv or '--insecure' in sys.argv), dest='cacert', help='SSL CA certificate') + parser.add_argument('--cert', required=('-s' in sys.argv or '--ssl' in sys.argv) and not ('-k' in sys.argv or '--insecure' in sys.argv), dest='cert', help='SSL client certificate') + parser.add_argument('--key', dest='key', help='SSL client key ( if not bundled into the cert )') parser.add_argument('-H', '--host', dest='host', required=True, help='Host.') parser.add_argument('-P', '--port', dest='port', help='TCP port') parser.add_argument('-p', '--path', dest='path', help='Path.') @@ -430,16 +433,18 @@ if __name__ == "__main__": nagios = NagiosHelper() if args.ssl: url = "https://%s" % args.host + if args.insecure: + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + else: + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + context.verify_mode = ssl.CERT_OPTIONAL + context.load_verify_locations(args.cacert) + context.load_cert_chain(args.cert,keyfile=args.key) else: url = "http://%s" % args.host if args.port: url += ":%s" % args.port if args.path: url += "/%s" % args.path debugPrint(args.debug, "url:%s" % url) - if args.insecure: - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) - else: - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) - context.verify_mode = ssl.CERT_OPTIONAL # Attempt to reach the endpoint try: req = urllib2.Request(url)