Merge branch 'drewkerrigan:master' into master

This commit is contained in:
aro-lew 2024-05-17 10:12:49 +02:00 committed by GitHub
commit ce50a4ecf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 269 additions and 156 deletions

View File

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: [3.8, 3,9] python-version: [3.8, 3.11, 3.12]
name: GitHub Action name: GitHub Action
steps: steps:
- name: Checkout - name: Checkout

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ var/
.installed.cfg .installed.cfg
*.egg *.egg
.venv/ .venv/
venv/
# PyInstaller # PyInstaller
# Usually these files are written by a python script from a template # Usually these files are written by a python script from a template

View File

@ -1,9 +1,11 @@
.PHONY: lint test coverage .PHONY: lint test coverage
PYTHON_PATH?=python3
lint: lint:
python -m pylint check_http_json.py $(PYTHON_PATH) -m pylint check_http_json.py
test: test:
python -m unittest discover $(PYTHON_PATH) -m unittest discover
coverage: coverage:
python -m coverage run -m unittest discover $(PYTHON_PATH) -m coverage run -m unittest discover
python -m coverage report -m --include check_http_json.py $(PYTHON_PATH) -m coverage report -m --include check_http_json.py

View File

@ -38,11 +38,12 @@ 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.1.2 (2022-09-15) Version: 2.2.0 (2024-05-14)
optional arguments: options:
-h, --help show this help message and exit -h, --help show this help message and exit
-d, --debug debug mode -d, --debug debug mode
-v, --verbose Verbose mode. Multiple -v options increase the verbosity
-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
@ -56,61 +57,44 @@ optional arguments:
-p PATH, --path PATH Path -p PATH, --path PATH Path
-t TIMEOUT, --timeout TIMEOUT -t TIMEOUT, --timeout TIMEOUT
Connection timeout (seconds) Connection timeout (seconds)
--unreachable-state UNREACHABLE_STATE
Exit with specified code if URL unreachable. Examples: 1 for Warning, 2 for Critical, 3 for Unknown (default: 3)
-B AUTH, --basic-auth AUTH -B AUTH, --basic-auth AUTH
Basic auth string "username:password" Basic auth string "username:password"
-D DATA, --data DATA The http payload to send as a POST -D DATA, --data DATA The http payload to send as a POST
-A HEADERS, --headers HEADERS -A HEADERS, --headers HEADERS
The http headers in JSON format. The http headers in JSON format.
-f SEPARATOR, --field_separator SEPARATOR -f SEPARATOR, --field_separator SEPARATOR
JSON Field separator, defaults to "."; Select element JSON Field separator, defaults to "."; Select element in an array with "(" ")"
in an array with "(" ")" -F VALUE_SEPARATOR, --value_separator VALUE_SEPARATOR
-F SEPARATOR, --value_separator SEPARATOR JSON Value separator, defaults to ":"
JSON Value separator, defaults to ":"; -w [KEY_THRESHOLD_WARNING ...], --warning [KEY_THRESHOLD_WARNING ...]
-w [KEY_THRESHOLD_WARNING [KEY_THRESHOLD_WARNING ...]], --warning [KEY_THRESHOLD_WARNING [KEY_THRESHOLD_WARNING ...]] Warning threshold for these values (key1[>alias],WarnRange key2[>alias],WarnRange). WarnRange is in the format
Warning threshold for these values [@]start:end, more information at nagios-plugins.org/doc/guidelines.html.
(key1[>alias],WarnRange key2[>alias],WarnRange). -c [KEY_THRESHOLD_CRITICAL ...], --critical [KEY_THRESHOLD_CRITICAL ...]
WarnRange is in the format [@]start:end, more Critical threshold for these values (key1[>alias],CriticalRange key2[>alias],CriticalRange. CriticalRange is in
information at nagios-plugins.org/doc/guidelines.html. the format [@]start:end, more information at nagios-plugins.org/doc/guidelines.html.
-c [KEY_THRESHOLD_CRITICAL [KEY_THRESHOLD_CRITICAL ...]], --critical [KEY_THRESHOLD_CRITICAL [KEY_THRESHOLD_CRITICAL ...]] -e [KEY_LIST ...], --key_exists [KEY_LIST ...]
Critical threshold for these values Checks existence of these keys to determine status. Return warning if key is not present.
(key1[>alias],CriticalRange -E [KEY_LIST_CRITICAL ...], --key_exists_critical [KEY_LIST_CRITICAL ...]
key2[>alias],CriticalRange. CriticalRange is in the
format [@]start:end, more information at nagios-
plugins.org/doc/guidelines.html.
-e [KEY_LIST [KEY_LIST ...]], --key_exists [KEY_LIST [KEY_LIST ...]]
Checks existence of these keys to determine status.
Return warning if key is not present.
-E [KEY_LIST_CRITICAL [KEY_LIST_CRITICAL ...]], --key_exists_critical [KEY_LIST_CRITICAL [KEY_LIST_CRITICAL ...]]
Same as -e but return critical if key is not present. Same as -e but return critical if key is not present.
-q [KEY_VALUE_LIST [KEY_VALUE_LIST ...]], --key_equals [KEY_VALUE_LIST [KEY_VALUE_LIST ...]] -q [KEY_VALUE_LIST ...], --key_equals [KEY_VALUE_LIST ...]
Checks equality of these keys and values Checks equality of these keys and values (key[>alias],value key2,value2) to determine status. Multiple key values
(key[>alias],value key2,value2) to determine status. can be delimited with colon (key,value1:value2). Return warning if equality check fails
Multiple key values can be delimited with colon -Q [KEY_VALUE_LIST_CRITICAL ...], --key_equals_critical [KEY_VALUE_LIST_CRITICAL ...]
(key,value1:value2). Return warning if equality check Same as -q but return critical if equality check fails.
fails -u [KEY_VALUE_LIST_UNKNOWN ...], --key_equals_unknown [KEY_VALUE_LIST_UNKNOWN ...]
-Q [KEY_VALUE_LIST_CRITICAL [KEY_VALUE_LIST_CRITICAL ...]], --key_equals_critical [KEY_VALUE_LIST_CRITICAL [KEY_VALUE_LIST_CRITICAL ...]]
Same as -q but return critical if equality check
fails.
-u [KEY_VALUE_LIST_UNKNOWN [KEY_VALUE_LIST_UNKNOWN ...]], --key_equals_unknown [KEY_VALUE_LIST_UNKNOWN [KEY_VALUE_LIST_UNKNOWN ...]]
Same as -q but return unknown if equality check fails. Same as -q but return unknown if equality check fails.
-y [KEY_VALUE_LIST_NOT [KEY_VALUE_LIST_NOT ...]], --key_not_equals [KEY_VALUE_LIST_NOT [KEY_VALUE_LIST_NOT ...]] -y [KEY_VALUE_LIST_NOT ...], --key_not_equals [KEY_VALUE_LIST_NOT ...]
Checks equality of these keys and values Checks equality of these keys and values (key[>alias],value key2,value2) to determine status. Multiple key values
(key[>alias],value key2,value2) to determine status. can be delimited with colon (key,value1:value2). Return warning if equality check succeeds
Multiple key values can be delimited with colon -Y [KEY_VALUE_LIST_NOT_CRITICAL ...], --key_not_equals_critical [KEY_VALUE_LIST_NOT_CRITICAL ...]
(key,value1:value2). Return warning if equality check Same as -q but return critical if equality check succeeds.
succeeds -m [METRIC_LIST ...], --key_metric [METRIC_LIST ...]
-Y [KEY_VALUE_LIST_NOT_CRITICAL [KEY_VALUE_LIST_NOT_CRITICAL ...]], --key_not_equals_critical [KEY_VALUE_LIST_NOT_CRITICAL [KEY_VALUE_LIST_NOT_CRITICAL ...]] Gathers the values of these keys (key[>alias], UnitOfMeasure,WarnRange,CriticalRange,Min,Max) for Nagios
Same as -q but return critical if equality check performance data. More information about Range format and units of measure for nagios can be found at nagios-
succeeds. plugins.org/doc/guidelines.html Additional formats for this parameter are: (key[>alias]),
-m [METRIC_LIST [METRIC_LIST ...]], --key_metric [METRIC_LIST [METRIC_LIST ...]] (key[>alias],UnitOfMeasure), (key[>alias],UnitOfMeasure,WarnRange, CriticalRange).
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 Additional
formats for this parameter are: (key[>alias]),
(key[>alias],UnitOfMeasure),
(key[>alias],UnitOfMeasure,WarnRange, CriticalRange).
``` ```
## Examples ## Examples

View File

@ -6,7 +6,6 @@ import json
import argparse import argparse
import sys import sys
import ssl import ssl
from pprint import pprint
from urllib.error import HTTPError from urllib.error import HTTPError
from urllib.error import URLError from urllib.error import URLError
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
@ -25,8 +24,8 @@ WARNING_CODE = 1
CRITICAL_CODE = 2 CRITICAL_CODE = 2
UNKNOWN_CODE = 3 UNKNOWN_CODE = 3
__version__ = '2.1.2' __version__ = '2.2.0'
__version_date__ = '2022-09-15' __version_date__ = '2024-05-14'
class NagiosHelper: class NagiosHelper:
""" """
@ -70,20 +69,19 @@ class NagiosHelper:
code = UNKNOWN_CODE code = UNKNOWN_CODE
return code return code
def append_warning(self, warning_message): def append_message(self, code, msg):
self.warning_message += warning_message if code > 2 or code < 0:
self.unknown_message += msg
def append_critical(self, critical_message): if code == 1:
self.critical_message += critical_message self.warning_message += msg
if code == 2:
def append_unknown(self, unknown_message): self.critical_message += msg
self.unknown_message += unknown_message
def append_metrics(self, metrics): def append_metrics(self, metrics):
(performance_data, warning_message, critical_message) = metrics (performance_data, warning_message, critical_message) = metrics
self.performance_data += performance_data self.performance_data += performance_data
self.append_warning(warning_message) self.append_message(WARNING_CODE, warning_message)
self.append_critical(critical_message) self.append_message(CRITICAL_CODE, critical_message)
class JsonHelper: class JsonHelper:
@ -492,6 +490,9 @@ def parseArgs(args):
parser.add_argument('-d', '--debug', action='store_true', parser.add_argument('-d', '--debug', action='store_true',
help='debug mode') help='debug mode')
parser.add_argument('-v', '--verbose', action='count', default=0,
help='Verbose mode. Multiple -v options increase the verbosity')
parser.add_argument('-s', '--ssl', action='store_true', parser.add_argument('-s', '--ssl', action='store_true',
help='use TLS to connect to remote host') help='use TLS to connect to remote host')
parser.add_argument('-H', '--host', dest='host', parser.add_argument('-H', '--host', dest='host',
@ -513,6 +514,8 @@ def parseArgs(args):
parser.add_argument('-p', '--path', dest='path', help='Path') parser.add_argument('-p', '--path', dest='path', help='Path')
parser.add_argument('-t', '--timeout', type=int, parser.add_argument('-t', '--timeout', type=int,
help='Connection timeout (seconds)') help='Connection timeout (seconds)')
parser.add_argument('--unreachable-state', type=int, default=3,
help='Exit with specified code if URL unreachable. Examples: 1 for Warning, 2 for Critical, 3 for Unknown (default: 3)')
parser.add_argument('-B', '--basic-auth', dest='auth', parser.add_argument('-B', '--basic-auth', dest='auth',
help='Basic auth string "username:password"') help='Basic auth string "username:password"')
parser.add_argument('-D', '--data', dest='data', parser.add_argument('-D', '--data', dest='data',
@ -598,16 +601,92 @@ def parseArgs(args):
return parser.parse_args(args) return parser.parse_args(args)
def debugPrint(debug_flag, message, pretty_flag=False): def debugPrint(debug_flag, message):
""" """
Print debug messages if -d (debug_flat ) is set. Print debug messages if -d is set.
""" """
if not debug_flag:
return
if debug_flag: print(message)
if pretty_flag:
pprint(message) def verbosePrint(verbose_flag, when, message):
else: """
print(message) Print verbose messages if -v is set.
Since -v can be used multiple times, the when parameter sets the required amount before printing
"""
if not verbose_flag:
return
if verbose_flag >= when:
print(message)
def prepare_context(args):
"""
Prepare TLS Context
"""
nagios = NagiosHelper()
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3
if args.insecure:
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
else:
context.verify_mode = ssl.CERT_OPTIONAL
context.load_default_certs()
if args.cacert:
try:
context.load_verify_locations(args.cacert)
except ssl.SSLError:
nagios.append_message(UNKNOWN_CODE, 'Error loading SSL CA cert "%s"!' % args.cacert)
if args.cert:
try:
context.load_cert_chain(args.cert, keyfile=args.key)
except ssl.SSLError:
if args.key:
nagios.append_message(UNKNOWN_CODE, 'Error loading SSL cert. Make sure key "%s" belongs to cert "%s"!' % (args.key, args.cert))
else:
nagios.append_message(UNKNOWN_CODE, 'Error loading SSL cert. Make sure "%s" contains the key as well!' % (args.cert))
if nagios.getCode() != OK_CODE:
print(nagios.getMessage())
sys.exit(nagios.getCode())
return context
def make_request(args, url, context):
"""
Performs the actual request to the given URL
"""
req = urllib.request.Request(url, method=args.method)
req.add_header("User-Agent", "check_http_json")
if args.auth:
authbytes = str(args.auth).encode()
base64str = base64.encodebytes(authbytes).decode().replace('\n', '')
req.add_header('Authorization', 'Basic %s' % base64str)
if args.headers:
headers = json.loads(args.headers)
debugPrint(args.debug, "Headers:\n %s" % headers)
for header in headers:
req.add_header(header, headers[header])
if args.timeout and args.data:
databytes = str(args.data).encode()
response = urllib.request.urlopen(req, timeout=args.timeout,
data=databytes, context=context)
elif args.timeout:
response = urllib.request.urlopen(req, timeout=args.timeout,
context=context)
elif args.data:
databytes = str(args.data).encode()
response = urllib.request.urlopen(req, data=databytes, context=context)
else:
# pylint: disable=consider-using-with
response = urllib.request.urlopen(req, context=context)
return response.read()
def main(cliargs): def main(cliargs):
@ -625,42 +704,7 @@ def main(cliargs):
if args.ssl: if args.ssl:
url = "https://%s" % args.host url = "https://%s" % args.host
context = prepare_context(args)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3
if args.insecure:
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
else:
context.verify_mode = ssl.CERT_OPTIONAL
context.load_default_certs()
if args.cacert:
try:
context.load_verify_locations(args.cacert)
except ssl.SSLError:
nagios.append_unknown(
'Error loading SSL CA cert "%s"!'
% args.cacert)
if args.cert:
try:
context.load_cert_chain(args.cert, keyfile=args.key)
except ssl.SSLError:
if args.key:
nagios.append_unknown(
'Error loading SSL cert. Make sure key "%s" belongs to cert "%s"!'
% (args.key, args.cert))
else:
nagios.append_unknown(
'Error loading SSL cert. Make sure "%s" contains the key as well!'
% (args.cert))
if nagios.getCode() != OK_CODE:
print(nagios.getMessage())
sys.exit(nagios.getCode())
else: else:
url = "http://%s" % args.host url = "http://%s" % args.host
if args.port: if args.port:
@ -668,60 +712,37 @@ def main(cliargs):
if args.path: if args.path:
url += "/%s" % args.path url += "/%s" % args.path
debugPrint(args.debug, "url:%s" % url) debugPrint(args.debug, "url: %s" % url)
json_data = '' json_data = ''
try: try:
req = urllib.request.Request(url, method=args.method) json_data = make_request(args, url, context)
req.add_header("User-Agent", "check_http_json")
if args.auth:
authbytes = str(args.auth).encode()
base64str = base64.encodebytes(authbytes).decode().replace('\n', '')
req.add_header('Authorization', 'Basic %s' % base64str)
if args.headers:
headers = json.loads(args.headers)
debugPrint(args.debug, "Headers:\n %s" % headers)
for header in headers:
req.add_header(header, headers[header])
if args.timeout and args.data:
databytes = str(args.data).encode()
response = urllib.request.urlopen(req, timeout=args.timeout,
data=databytes, context=context)
elif args.timeout:
response = urllib.request.urlopen(req, timeout=args.timeout,
context=context)
elif args.data:
databytes = str(args.data).encode()
response = urllib.request.urlopen(req, data=databytes, context=context)
else:
# pylint: disable=consider-using-with
response = urllib.request.urlopen(req, context=context)
json_data = response.read()
except HTTPError as e: except HTTPError as e:
# Try to recover from HTTP Error, if there is JSON in the response # Try to recover from HTTP Error, if there is JSON in the response
if "json" in e.info().get_content_subtype(): if "json" in e.info().get_content_subtype():
json_data = e.read() json_data = e.read()
else: else:
nagios.append_unknown(" HTTPError[%s], url:%s" % (str(e.code), url)) nagios.append_message(UNKNOWN_CODE, " Could not find JSON in HTTP body. HTTPError[%s], url:%s" % (str(e.code), url))
except URLError as e: except URLError as e:
nagios.append_critical(" URLError[%s], url:%s" % (str(e.reason), url)) # Some users might prefer another exit code if the URL wasn't reached
exit_code = args.unreachable_state
nagios.append_message(exit_code, " URLError[%s], url:%s" % (str(e.reason), url))
# Since we don't got any data, we can simply exit
print(nagios.getMessage())
sys.exit(nagios.getCode())
try: try:
data = json.loads(json_data) data = json.loads(json_data)
except ValueError as e: except ValueError as e:
nagios.append_unknown(" Parser error: %s" % str(e)) nagios.append_message(UNKNOWN_CODE, " JSON Parser error: %s" % str(e))
else: else:
debugPrint(args.debug, 'json:') verbosePrint(args.verbose, 1, json.dumps(data, indent=2))
debugPrint(args.debug, data, True)
# Apply rules to returned JSON data # Apply rules to returned JSON data
processor = JsonRuleProcessor(data, args) processor = JsonRuleProcessor(data, args)
nagios.append_warning(processor.checkWarning()) nagios.append_message(WARNING_CODE, processor.checkWarning())
nagios.append_critical(processor.checkCritical()) nagios.append_message(CRITICAL_CODE, processor.checkCritical())
nagios.append_metrics(processor.checkMetrics()) nagios.append_metrics(processor.checkMetrics())
nagios.append_unknown(processor.checkUnknown()) nagios.append_message(UNKNOWN_CODE, processor.checkUnknown())
# Print Nagios specific string and exit appropriately # Print Nagios specific string and exit appropriately
print(nagios.getMessage()) print(nagios.getMessage())

View File

@ -1,2 +1,2 @@
coverage==6.4.4 coverage==6.5.0
pylint==2.15.2 pylint==2.17.7

View File

@ -86,10 +86,10 @@ class UtilTest(unittest.TestCase):
data = json.loads(jsondata) data = json.loads(jsondata)
nagios = NagiosHelper() nagios = NagiosHelper()
processor = JsonRuleProcessor(data, args) processor = JsonRuleProcessor(data, args)
nagios.append_warning(processor.checkWarning()) nagios.append_message(WARNING_CODE, processor.checkWarning())
nagios.append_critical(processor.checkCritical()) nagios.append_message(CRITICAL_CODE, processor.checkCritical())
nagios.append_metrics(processor.checkMetrics()) nagios.append_metrics(processor.checkMetrics())
nagios.append_unknown(processor.checkUnknown()) nagios.append_message(UNKNOWN_CODE, processor.checkUnknown())
self.assertEqual(code, nagios.getCode()) self.assertEqual(code, nagios.getCode())
def test_metrics(self): def test_metrics(self):

View File

@ -9,6 +9,7 @@ import os
sys.path.append('..') sys.path.append('..')
from check_http_json import debugPrint from check_http_json import debugPrint
from check_http_json import verbosePrint
class CLITest(unittest.TestCase): class CLITest(unittest.TestCase):
@ -31,10 +32,13 @@ class CLITest(unittest.TestCase):
debugPrint(True, 'debug') debugPrint(True, 'debug')
mock_print.assert_called_once_with('debug') mock_print.assert_called_once_with('debug')
def test_debugprint_pprint(self): def test_verbose(self):
with mock.patch('check_http_json.pprint') as mock_pprint: with mock.patch('builtins.print') as mock_print:
debugPrint(True, 'debug', True) verbosePrint(0, 3, 'verbose')
mock_pprint.assert_called_once_with('debug') mock_print.assert_not_called()
verbosePrint(3, 3, 'verbose')
mock_print.assert_called_once_with('verbose')
def test_cli_without_params(self): def test_cli_without_params(self):

View File

@ -95,3 +95,37 @@ class MainTest(unittest.TestCase):
main(args) main(args)
self.assertEqual(test.exception.code, 0) self.assertEqual(test.exception.code, 0)
@mock.patch('builtins.print')
def test_main_with_tls(self, mock_print):
args = ['-H', 'localhost',
'--ssl',
'--cacert',
'test/tls/ca-root.pem',
'--cert',
'test/tls/cert.pem',
'--key',
'test/tls/key.pem']
with self.assertRaises(SystemExit) as test:
main(args)
self.assertTrue('https://localhost' in str(mock_print.call_args))
self.assertEqual(test.exception.code, 3)
@mock.patch('builtins.print')
def test_main_with_tls_wrong_ca(self, mock_print):
args = ['-H', 'localhost',
'--ssl',
'--cacert',
'test/tls/key.pem',
'--cert',
'test/tls/cert.pem',
'--key',
'test/tls/key.pem']
with self.assertRaises(SystemExit) as test:
main(args)
self.assertTrue('Error loading SSL CA' in str(mock_print.call_args))
self.assertEqual(test.exception.code, 3)

21
test/tls/ca-root.pem Normal file
View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIUB6EZDl3ajJgJsoLzyC9DrOQQpKowDQYJKoZIhvcNAQEN
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yNDAzMTgwODE5MDhaGA8yMDUx
MDgwMzA4MTkwOFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALVxioj+6zw6Snr+B1JOivC8Of6YptVYym5ICiHX
wjpbSVVe+Py/P2LDb/uQ1QkAENlpvChFqSaRBZU5keXYS/DaFb2Evb2/zf5qIdWU
2ju8B5V13gXSeaNNetyEn1Ivvk0lOCQo2RwEZXuStpLS4Q32rkRBvkoL+RXDc1NX
c3RwcU1p9ybgBqAC7FYdV82sgHGugIrbzkjfFREJXp1AnqvKAdk39b1CnPxfmPZC
nzPPetfr3iivH8yVO5rodU/LDtQNph22JR94YvPB89QO+bZ9bw2GHtPdAKFew9HF
UxM1fmy381Mq2iS3KUq5vsC1jMe8slUAIFYEDzoPvOz+MpcCAwEAAaNTMFEwHQYD
VR0OBBYEFOmCb+JnMzX29hwgtXSzrN+m6mTDMB8GA1UdIwQYMBaAFOmCb+JnMzX2
9hwgtXSzrN+m6mTDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQENBQADggEB
AAkTD8K4UO4uO4i6p2BCofbhVm9LYA0ulmLO8Uro0U491TeEDOQpgMFAK+b2gZIU
zvDHoCMn3UPVxHKl7XzDgLZVkYYEc2s9vArxk5vSnFmh3XvlDu2SO5gSLB2sf68A
2+Jz2x6z9tjWWdZCGJWU/iwMbG2Y3JMHyv1NMF8cyOclJaSDNBAwF5c5sdlGTLKb
WHGXzVqHSAFlGcHtQrcEKclHiuzw2G3LZzwghGk0XzxwvyKrnAEy408RY0mfNLtz
32KHqYtrip0RYlGWKP7/7q6i0D8muEFW/I4emFI0z0I/1CcYZZS8tQkWaPf/wCN0
llTD1kKJACsIMaqkkyy+EZM=
-----END CERTIFICATE-----

19
test/tls/cert.pem Normal file
View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDDzCCAfcCFBOrBcHIH2x9xcUyUeDid0cvBxWtMA0GCSqGSIb3DQEBDQUAMEUx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMjQwMzE4MDgxOTM1WhgPMjA1MTA4MDMw
ODE5MzVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEeMA0GCSqGSIb3DQEBAQUA
A4IBCwAwggEGAoH+ALuzyIhEATF5YyAOsXKfr2mttF2HyJvEscGcoA7YetT57bjJ
5lg944kc3QH/wTEdrGda3cwh3OXdUuyR7Wrm9jPw38hMArx/fWPkiISOShrUSHGd
Qyy2bT+zxBaUo+pomyrlqlgwGlbxuwTAlTSFcI+i7yXrckl2HRj40EW4FNsYpPzv
maxRXs0kg0J2JLTYF+fHlqlYbSX/hRU9wz2DYfkRSS0+OYJNSmqK0jayUsdZYurG
gbPwOCgQ0QxLLh7P8z4sOanRowqUzqTI77cyUugEJRyoi+LJr4r0EwMTBX3STgPh
S9B78+LNvwOrLrZFUhr144RfO9QPLnz0uWcCAwEAATANBgkqhkiG9w0BAQ0FAAOC
AQEAeIR21PfLzgpL7WDBE2KgwI78nVc1wY9nwoAxSBzHjS0Olve3r9MaVzAKn5ZS
xHtv8oroXjhTcczCIzxii6Imp6u0iIr3QVBIceofxrH3aWmICURcC9l+dIiY6sk9
Ct8P8gm/Erv2iF/7bnsARwDnw0f41fC9eXtHZ7WLRQrc7tLHpjL0Z7bT77ysQJVK
C1SWtBnq3afmwH3R1wVHENn0JVFQpBp+vqWU5KIlvjcz49yPU+aNODk1rJsHMlgS
x2iddwF31GNOxNfXtw8fdw4UDUl2wYoZ45w2e2pXt4pbN43m0Wys1eQZdk3tyR6G
AZOLP05073mLtbVlFRmcTdXIGg==
-----END CERTIFICATE-----

27
test/tls/key.pem Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN PRIVATE KEY-----
MIIEqAIBADANBgkqhkiG9w0BAQEFAASCBJIwggSOAgEAAoH+ALuzyIhEATF5YyAO
sXKfr2mttF2HyJvEscGcoA7YetT57bjJ5lg944kc3QH/wTEdrGda3cwh3OXdUuyR
7Wrm9jPw38hMArx/fWPkiISOShrUSHGdQyy2bT+zxBaUo+pomyrlqlgwGlbxuwTA
lTSFcI+i7yXrckl2HRj40EW4FNsYpPzvmaxRXs0kg0J2JLTYF+fHlqlYbSX/hRU9
wz2DYfkRSS0+OYJNSmqK0jayUsdZYurGgbPwOCgQ0QxLLh7P8z4sOanRowqUzqTI
77cyUugEJRyoi+LJr4r0EwMTBX3STgPhS9B78+LNvwOrLrZFUhr144RfO9QPLnz0
uWcCAwEAAQKB/UQAYzMy5/fDkWzoxdLQFV3E56ZG7h+4x+lr0/Ts6rtD/KLIyqHH
ciqXgV4bCSPBK1eabOZqkjvYzhUU3R2wpRu2NWy8VPVzfrr07ZyQbDqCE+jNX6vQ
P44nk2/W0/e1hBmrcOZYLwK2utmC58tKWLhBAEENpq8EkpAcfF/1y9aRHKYwNnH7
vouoQibN5NTs5m8s0VyjRTDwRZja98eWnn5NfU3orqYO8fSlF6CyzDtoyhMco6zR
0skBgMzRYCRTuJpV+KekC7XFYyiJ6XZN5DKLbbqP6Y7YR8wjyFEruoGCS0mZH2H0
9/rhTsJram1B2zohXHPsHJGGGv12/7kCfw5C7yda+8Yv0NmRp1F+EJYb75SCAWIP
kzN/xvjP2bMKa6oSzU0DOga3Wc4ijJHDaND8rqdPqQe3zXFr1nPdBrybLSJ6k5CN
4Dd6ENJWVWino0L460kpLtlBG6TsgmB8bkwhjWVE6Vgt4Vila+a3TGRXeniaRzdw
icNOtMrjYlUCfw0pWEvO2uFq0DbNZbmzC2j5ClFcU96CAl4AqKG2PiGnuSy9TKVZ
c5OiXFmyoig7v4LJzaKLSqVIN4hVBU80/MlhvG+dpeimvLaQKNtlZQethIs5hXlB
R1XfaPhq6BQiYmQ3tufyS/0Es2OY+Cs3LU1uDB8qVzonlmnIi69OwMsCfwRPISfJ
C+4UIIy8v8uVxbk1c6xxo61Xe2jCIQKo+uRoL6PRzoqIgQ3qdI4eTk70tkT/NF6F
aVNVrBOrO78Cd7ihQn/6fX/d/nOExHRpdaELlf70a1NNyEQIsiug8rvonQMP2ENT
ERZ9tmssgG/Tzpc6/1xVcVNFA7spmuL61YkCfwnu2zGTc0PO7kd96rkktIbL9YqD
6NQ0QH8bdildtjSGNc3bLB5ajUytq48Sryk4NogJr8Vt5K8q+qZMrE4kCmgd+C4w
x4b3V9Ncp0k1k/MgdLjyd5aUurbHfpyFapPPg3xpRAR3q/vP8WdIintrECiw1jsr
JFvChtVdQnbTM9MCfw41RcjNwCaIG+uXc8bD6Yf+NyXD8zP6ZDywmBlkMWlGSzx4
xM8J+wQiQsNWthDBbF7inJc+lbtJiEe4YOPkbjCYVZRHribL65HKJlEUv6M9bvQo
3P1DS5tDrwo6z9UPs4tD1SgF9fDu/xA7fwPF1RTvuW07MhFJWlDo4FSWS9c=
-----END PRIVATE KEY-----