mirror of
https://github.com/drewkerrigan/nagios-http-json.git
synced 2026-02-12 01:51:01 +01:00
Compare commits
15 Commits
v2.1.1
...
fix/array-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfcdf4d872 | ||
|
|
ce9c5fdada | ||
|
|
27c710b2ea | ||
|
|
dddf8432d6 | ||
|
|
739c093702 | ||
|
|
46271c961b | ||
|
|
49b338bdb6 | ||
|
|
9f41fc491e | ||
|
|
3a22b712ab | ||
|
|
9626fc4464 | ||
|
|
c54a0040a0 | ||
|
|
ffd96dd59f | ||
|
|
0572c2f494 | ||
|
|
2e6eaeea59 | ||
|
|
428a5a6d3a |
15
.github/workflows/unittest.yml
vendored
15
.github/workflows/unittest.yml
vendored
@@ -7,21 +7,20 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.6, 3.7, 3.8]
|
python-version: [3.8, 3,9]
|
||||||
name: GitHub Action
|
name: GitHub Action
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install -r requirements-dev.txt
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: |
|
run: |
|
||||||
pip3 install --upgrade pip wheel setuptools
|
make lint
|
||||||
pip3 install pylint
|
|
||||||
python3 -m pylint check_http_json.py
|
|
||||||
- name: Unit Test
|
- name: Unit Test
|
||||||
run: |
|
run: |
|
||||||
python3 -m unittest discover
|
make test
|
||||||
- name: Coverage
|
- name: Coverage
|
||||||
run: |
|
run: |
|
||||||
pip3 install coverage
|
make coverage
|
||||||
python3 -m coverage run -m unittest discover
|
|
||||||
python3 -m coverage report -m --include check_http_json.py
|
|
||||||
|
|||||||
20
.pylintrc
20
.pylintrc
@@ -1,5 +1,21 @@
|
|||||||
# pylint config
|
# pylint config
|
||||||
[MESSAGES CONTROL]
|
|
||||||
disable=line-too-long, redefined-outer-name, too-many-arguments, too-many-instance-attributes, fixme, invalid-name, superfluous-parens, missing-function-docstring, missing-module-docstring, multiple-imports, no-else-return, too-many-return-statements, too-many-branches, too-many-statements
|
|
||||||
[MASTER]
|
[MASTER]
|
||||||
ignore-patterns=^test.*
|
ignore-patterns=^test.*
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
disable=fixme,
|
||||||
|
consider-using-f-string,
|
||||||
|
invalid-name,
|
||||||
|
line-too-long,
|
||||||
|
missing-function-docstring,
|
||||||
|
missing-module-docstring,
|
||||||
|
multiple-imports,
|
||||||
|
no-else-return,
|
||||||
|
redefined-outer-name,
|
||||||
|
superfluous-parens,
|
||||||
|
too-many-locals,
|
||||||
|
too-many-arguments,
|
||||||
|
too-many-branches,
|
||||||
|
too-many-instance-attributes,
|
||||||
|
too-many-return-statements,
|
||||||
|
too-many-statements
|
||||||
|
|||||||
9
Makefile
Normal file
9
Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.PHONY: lint test coverage
|
||||||
|
|
||||||
|
lint:
|
||||||
|
python -m pylint check_http_json.py
|
||||||
|
test:
|
||||||
|
python -m unittest discover
|
||||||
|
coverage:
|
||||||
|
python -m coverage run -m unittest discover
|
||||||
|
python -m coverage report -m --include check_http_json.py
|
||||||
@@ -38,7 +38,7 @@ Generic Nagios plugin which checks json values from a given endpoint against
|
|||||||
argument specified rules and determines the status and performance data for
|
argument specified rules and determines the status and performance data for
|
||||||
that service.
|
that service.
|
||||||
|
|
||||||
Version: 2.0.0 (2020-03-22)
|
Version: 2.1.2 (2022-09-15)
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@@ -46,6 +46,8 @@ optional arguments:
|
|||||||
-s, --ssl use TLS to connect to remote host
|
-s, --ssl use TLS to connect to remote host
|
||||||
-H HOST, --host HOST remote host to query
|
-H HOST, --host HOST remote host to query
|
||||||
-k, --insecure do not check server SSL certificate
|
-k, --insecure do not check server SSL certificate
|
||||||
|
-X {GET,POST}, --request {GET,POST}
|
||||||
|
Specifies a custom request method to use when communicating with the HTTP server
|
||||||
-V, --version print version of this plugin
|
-V, --version print version of this plugin
|
||||||
--cacert CACERT SSL CA certificate
|
--cacert CACERT SSL CA certificate
|
||||||
--cert CERT SSL client certificate
|
--cert CERT SSL client certificate
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ WARNING_CODE = 1
|
|||||||
CRITICAL_CODE = 2
|
CRITICAL_CODE = 2
|
||||||
UNKNOWN_CODE = 3
|
UNKNOWN_CODE = 3
|
||||||
|
|
||||||
__version__ = '2.0.0'
|
__version__ = '2.1.2'
|
||||||
__version_date__ = '2020-03-22'
|
__version_date__ = '2022-09-15'
|
||||||
|
|
||||||
class NagiosHelper:
|
class NagiosHelper:
|
||||||
"""
|
"""
|
||||||
@@ -156,25 +156,30 @@ class JsonHelper:
|
|||||||
data = temp_data
|
data = temp_data
|
||||||
else:
|
else:
|
||||||
data = self.data
|
data = self.data
|
||||||
|
|
||||||
if len(key) <= 0:
|
if len(key) <= 0:
|
||||||
return data
|
return data
|
||||||
if key.find(self.separator) != -1 and \
|
|
||||||
key.find(self.arrayOpener) != -1:
|
|
||||||
|
if key.find(self.separator) != -1 and key.find(self.arrayOpener) != -1:
|
||||||
if key.find(self.separator) < key.find(self.arrayOpener):
|
if key.find(self.separator) < key.find(self.arrayOpener):
|
||||||
return self.getSubElement(key, data)
|
return self.getSubElement(key, data)
|
||||||
else:
|
else:
|
||||||
return self.getSubArrayElement(key, data)
|
return self.getSubArrayElement(key, data)
|
||||||
else:
|
|
||||||
if key.find(self.separator) != -1:
|
if key.find(self.separator) != -1:
|
||||||
return self.getSubElement(key, data)
|
return self.getSubElement(key, data)
|
||||||
else:
|
|
||||||
if key.find(self.arrayOpener) != -1:
|
if key.find(self.arrayOpener) != -1:
|
||||||
return self.getSubArrayElement(key, data)
|
# If we got an arrayOpener but the next char is not [0-9] or * then it might just be a string
|
||||||
else:
|
# This isn't optimal since this 'update (foobar)(0)' still won't work
|
||||||
if isinstance(data, dict) and key in data:
|
if key[key.find(self.arrayOpener)+1].isnumeric() or key[key.find(self.arrayOpener)+1] == "*":
|
||||||
return data[key]
|
return self.getSubArrayElement(key, data)
|
||||||
else:
|
|
||||||
return (None, 'not_found')
|
if isinstance(data, dict) and key in data:
|
||||||
|
return data[key]
|
||||||
|
|
||||||
|
return (None, 'not_found')
|
||||||
|
|
||||||
def expandKey(self, key, keys):
|
def expandKey(self, key, keys):
|
||||||
if '(*)' not in key:
|
if '(*)' not in key:
|
||||||
@@ -430,6 +435,8 @@ def parseArgs(args):
|
|||||||
help='remote host to query')
|
help='remote host to query')
|
||||||
parser.add_argument('-k', '--insecure', action='store_true',
|
parser.add_argument('-k', '--insecure', action='store_true',
|
||||||
help='do not check server SSL certificate')
|
help='do not check server SSL certificate')
|
||||||
|
parser.add_argument('-X', '--request', dest='method', default='GET', choices=['GET', 'POST'],
|
||||||
|
help='Specifies a custom request method to use when communicating with the HTTP server')
|
||||||
parser.add_argument('-V', '--version', action='store_true',
|
parser.add_argument('-V', '--version', action='store_true',
|
||||||
help='print version of this plugin')
|
help='print version of this plugin')
|
||||||
parser.add_argument('--cacert',
|
parser.add_argument('--cacert',
|
||||||
@@ -542,11 +549,12 @@ def main(cliargs):
|
|||||||
if args.ssl:
|
if args.ssl:
|
||||||
url = "https://%s" % args.host
|
url = "https://%s" % args.host
|
||||||
|
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||||
context.options |= ssl.OP_NO_SSLv2
|
context.options |= ssl.OP_NO_SSLv2
|
||||||
context.options |= ssl.OP_NO_SSLv3
|
context.options |= ssl.OP_NO_SSLv3
|
||||||
|
|
||||||
if args.insecure:
|
if args.insecure:
|
||||||
|
context.check_hostname = False
|
||||||
context.verify_mode = ssl.CERT_NONE
|
context.verify_mode = ssl.CERT_NONE
|
||||||
else:
|
else:
|
||||||
context.verify_mode = ssl.CERT_OPTIONAL
|
context.verify_mode = ssl.CERT_OPTIONAL
|
||||||
@@ -587,7 +595,7 @@ def main(cliargs):
|
|||||||
json_data = ''
|
json_data = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
req = urllib.request.Request(url)
|
req = urllib.request.Request(url, method=args.method)
|
||||||
req.add_header("User-Agent", "check_http_json")
|
req.add_header("User-Agent", "check_http_json")
|
||||||
if args.auth:
|
if args.auth:
|
||||||
authbytes = str(args.auth).encode()
|
authbytes = str(args.auth).encode()
|
||||||
@@ -599,14 +607,17 @@ def main(cliargs):
|
|||||||
for header in headers:
|
for header in headers:
|
||||||
req.add_header(header, headers[header])
|
req.add_header(header, headers[header])
|
||||||
if args.timeout and args.data:
|
if args.timeout and args.data:
|
||||||
|
databytes = str(args.data).encode()
|
||||||
response = urllib.request.urlopen(req, timeout=args.timeout,
|
response = urllib.request.urlopen(req, timeout=args.timeout,
|
||||||
data=args.data, context=context)
|
data=databytes, context=context)
|
||||||
elif args.timeout:
|
elif args.timeout:
|
||||||
response = urllib.request.urlopen(req, timeout=args.timeout,
|
response = urllib.request.urlopen(req, timeout=args.timeout,
|
||||||
context=context)
|
context=context)
|
||||||
elif args.data:
|
elif args.data:
|
||||||
response = urllib.request.urlopen(req, data=args.data, context=context)
|
databytes = str(args.data).encode()
|
||||||
|
response = urllib.request.urlopen(req, data=databytes, context=context)
|
||||||
else:
|
else:
|
||||||
|
# pylint: disable=consider-using-with
|
||||||
response = urllib.request.urlopen(req, context=context)
|
response = urllib.request.urlopen(req, context=context)
|
||||||
|
|
||||||
json_data = response.read()
|
json_data = response.read()
|
||||||
|
|||||||
9
makefile
9
makefile
@@ -1,9 +0,0 @@
|
|||||||
.PHONY: lint test coverage
|
|
||||||
|
|
||||||
lint:
|
|
||||||
python3 -m pylint check_http_json.py
|
|
||||||
test:
|
|
||||||
python3 -m unittest discover
|
|
||||||
coverage:
|
|
||||||
python3 -m coverage run -m unittest discover
|
|
||||||
python3 -m coverage report -m --include check_http_json.py
|
|
||||||
2
requirements-dev.txt
Normal file
2
requirements-dev.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
coverage==6.4.4
|
||||||
|
pylint==2.15.2
|
||||||
@@ -110,6 +110,14 @@ class UtilTest(unittest.TestCase):
|
|||||||
self.check_data(RulesHelper().dash_U(['metric,0']),
|
self.check_data(RulesHelper().dash_U(['metric,0']),
|
||||||
'{"metric": 3}', UNKNOWN_CODE)
|
'{"metric": 3}', UNKNOWN_CODE)
|
||||||
|
|
||||||
|
def test_array(self):
|
||||||
|
self.check_data(RulesHelper().dash_q(['foo(0),bar']),
|
||||||
|
'{"foo": ["bar"]}', OK_CODE)
|
||||||
|
self.check_data(RulesHelper().dash_q(['foo(0),foo']),
|
||||||
|
'{"foo": ["bar"]}', WARNING_CODE)
|
||||||
|
self.check_data(RulesHelper().dash_Q(['foo(1),bar']),
|
||||||
|
'{"foo": ["bar"]}', CRITICAL_CODE)
|
||||||
|
|
||||||
def test_exists(self):
|
def test_exists(self):
|
||||||
self.check_data(RulesHelper().dash_e(['nothere']),
|
self.check_data(RulesHelper().dash_e(['nothere']),
|
||||||
'{"metric": 5}', WARNING_CODE)
|
'{"metric": 5}', WARNING_CODE)
|
||||||
@@ -294,3 +302,30 @@ class UtilTest(unittest.TestCase):
|
|||||||
# This should throw an error
|
# This should throw an error
|
||||||
data = '[]'
|
data = '[]'
|
||||||
self.check_data(rules.dash_q(['(*).update_status,warn_me']), data, CRITICAL_CODE)
|
self.check_data(rules.dash_q(['(*).update_status,warn_me']), data, CRITICAL_CODE)
|
||||||
|
|
||||||
|
def test_bracket_in_key(self):
|
||||||
|
"""
|
||||||
|
https://github.com/drewkerrigan/nagios-http-json/issues/76
|
||||||
|
"""
|
||||||
|
|
||||||
|
rules = RulesHelper()
|
||||||
|
|
||||||
|
# This should work
|
||||||
|
data = '[{"update status": "failure"}]'
|
||||||
|
self.check_data(rules.dash_q(['(*).update status,failure']), data, OK_CODE)
|
||||||
|
|
||||||
|
data = '[{"update (status)": "failure"}]'
|
||||||
|
self.check_data(rules.dash_q(['(*).update (status),failure']), data, OK_CODE)
|
||||||
|
|
||||||
|
data = '[{"update (((status)": "failure"}]'
|
||||||
|
self.check_data(rules.dash_q(['(*).update (((status),failure']), data, OK_CODE)
|
||||||
|
|
||||||
|
data = '[{"update )status)": "failure"}]'
|
||||||
|
self.check_data(rules.dash_q(['(*).update )status),failure']), data, OK_CODE)
|
||||||
|
|
||||||
|
data = '[{"update (status": "failure"}]'
|
||||||
|
self.check_data(rules.dash_q(['(*).update (status),failure']), data, WARNING_CODE)
|
||||||
|
|
||||||
|
# Does not yet work
|
||||||
|
# data = '{"update (foobar)": ["bar"]}'
|
||||||
|
# self.check_data(rules.dash_q(['update (foobar)(0),bar']), data, OK_CODE)
|
||||||
|
|||||||
Reference in New Issue
Block a user