Commit 1ee763ab authored by Łukasz Nowak's avatar Łukasz Nowak

XXX: Support ssl_certificate

This promise has to be redesigned, otherwise it's pure spaghetti...
parent 7c1594ad
......@@ -7,6 +7,7 @@ import email.utils
import json
import os
import time
import urlparse
@implementer(interface.IPromise)
......@@ -58,15 +59,76 @@ class RunPromise(GenericPromise):
'%s: Last bot status from %s ok, UTC now is %s',
key, last_bot_datetime, self.utcnow)
def senseSslCertificate(self):
key = 'ssl_certificate'
error_list = []
info_list = []
def appendError(msg, *args):
self.logger.error(key + ': ' + msg, *args)
url = self.getConfig('url')
parsed_url = urlparse.urlparse(url)
if parsed_url.scheme == 'https':
hostname = parsed_url.netloc
ssl_check = True
certificate_expiration_days = self.getConfig(
'certificate-expiration-days', '15')
try:
certificate_expiration_days = int(certificate_expiration_days)
except ValueError:
certificate_expiration_days = None
else:
ssl_check = False
certificate_expiration_days = None
if ssl_check is None:
return error_list, info_list
if certificate_expiration_days is None:
appendError(
'certificate-expiration-days %r is incorrect',
self.getConfig('certificate-expiration-days'))
return error_list, info_list
if not hostname:
appendError('url %r is incorrect', url)
return error_list, info_list
if key not in self.surykatka_json:
appendError(
'No data for %s . If the error persist, please update surykatka.', url)
return error_list, info_list
entry_list = [
q for q in self.surykatka_json[key] if q['hostname'] == hostname]
if len(entry_list) == 0:
appendError('No data for %s', url)
return error_list, info_list
for entry in entry_list:
timetuple = email.utils.parsedate(entry['not_after'])
certificate_expiration_time = datetime.datetime.fromtimestamp(
time.mktime(timetuple))
if certificate_expiration_time - datetime.timedelta(
days=certificate_expiration_days) < self.utcnow:
appendError(
'Certificate for %s will expire on %s, which is less than %s days, '
'UTC now is %s',
url, entry['not_after'], certificate_expiration_days, self.utcnow)
return error_list, info_list
else:
return [], [
'%s: Certificate for %s will expire on %s, which is more than %s '
'days, UTC now is %s' %
(key, url, entry['not_after'], certificate_expiration_days,
self.utcnow)]
def senseHttpQuery(self):
key = 'http_query'
error_list = []
info_list = []
def logError(msg, *args):
self.logger.error(key + ': ' + msg, *args)
def appendError(msg, *args):
error_list.append(key + ': ' + (msg % args))
if key not in self.surykatka_json:
logError("%r not in %r", key, self.json_file)
return
appendError("%r not in %r", key, self.json_file)
return error_list, info_list
url = self.getConfig('url')
status_code = self.getConfig('status-code')
......@@ -74,8 +136,8 @@ class RunPromise(GenericPromise):
entry_list = [q for q in self.surykatka_json[key] if q['url'] == url]
if len(entry_list) == 0:
logError('No data for %s', url)
return
appendError('No data for %s', url)
return error_list, info_list
error_list = []
for entry in entry_list:
entry_status_code = str(entry['status_code'])
......@@ -97,16 +159,16 @@ class RunPromise(GenericPromise):
'expected IPs %s differes from got %s' % (
' '.join(ip_list), ' '.join(db_ip_list)))
if len(error_list):
logError('Problem with %s : ' % (url,) + ', '.join(error_list))
return
appendError('Problem with %s : ' % (url,) + ', '.join(error_list))
return error_list, info_list
if len(ip_list) > 0:
self.logger.info(
'%s: %s replied correctly with status code %s on ip list %s',
key, url, status_code, ' '.join(ip_list))
return [], [
'%s: %s replied correctly with status code %s on ip list %s' %
(key, url, status_code, ' '.join(ip_list))]
else:
self.logger.info(
'%s: %s replied correctly with status code %s',
key, url, status_code)
return [], [
'%s: %s replied correctly with status code %s' %
(key, url, status_code)]
def sense(self):
"""
......@@ -134,7 +196,14 @@ class RunPromise(GenericPromise):
if report == 'bot_status':
return self.senseBotStatus()
elif report == 'http_query':
return self.senseHttpQuery()
error_list, info_list = self.senseHttpQuery()
error_ssl_list, info_ssl_list = self.senseSslCertificate()
error_list += error_ssl_list
info_list += info_ssl_list
if len(error_list) > 0:
self.logger.error(' '.join(error_list + info_list))
elif len(info_list) > 0:
self.logger.info(' '.join(info_list))
else:
self.logger.error("Report %r is not supported", report)
return
......
......@@ -214,7 +214,8 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
'json-file': self.json_file,
'url': 'https://www.erp5.com/',
'status-code': '302',
'ip-list': '127.0.0.1 127.0.0.2'
'ip-list': '127.0.0.1 127.0.0.2',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
}
)
self.writeSurykatkaJson("""{
......@@ -237,6 +238,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
"status_code": 200,
"url": "https://www.erp5.org/"
}
],
"ssl_certificate": [
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.1",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
},
{
"date": "Fri, 27 Dec 2019 14:43:26 -0000",
"hostname": "www.erp5.com",
"ip": "127.0.0.2",
"not_after": "Mon, 13 Jul 2020 12:00:00 -0000"
}
]
}
""")
......@@ -245,7 +260,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.assertPassedMessage(
self.getPromiseResult(self.promise_name),
"http_query: https://www.erp5.com/ replied correctly with "
"status code 302 on ip list 127.0.0.1 127.0.0.2"
"status code 302 on ip list 127.0.0.1 127.0.0.2 ssl_certificate: "
"Certificate for https://www.erp5.com/ will expire on Mon, 13 Jul "
"2020 12:00:00 -0000, which is more than 15 days, UTC now is "
"2019-12-27 15:11:12"
)
def test_no_ip_list(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment