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 ...@@ -7,6 +7,7 @@ import email.utils
import json import json
import os import os
import time import time
import urlparse
@implementer(interface.IPromise) @implementer(interface.IPromise)
...@@ -58,15 +59,76 @@ class RunPromise(GenericPromise): ...@@ -58,15 +59,76 @@ class RunPromise(GenericPromise):
'%s: Last bot status from %s ok, UTC now is %s', '%s: Last bot status from %s ok, UTC now is %s',
key, last_bot_datetime, self.utcnow) 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): def senseHttpQuery(self):
key = 'http_query' key = 'http_query'
error_list = []
info_list = []
def logError(msg, *args): def appendError(msg, *args):
self.logger.error(key + ': ' + msg, *args) error_list.append(key + ': ' + (msg % args))
if key not in self.surykatka_json: if key not in self.surykatka_json:
logError("%r not in %r", key, self.json_file) appendError("%r not in %r", key, self.json_file)
return return error_list, info_list
url = self.getConfig('url') url = self.getConfig('url')
status_code = self.getConfig('status-code') status_code = self.getConfig('status-code')
...@@ -74,8 +136,8 @@ class RunPromise(GenericPromise): ...@@ -74,8 +136,8 @@ class RunPromise(GenericPromise):
entry_list = [q for q in self.surykatka_json[key] if q['url'] == url] entry_list = [q for q in self.surykatka_json[key] if q['url'] == url]
if len(entry_list) == 0: if len(entry_list) == 0:
logError('No data for %s', url) appendError('No data for %s', url)
return return error_list, info_list
error_list = [] error_list = []
for entry in entry_list: for entry in entry_list:
entry_status_code = str(entry['status_code']) entry_status_code = str(entry['status_code'])
...@@ -97,16 +159,16 @@ class RunPromise(GenericPromise): ...@@ -97,16 +159,16 @@ class RunPromise(GenericPromise):
'expected IPs %s differes from got %s' % ( 'expected IPs %s differes from got %s' % (
' '.join(ip_list), ' '.join(db_ip_list))) ' '.join(ip_list), ' '.join(db_ip_list)))
if len(error_list): if len(error_list):
logError('Problem with %s : ' % (url,) + ', '.join(error_list)) appendError('Problem with %s : ' % (url,) + ', '.join(error_list))
return return error_list, info_list
if len(ip_list) > 0: if len(ip_list) > 0:
self.logger.info( return [], [
'%s: %s replied correctly with status code %s on ip list %s', '%s: %s replied correctly with status code %s on ip list %s' %
key, url, status_code, ' '.join(ip_list)) (key, url, status_code, ' '.join(ip_list))]
else: else:
self.logger.info( return [], [
'%s: %s replied correctly with status code %s', '%s: %s replied correctly with status code %s' %
key, url, status_code) (key, url, status_code)]
def sense(self): def sense(self):
""" """
...@@ -134,7 +196,14 @@ class RunPromise(GenericPromise): ...@@ -134,7 +196,14 @@ class RunPromise(GenericPromise):
if report == 'bot_status': if report == 'bot_status':
return self.senseBotStatus() return self.senseBotStatus()
elif report == 'http_query': 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: else:
self.logger.error("Report %r is not supported", report) self.logger.error("Report %r is not supported", report)
return return
......
...@@ -214,7 +214,8 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -214,7 +214,8 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
'json-file': self.json_file, 'json-file': self.json_file,
'url': 'https://www.erp5.com/', 'url': 'https://www.erp5.com/',
'status-code': '302', '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("""{ self.writeSurykatkaJson("""{
...@@ -237,6 +238,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -237,6 +238,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
"status_code": 200, "status_code": 200,
"url": "https://www.erp5.org/" "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): ...@@ -245,7 +260,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.assertPassedMessage( self.assertPassedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: https://www.erp5.com/ replied correctly with " "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): 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