Commit ec3ac84c authored by Łukasz Nowak's avatar Łukasz Nowak

promise: Support ssl_certificate in check_surykatka_json

parent e82f122c
...@@ -7,6 +7,10 @@ import email.utils ...@@ -7,6 +7,10 @@ import email.utils
import json import json
import os import os
import time import time
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
@implementer(interface.IPromise) @implementer(interface.IPromise)
...@@ -66,8 +70,67 @@ class RunPromise(GenericPromise): ...@@ -66,8 +70,67 @@ 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'
def appendError(msg, *args):
self.appendError(key + ': ' + msg % args)
url = self.getConfig('url')
parsed_url = 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
if certificate_expiration_days is None:
appendError(
'certificate-expiration-days %r is incorrect',
self.getConfig('certificate-expiration-days'))
return
if not hostname:
appendError('url %r is incorrect', url)
return
if key not in self.surykatka_json:
appendError(
'No data for %s . If the error persist, please update surykatka.', url)
return
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
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_string)
return
else:
self.appendInfo(
'%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_string))
return
def senseHttpQuery(self): def senseHttpQuery(self):
key = 'http_query' key = 'http_query'
error_list = []
def logError(msg, *args): def logError(msg, *args):
self.appendError(key + ': ' + msg % args) self.appendError(key + ': ' + msg % args)
...@@ -116,8 +179,10 @@ class RunPromise(GenericPromise): ...@@ -116,8 +179,10 @@ class RunPromise(GenericPromise):
if test_utcnow: if test_utcnow:
self.utcnow = datetime.datetime.fromtimestamp( self.utcnow = datetime.datetime.fromtimestamp(
time.mktime(email.utils.parsedate(test_utcnow))) time.mktime(email.utils.parsedate(test_utcnow)))
self.utcnow_string = test_utcnow
else: else:
self.utcnow = datetime.datetime.utcnow() self.utcnow = datetime.datetime.utcnow()
self.utcnow_string = email.utils.formatdate(time.mktime(self.utcnow.timetuple()))
self.json_file = self.getConfig('json-file', '') self.json_file = self.getConfig('json-file', '')
if not os.path.exists(self.json_file): if not os.path.exists(self.json_file):
...@@ -134,6 +199,7 @@ class RunPromise(GenericPromise): ...@@ -134,6 +199,7 @@ class RunPromise(GenericPromise):
self.senseBotStatus() self.senseBotStatus()
elif report == 'http_query': elif report == 'http_query':
self.senseHttpQuery() self.senseHttpQuery()
self.senseSslCertificate()
else: else:
self.appendError("Report %r is not supported" % report) self.appendError("Report %r is not supported" % report)
self.emitLog() self.emitLog()
......
...@@ -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 "
"Fri, 27 Dec 2019 15:11:12 -0000"
) )
def test_no_ip_list(self): def test_no_ip_list(self):
...@@ -255,6 +273,7 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -255,6 +273,7 @@ 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',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
} }
) )
self.writeSurykatkaJson("""{ self.writeSurykatkaJson("""{
...@@ -277,6 +296,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -277,6 +296,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"
}
] ]
} }
""") """)
...@@ -284,8 +317,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -284,8 +317,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
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 "
"status code 302" "code 302 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 Fri, 27 Dec 2019 15:11:12 -0000"
) )
def test_bad_code(self): def test_bad_code(self):
...@@ -295,6 +330,7 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -295,6 +330,7 @@ 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': '301', 'status-code': '301',
'test-utcnow': 'Fri, 27 Dec 2019 15:11:12 -0000'
} }
) )
self.writeSurykatkaJson("""{ self.writeSurykatkaJson("""{
...@@ -317,6 +353,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -317,6 +353,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"
}
] ]
} }
""") """)
...@@ -325,8 +375,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -325,8 +375,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
self.assertFailedMessage( self.assertFailedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: Problem with https://www.erp5.com/: " "http_query: Problem with https://www.erp5.com/: IP 127.0.0.1 got "
"IP 127.0.0.1 got status code 302 instead of 301" "status code 302 instead of 301 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 Fri, 27 Dec 2019 "
"15:11:12 -0000"
) )
def test_bad_ip(self): def test_bad_ip(self):
...@@ -336,7 +389,8 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -336,7 +389,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': '301', 'status-code': '301',
'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("""{
...@@ -359,6 +413,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -359,6 +413,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"
}
] ]
} }
""") """)
...@@ -367,8 +435,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -367,8 +435,11 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
self.assertFailedMessage( self.assertFailedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: Problem with https://www.erp5.com/: " "http_query: Problem with https://www.erp5.com/: expected IPs "
"expected IPs 127.0.0.1 127.0.0.2 differes from got 127.0.0.1 127.0.0.4" "127.0.0.1 127.0.0.2 differes from got 127.0.0.1 127.0.0.4 "
"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 Fri, 27 Dec 2019 15:11:12 -0000"
) )
def test_bad_ip_status_code(self): def test_bad_ip_status_code(self):
...@@ -378,7 +449,8 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -378,7 +449,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': '301', 'status-code': '301',
'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("""{
...@@ -401,6 +473,20 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -401,6 +473,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"
}
] ]
} }
""") """)
...@@ -409,8 +495,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin): ...@@ -409,8 +495,10 @@ class TestCheckSurykatkaJSONHttpQuery(CheckSurykatkaJSONMixin):
self.launcher.run() self.launcher.run()
self.assertFailedMessage( self.assertFailedMessage(
self.getPromiseResult(self.promise_name), self.getPromiseResult(self.promise_name),
"http_query: Problem with https://www.erp5.com/: " "http_query: Problem with https://www.erp5.com/: IP 127.0.0.1 got "
"IP 127.0.0.1 got status code 302 instead of 301, " "status code 302 instead of 301, expected IPs 127.0.0.1 127.0.0.2 "
"expected IPs 127.0.0.1 127.0.0.2 differes from got " "differes from got 127.0.0.1 127.0.0.4 ssl_certificate: Certificate "
"127.0.0.1 127.0.0.4" "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 Fri, 27 Dec 2019 "
"15:11:12 -0000"
) )
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